Decimal::toString should not round integer value.
authoryosin@chromium.org <yosin@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 18 Jul 2012 08:09:45 +0000 (08:09 +0000)
committeryosin@chromium.org <yosin@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 18 Jul 2012 08:09:45 +0000 (08:09 +0000)
https://bugs.webkit.org/show_bug.cgi?id=91481

Reviewed by Kent Tamura.

Source/WebCore:

This patch makes Decimal::toString not to round an integer value
before converting string.

Tests: WebKit/chromium/tests/DecimalTest.cpp: DecimalTest.toString

* platform/Decimal.cpp:
(WebCore::Decimal::toString): When the value is an integer, we don't
round coefficient to be DBL_DIG(15) digits because double can
represent an integer without rounding error.

Source/WebKit/chromium:

This patch adds a new test cases for Decimal::toString() for failed
value and maximum coefficient value with various exponent.

* tests/DecimalTest.cpp:
(TEST_F): DecimalTest.toString: Add test cases for big coefficient values.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@122928 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/Decimal.cpp
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/tests/DecimalTest.cpp

index b2e5229..1f98724 100644 (file)
@@ -1,3 +1,20 @@
+2012-07-18  Yoshifumi Inoue  <yosin@chromium.org>
+
+        Decimal::toString should not round integer value.
+        https://bugs.webkit.org/show_bug.cgi?id=91481
+
+        Reviewed by Kent Tamura.
+
+        This patch makes Decimal::toString not to round an integer value
+        before converting string.
+
+        Tests: WebKit/chromium/tests/DecimalTest.cpp: DecimalTest.toString
+
+        * platform/Decimal.cpp:
+        (WebCore::Decimal::toString): When the value is an integer, we don't
+        round coefficient to be DBL_DIG(15) digits because double can
+        represent an integer without rounding error.
+
 2012-07-18  Luke Macpherson   <macpherson@chromium.org>
 
         Fix null pointer dereference introduced by Changeset 121874.
index 1472dc1..8a5e275 100644 (file)
@@ -967,22 +967,24 @@ String Decimal::toString() const
         builder.append('-');
 
     int originalExponent = exponent();
-
-    const int maxDigits = DBL_DIG;
     uint64_t coefficient = m_data.coefficient();
-    uint64_t lastDigit = 0;
-    while (countDigits(coefficient) > maxDigits) {
-        lastDigit = coefficient % 10;
-        coefficient /= 10;
-        ++originalExponent;
-    }
 
-    if (lastDigit >= 5)
-        ++coefficient;
+    if (originalExponent < 0) {
+        const int maxDigits = DBL_DIG;
+        uint64_t lastDigit = 0;
+        while (countDigits(coefficient) > maxDigits) {
+            lastDigit = coefficient % 10;
+            coefficient /= 10;
+            ++originalExponent;
+        }
 
-    while (originalExponent < 0 && coefficient && !(coefficient % 10)) {
-        coefficient /= 10;
-        ++originalExponent;
+        if (lastDigit >= 5)
+            ++coefficient;
+
+        while (originalExponent < 0 && coefficient && !(coefficient % 10)) {
+            coefficient /= 10;
+            ++originalExponent;
+        }
     }
 
     const String digits = String::number(coefficient);
index 70a1461..1654cc6 100644 (file)
@@ -1,3 +1,16 @@
+2012-07-18  Yoshifumi Inoue  <yosin@chromium.org>
+
+        Decimal::toString should not round integer value.
+        https://bugs.webkit.org/show_bug.cgi?id=91481
+
+        Reviewed by Kent Tamura.
+
+        This patch adds a new test cases for Decimal::toString() for failed
+        value and maximum coefficient value with various exponent.
+
+        * tests/DecimalTest.cpp:
+        (TEST_F): DecimalTest.toString: Add test cases for big coefficient values.
+
 2012-07-18  Hans Wennborg  <hans@chromium.org>
 
         Add copy constructor to WebSpeechGrammar.h
index bf74ea7..8d41062 100644 (file)
@@ -1072,6 +1072,16 @@ TEST_F(DecimalTest, ToString)
     EXPECT_DECIMAL_STREQ("-5.678e+103", encode(5678, 100, Negative));
     EXPECT_DECIMAL_STREQ("5.678e-97", encode(5678, -100, Positive));
     EXPECT_DECIMAL_STREQ("-5.678e-97", encode(5678, -100, Negative));
+    EXPECT_DECIMAL_STREQ("8639999913600001", encode(UINT64_C(8639999913600001), 0, Positive));
+    EXPECT_DECIMAL_STREQ("9007199254740991", encode((static_cast<uint64_t>(1) << DBL_MANT_DIG) - 1, 0, Positive));
+    EXPECT_DECIMAL_STREQ("99999999999999999", encode(UINT64_C(99999999999999999), 0, Positive));
+    EXPECT_DECIMAL_STREQ("9.9999999999999999e+17", encode(UINT64_C(99999999999999999), 1, Positive));
+    EXPECT_DECIMAL_STREQ("9.9999999999999999e+18", encode(UINT64_C(99999999999999999), 2, Positive));
+    EXPECT_DECIMAL_STREQ("1e+16", encode(UINT64_C(99999999999999999), -1, Positive));
+    EXPECT_DECIMAL_STREQ("1000000000000000", encode(UINT64_C(99999999999999999), -2, Positive));
+    EXPECT_DECIMAL_STREQ("1", encode(UINT64_C(99999999999999999), -17, Positive));
+    EXPECT_DECIMAL_STREQ("0.001", encode(UINT64_C(99999999999999999), -20, Positive));
+    EXPECT_DECIMAL_STREQ("1e-83", encode(UINT64_C(99999999999999999), -100, Positive));
 }
 
 TEST_F(DecimalTest, ToStringSpecialValues)