From 10924e389cf904399d80900f32d1e39627762276 Mon Sep 17 00:00:00 2001 From: Milo Yip Date: Mon, 30 Jun 2014 21:26:43 +0800 Subject: [PATCH 1/2] Fixes parsing small floating point values underflow https://code.google.com/p/rapidjson/issues/detail?id=75 The modification is slightly different from dlbattle123 to improve speed. --- include/rapidjson/reader.h | 10 +++++++++- test/unittest/readertest.cpp | 5 +++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/include/rapidjson/reader.h b/include/rapidjson/reader.h index a265605..4be8d9c 100644 --- a/include/rapidjson/reader.h +++ b/include/rapidjson/reader.h @@ -664,7 +664,15 @@ private: // Finish parsing, call event according to the type of number. if (useDouble) { - d *= internal::Pow10(exp + expFrac); + int expSum = exp + expFrac; + if (expSum < -308) { + // Prevent expSum < -308, making Pow10(expSum) = 0 + d *= internal::Pow10(exp); + d *= internal::Pow10(expFrac); + } + else + d *= internal::Pow10(expSum); + handler.Double(minus ? -d : d); } else { diff --git a/test/unittest/readertest.cpp b/test/unittest/readertest.cpp index 829837d..f31da10 100644 --- a/test/unittest/readertest.cpp +++ b/test/unittest/readertest.cpp @@ -129,9 +129,10 @@ TEST(Reader, ParseNumberHandler) { TEST_DOUBLE("1.234E+10", 1.234E+10); TEST_DOUBLE("1.234E-10", 1.234E-10); TEST_DOUBLE("1.79769e+308", 1.79769e+308); - //TEST_DOUBLE("2.22507e-308", 2.22507e-308); // TODO: underflow + __asm int 3; + TEST_DOUBLE("2.22507e-308", 2.22507e-308); TEST_DOUBLE("-1.79769e+308", -1.79769e+308); - //TEST_DOUBLE("-2.22507e-308", -2.22507e-308); // TODO: underflow + TEST_DOUBLE("-2.22507e-308", -2.22507e-308); 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) From 4843b790c0bb0aefed2d1f247fff1b52c4816f03 Mon Sep 17 00:00:00 2001 From: Milo Yip Date: Mon, 30 Jun 2014 21:28:57 +0800 Subject: [PATCH 2/2] Remove debug code --- test/unittest/readertest.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/test/unittest/readertest.cpp b/test/unittest/readertest.cpp index f31da10..362cde1 100644 --- a/test/unittest/readertest.cpp +++ b/test/unittest/readertest.cpp @@ -129,7 +129,6 @@ TEST(Reader, ParseNumberHandler) { TEST_DOUBLE("1.234E+10", 1.234E+10); TEST_DOUBLE("1.234E-10", 1.234E-10); TEST_DOUBLE("1.79769e+308", 1.79769e+308); - __asm int 3; TEST_DOUBLE("2.22507e-308", 2.22507e-308); TEST_DOUBLE("-1.79769e+308", -1.79769e+308); TEST_DOUBLE("-2.22507e-308", -2.22507e-308);