From b0436911a8ce2b7e2aa73972d5275702a60cc3ae Mon Sep 17 00:00:00 2001 From: miloyip Date: Wed, 3 Sep 2014 14:45:37 +0800 Subject: [PATCH] Check "fast path cases in disguise" in strtod --- include/rapidjson/reader.h | 14 ++++++++++++-- test/unittest/readertest.cpp | 1 + 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/include/rapidjson/reader.h b/include/rapidjson/reader.h index 0615ce2..92deeab 100644 --- a/include/rapidjson/reader.h +++ b/include/rapidjson/reader.h @@ -877,11 +877,21 @@ private: if (useDouble) { int p = exp + expFrac; double d; - uint64_t significand = use64bit ? i64 : i; + double significand = use64bit ? i64 : i; // Use fast path for string-to-double conversion if possible // see http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/ - if (!useStrtod && p >= -22 && p <= 22 && significand <= RAPIDJSON_UINT64_C2(0x001FFFFF, 0xFFFFFFFF)) { + if (!useStrtod && p > 22) { + if (p < 22 + 16) { + // Fast Path Cases In Disguise + significand *= internal::Pow10(p - 22); + p = 22; + } + else + useStrtod = true; + } + + if (!useStrtod && p >= -22 && significand <= 9007199254740991.0) { // 2^53 - 1 if (p >= 0) d = significand * internal::Pow10(p); else diff --git a/test/unittest/readertest.cpp b/test/unittest/readertest.cpp index 104bcd2..bbfbae5 100644 --- a/test/unittest/readertest.cpp +++ b/test/unittest/readertest.cpp @@ -165,6 +165,7 @@ TEST(Reader, ParseNumberHandler) { TEST_DOUBLE("18446744073709551616", 18446744073709551616.0); // 2^64 (max of uint64_t + 1, force to use double) TEST_DOUBLE("-9223372036854775809", -9223372036854775809.0); // -2^63 - 1(min of int64_t + 1, force to use double) TEST_DOUBLE("0.9868011474609375", 0.9868011474609375); // https://github.com/miloyip/rapidjson/issues/120 + TEST_DOUBLE("123e34", 123e34); // Fast Path Cases In Disguise { char n1e308[310]; // '1' followed by 308 '0'