From 1921cb379da8acd268865f258d519432ee690aa6 Mon Sep 17 00:00:00 2001 From: Florian Loitsch Date: Sat, 4 Mar 2017 17:02:54 +0100 Subject: [PATCH 1/2] Avoid negative shift. When filling in fractional digits in a fixed representation we might use all existing digits. When this happens, we can not look at the next digit to see if we should round up. Before this fix, we tried to shift by a negative amount to see if the (non-existing) next bit was set to 1 (requiring the number to be rounded up). Fixes #41. --- double-conversion/fixed-dtoa.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/double-conversion/fixed-dtoa.cc b/double-conversion/fixed-dtoa.cc index 78378c51..e06617bf 100644 --- a/double-conversion/fixed-dtoa.cc +++ b/double-conversion/fixed-dtoa.cc @@ -259,7 +259,7 @@ static void FillFractionals(uint64_t fractionals, int exponent, fractionals -= static_cast(digit) << point; } // If the first bit after the point is set we have to round up. - if (((fractionals >> (point - 1)) & 1) == 1) { + if ((fractionals != 0) && ((fractionals >> (point - 1)) & 1) == 1) { RoundUp(buffer, length, decimal_point); } } else { // We need 128 bits. From 78cd7b13a8212f3b6bfb1b0b86e58e594dee3792 Mon Sep 17 00:00:00 2001 From: Florian Loitsch Date: Sat, 4 Mar 2017 17:12:32 +0100 Subject: [PATCH 2/2] Add assert and test. --- double-conversion/fixed-dtoa.cc | 1 + test/cctest/test-fixed-dtoa.cc | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/double-conversion/fixed-dtoa.cc b/double-conversion/fixed-dtoa.cc index e06617bf..0f55a0b6 100644 --- a/double-conversion/fixed-dtoa.cc +++ b/double-conversion/fixed-dtoa.cc @@ -259,6 +259,7 @@ static void FillFractionals(uint64_t fractionals, int exponent, fractionals -= static_cast(digit) << point; } // If the first bit after the point is set we have to round up. + ASSERT(fractionals == 0 || point - 1 >= 0); if ((fractionals != 0) && ((fractionals >> (point - 1)) & 1) == 1) { RoundUp(buffer, length, decimal_point); } diff --git a/test/cctest/test-fixed-dtoa.cc b/test/cctest/test-fixed-dtoa.cc index 5ffac581..e66f3890 100644 --- a/test/cctest/test-fixed-dtoa.cc +++ b/test/cctest/test-fixed-dtoa.cc @@ -485,6 +485,10 @@ TEST(FastFixedVariousDoubles) { buffer, &length, &point)); CHECK_EQ("1000000000000000128", buffer.start()); CHECK_EQ(19, point); + + CHECK(FastFixedDtoa(2.10861548515811875e+15, 17, buffer, &length, &point)); + CHECK_EQ("210861548515811875", buffer.start()); + CHECK_EQ(16, point); }