Commit 82ff580f authored by Milo Yip's avatar Milo Yip

Merge pull request #342 from miloyip/issue340_doubleparsebug

Fix some numbers parsed incorrectly
parents f8b3c65d add5a505
......@@ -191,8 +191,13 @@ inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosit
DiyFp rounded(v.f >> precisionSize, v.e + precisionSize);
const uint64_t precisionBits = (v.f & ((uint64_t(1) << precisionSize) - 1)) * kUlp;
const uint64_t halfWay = (uint64_t(1) << (precisionSize - 1)) * kUlp;
if (precisionBits >= halfWay + error)
if (precisionBits >= halfWay + error) {
rounded.f++;
if (rounded.f & (DiyFp::kDpHiddenBit << 1)) { // rounding overflows mantissa (issue #340)
rounded.f >>= 1;
rounded.e++;
}
}
*result = rounded.ToDouble();
......
......@@ -193,7 +193,7 @@ static void TestParseDouble() {
EXPECT_DOUBLE_EQ(x, h.actual_); \
} \
}
TEST_DOUBLE(fullPrecision, "0.0", 0.0);
TEST_DOUBLE(fullPrecision, "-0.0", -0.0); // For checking issue #289
TEST_DOUBLE(fullPrecision, "1.0", 1.0);
......@@ -327,15 +327,44 @@ static void TestParseDouble() {
if (fullPrecision) {
EXPECT_EQ(d.Uint64Value(), a.Uint64Value());
if (d.Uint64Value() != a.Uint64Value())
printf(" String: %sn Actual: %.17gnExpected: %.17gn", buffer, h.actual_, d.Value());
printf(" String: %s\n Actual: %.17g\nExpected: %.17g\n", buffer, h.actual_, d.Value());
}
else {
EXPECT_EQ(d.Sign(), a.Sign()); /* for 0.0 != -0.0 */
EXPECT_EQ(d.Sign(), a.Sign()); // for 0.0 != -0.0
EXPECT_DOUBLE_EQ(d.Value(), h.actual_);
}
}
}
}
// Issue #340
TEST_DOUBLE(fullPrecision, "7.450580596923828e-9", 7.450580596923828e-9);
{
internal::Double d(1.0);
for (int i = 0; i < 324; i++) {
char buffer[32];
*internal::dtoa(d.Value(), buffer) = '\0';
StringStream s(buffer);
ParseDoubleHandler h;
Reader reader;
ASSERT_EQ(kParseErrorNone, reader.Parse<fullPrecision ? kParseFullPrecisionFlag : 0>(s, h).Code());
EXPECT_EQ(1u, h.step_);
internal::Double a(h.actual_);
if (fullPrecision) {
EXPECT_EQ(d.Uint64Value(), a.Uint64Value());
if (d.Uint64Value() != a.Uint64Value())
printf(" String: %s\n Actual: %.17g\nExpected: %.17g\n", buffer, h.actual_, d.Value());
}
else {
EXPECT_EQ(d.Sign(), a.Sign()); // for 0.0 != -0.0
EXPECT_DOUBLE_EQ(d.Value(), h.actual_);
}
d = d.Value() * 0.5;
}
}
#undef TEST_DOUBLE
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment