]> granicus.if.org Git - icu/commitdiff
ICU-21581 Update double-conversion
authorShane F. Carr <shane@unicode.org>
Wed, 29 Sep 2021 07:24:20 +0000 (02:24 -0500)
committerShane F. Carr <shane@unicode.org>
Wed, 29 Sep 2021 17:41:28 +0000 (12:41 -0500)
15 files changed:
icu4c/source/i18n/double-conversion-fast-dtoa.cpp
icu4c/source/i18n/double-conversion-string-to-double.cpp
icu4c/source/i18n/double-conversion-string-to-double.h
icu4c/source/i18n/double-conversion-utils.h
vendor/double-conversion/pull-from-upstream.sh
vendor/double-conversion/upstream/Changelog
vendor/double-conversion/upstream/double-conversion/bignum-dtoa.cc
vendor/double-conversion/upstream/double-conversion/double-to-string.h
vendor/double-conversion/upstream/double-conversion/fast-dtoa.cc
vendor/double-conversion/upstream/double-conversion/fixed-dtoa.cc
vendor/double-conversion/upstream/double-conversion/string-to-double.cc
vendor/double-conversion/upstream/double-conversion/string-to-double.h
vendor/double-conversion/upstream/double-conversion/strtod.cc
vendor/double-conversion/upstream/double-conversion/utils.h
vendor/double-conversion/upstream/test/cctest/test-conversions.cc

index 87a3d536bf111fec38a1e50bfd8618d663dd1b9c..06e4cf12559da06694958735a7d4e9500d910902 100644 (file)
@@ -579,7 +579,7 @@ static bool Grisu3(double v,
   // the difference between w and boundary_minus/plus (a power of 2) and to
   // compute scaled_boundary_minus/plus by subtracting/adding from
   // scaled_w. However the code becomes much less readable and the speed
-  // enhancements are not terriffic.
+  // enhancements are not terrific.
   DiyFp scaled_boundary_minus = DiyFp::Times(boundary_minus, ten_mk);
   DiyFp scaled_boundary_plus  = DiyFp::Times(boundary_plus,  ten_mk);
 
@@ -587,7 +587,7 @@ static bool Grisu3(double v,
   // v == (double) (scaled_w * 10^-mk).
   // Set decimal_exponent == -mk and pass it to DigitGen. If scaled_w is not an
   // integer than it will be updated. For instance if scaled_w == 1.23 then
-  // the buffer will be filled with "123" und the decimal_exponent will be
+  // the buffer will be filled with "123" and the decimal_exponent will be
   // decreased by 2.
   int kappa;
   bool result = DigitGen(scaled_boundary_minus, scaled_w, scaled_boundary_plus,
index 3275b9e552f66b0eb729595df73eeec9628f8099..c72bb26277435abe764d4c389d1d10f9cc20ac26 100644 (file)
@@ -800,6 +800,42 @@ float StringToDoubleConverter::StringToFloat(
                                          processed_characters_count));
 }
 
+
+template<>
+double StringToDoubleConverter::StringTo<double>(
+    const char* buffer,
+    int length,
+    int* processed_characters_count) const {
+    return StringToDouble(buffer, length, processed_characters_count);
+}
+
+
+template<>
+float StringToDoubleConverter::StringTo<float>(
+    const char* buffer,
+    int length,
+    int* processed_characters_count) const {
+    return StringToFloat(buffer, length, processed_characters_count);
+}
+
+
+template<>
+double StringToDoubleConverter::StringTo<double>(
+    const uc16* buffer,
+    int length,
+    int* processed_characters_count) const {
+    return StringToDouble(buffer, length, processed_characters_count);
+}
+
+
+template<>
+float StringToDoubleConverter::StringTo<float>(
+    const uc16* buffer,
+    int length,
+    int* processed_characters_count) const {
+    return StringToFloat(buffer, length, processed_characters_count);
+}
+
 }  // namespace double_conversion
 
 // ICU PATCH: Close ICU namespace
index 2eb0c1f8979838be0f68c0273e73605c0e426ad7..9f6f5307111ac5202a80f5e794cf2323524261c7 100644 (file)
@@ -100,7 +100,7 @@ class StringToDoubleConverter {
   //      This *must* start with "0x" and separate the exponent with "p".
   //      Examples: 0x1.2p3 == 9.0
   //                0x10.1p0 == 16.0625
-  //      ALLOW_HEX and ALLOW_HEX_FLOATS are indendent.
+  //      ALLOW_HEX and ALLOW_HEX_FLOATS are indented.
   //
   // empty_string_value is returned when an empty string is given as input.
   // If ALLOW_LEADING_SPACES or ALLOW_TRAILING_SPACES are set, then a string
@@ -218,6 +218,18 @@ class StringToDoubleConverter {
                       int length,
                       int* processed_characters_count) const;
 
+  // Same as StringToDouble for T = double, and StringToFloat for T = float.
+  template <typename T>
+  T StringTo(const char* buffer,
+             int length,
+             int* processed_characters_count) const;
+
+  // Same as StringTo above but for 16 bit characters.
+  template <typename T>
+  T StringTo(const uc16* buffer,
+             int length,
+             int* processed_characters_count) const;
+
  private:
   const int flags_;
   const double empty_string_value_;
index c937463647135becaff0e2f9876f5ed4b19122dc..97f583424dfdc38d68af933e74d5e4daf1f25df8 100644 (file)
@@ -118,6 +118,7 @@ int main(int argc, char** argv) {
     defined(__ARMEL__) || defined(__avr32__) || defined(_M_ARM) || defined(_M_ARM64) || \
     defined(__hppa__) || defined(__ia64__) || \
     defined(__mips__) || \
+    defined(__loongarch__) || \
     defined(__nios2__) || defined(__ghs) || \
     defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__) || \
     defined(_POWER) || defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \
index e2a8ca9655b9fb9076fc3bcb37718ef86099aba6..de0fd1c807130015bac8ca0e11cdeedd65aa010d 100755 (executable)
@@ -4,7 +4,7 @@
 
 if [[ -z $1 ]]; then
        echo "Pass the current version tag of double-conversion as the first argument to this script";
-       echo "To pull the latest changes, use 'main'"
+       echo "To pull the latest changes, use 'master'"
        exit 1;
 fi
 
index a3add38fca62ada89d17fb330aa4822f3f1adc29..c7bb86e0889d2c3b1fef16ef602c4009ea77f99f 100644 (file)
@@ -1,3 +1,7 @@
+2021-05-19:
+  Loongarch is a RISC-style command system architecture.
+  Add support for loongarch architecture.
+
 2020-02-16:
   Add support for quiet and signaling NaNs to ieee header.
 
@@ -10,7 +14,7 @@
        the necessary line.
 
 2019-09-02:
-  Add support for e2k architectur. Thanks to Michael Shigorin.
+  Add support for e2k architecture. Thanks to Michael Shigorin.
 
 2019-08-01:
   Add min exponent width option in double-to-string conversion.
index dfd159dde10fe4a68a6a50e0a2ce5c4ff58bd3f9..15123e6a63cfad9d497d9de8885145ccf3101714 100644 (file)
@@ -276,7 +276,7 @@ static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator,
 
 // Let v = numerator / denominator < 10.
 // Then we generate 'count' digits of d = x.xxxxx... (without the decimal point)
-// from left to right. Once 'count' digits have been produced we decide wether
+// from left to right. Once 'count' digits have been produced we decide whether
 // to round up or down. Remainders of exactly .5 round upwards. Numbers such
 // as 9.999999 propagate a carry all the way, and change the
 // exponent (decimal_point), when rounding upwards.
index 876a047f226bd12cbea85785d5b50cf4a42ff9a9..04a4ac384002b7a2f58ad59c6dee064ad153c0b3 100644 (file)
@@ -123,7 +123,7 @@ class DoubleToStringConverter {
   // Example with max_leading_padding_zeroes_in_precision_mode = 6.
   //   ToPrecision(0.0000012345, 2) -> "0.0000012"
   //   ToPrecision(0.00000012345, 2) -> "1.2e-7"
-  // Similarily the converter may add up to
+  // Similarly the converter may add up to
   // max_trailing_padding_zeroes_in_precision_mode in precision mode to avoid
   // returning an exponential representation. A zero added by the
   // EMIT_TRAILING_ZERO_AFTER_POINT flag is counted for this limit.
@@ -181,7 +181,7 @@ class DoubleToStringConverter {
   // Example with decimal_in_shortest_low = -6,
   //              decimal_in_shortest_high = 21,
   //              EMIT_POSITIVE_EXPONENT_SIGN activated, and
-  //              EMIT_TRAILING_DECIMAL_POINT deactived:
+  //              EMIT_TRAILING_DECIMAL_POINT deactivated:
   //   ToShortest(0.000001)  -> "0.000001"
   //   ToShortest(0.0000001) -> "1e-7"
   //   ToShortest(111111111111111111111.0)  -> "111111111111111110000"
@@ -305,7 +305,7 @@ class DoubleToStringConverter {
   // Example with max_leading_padding_zeroes_in_precision_mode = 6.
   //   ToPrecision(0.0000012345, 2) -> "0.0000012"
   //   ToPrecision(0.00000012345, 2) -> "1.2e-7"
-  // Similarily the converter may add up to
+  // Similarly the converter may add up to
   // max_trailing_padding_zeroes_in_precision_mode in precision mode to avoid
   // returning an exponential representation. A zero added by the
   // EMIT_TRAILING_ZERO_AFTER_POINT flag is counted for this limit.
index f4702864375573447ee641e331a03f42a28b7492..d7a23984df2de338354fd7c7b3896f8e5fe63613 100644 (file)
@@ -565,7 +565,7 @@ static bool Grisu3(double v,
   // the difference between w and boundary_minus/plus (a power of 2) and to
   // compute scaled_boundary_minus/plus by subtracting/adding from
   // scaled_w. However the code becomes much less readable and the speed
-  // enhancements are not terriffic.
+  // enhancements are not terrific.
   DiyFp scaled_boundary_minus = DiyFp::Times(boundary_minus, ten_mk);
   DiyFp scaled_boundary_plus  = DiyFp::Times(boundary_plus,  ten_mk);
 
@@ -573,7 +573,7 @@ static bool Grisu3(double v,
   // v == (double) (scaled_w * 10^-mk).
   // Set decimal_exponent == -mk and pass it to DigitGen. If scaled_w is not an
   // integer than it will be updated. For instance if scaled_w == 1.23 then
-  // the buffer will be filled with "123" und the decimal_exponent will be
+  // the buffer will be filled with "123" and the decimal_exponent will be
   // decreased by 2.
   int kappa;
   bool result = DigitGen(scaled_boundary_minus, scaled_w, scaled_boundary_plus,
index ab6ef10eba2c16262c0cd4cf86cf788defee78f1..e739b19804cdc219376fc9e85f825d2e6af41ab7 100644 (file)
@@ -395,8 +395,8 @@ bool FastFixedDtoa(double v,
   TrimZeros(buffer, length, decimal_point);
   buffer[*length] = '\0';
   if ((*length) == 0) {
-    // The string is empty and the decimal_point thus has no importance. Mimick
-    // Gay's dtoa and and set it to -fractional_count.
+    // The string is empty and the decimal_point thus has no importance. Mimic
+    // Gay's dtoa and set it to -fractional_count.
     *decimal_point = -fractional_count;
   }
   return true;
index 85c3a082eb67c706dbb0c8cadd03a687a6e4113f..fe633aace78f236c34ca8cb8b21cf8059aea360f 100644 (file)
@@ -779,4 +779,40 @@ float StringToDoubleConverter::StringToFloat(
                                          processed_characters_count));
 }
 
+
+template<>
+double StringToDoubleConverter::StringTo<double>(
+    const char* buffer,
+    int length,
+    int* processed_characters_count) const {
+    return StringToDouble(buffer, length, processed_characters_count);
+}
+
+
+template<>
+float StringToDoubleConverter::StringTo<float>(
+    const char* buffer,
+    int length,
+    int* processed_characters_count) const {
+    return StringToFloat(buffer, length, processed_characters_count);
+}
+
+
+template<>
+double StringToDoubleConverter::StringTo<double>(
+    const uc16* buffer,
+    int length,
+    int* processed_characters_count) const {
+    return StringToDouble(buffer, length, processed_characters_count);
+}
+
+
+template<>
+float StringToDoubleConverter::StringTo<float>(
+    const uc16* buffer,
+    int length,
+    int* processed_characters_count) const {
+    return StringToFloat(buffer, length, processed_characters_count);
+}
+
 }  // namespace double_conversion
index ecd6c76197687cd194a1386652c00ad1421c4d5b..fdf302d4c38cec67f3bc9830231e58052ed7300d 100644 (file)
@@ -86,7 +86,7 @@ class StringToDoubleConverter {
   //      This *must* start with "0x" and separate the exponent with "p".
   //      Examples: 0x1.2p3 == 9.0
   //                0x10.1p0 == 16.0625
-  //      ALLOW_HEX and ALLOW_HEX_FLOATS are indendent.
+  //      ALLOW_HEX and ALLOW_HEX_FLOATS are indented.
   //
   // empty_string_value is returned when an empty string is given as input.
   // If ALLOW_LEADING_SPACES or ALLOW_TRAILING_SPACES are set, then a string
@@ -204,6 +204,18 @@ class StringToDoubleConverter {
                       int length,
                       int* processed_characters_count) const;
 
+  // Same as StringToDouble for T = double, and StringToFloat for T = float.
+  template <typename T>
+  T StringTo(const char* buffer,
+             int length,
+             int* processed_characters_count) const;
+
+  // Same as StringTo above but for 16 bit characters.
+  template <typename T>
+  T StringTo(const uc16* buffer,
+             int length,
+             int* processed_characters_count) const;
+
  private:
   const int flags_;
   const double empty_string_value_;
index 0cc74951d9e0d54e5d897f951f877ec2ece473c3..5fb1b2f104e545342cefca64b168546bb3877451 100644 (file)
@@ -550,7 +550,7 @@ float StrtofTrimmed(Vector<const char> trimmed, int exponent) {
   //    low-precision (3 digits):
   //       when read from input: 123
   //       when rounded from high precision: 124.
-  // To do this we simply look at the neigbors of the correct result and see
+  // To do this we simply look at the neighbors of the correct result and see
   // if they would round to the same float. If the guess is not correct we have
   // to look at four values (since two different doubles could be the correct
   // double).
index c72c333f020a1a4b4b1a64fb2de346addb30a7f2..c84c0fa56be50294c3e11ac7cae5e5253edc3be8 100644 (file)
@@ -108,6 +108,7 @@ int main(int argc, char** argv) {
     defined(__ARMEL__) || defined(__avr32__) || defined(_M_ARM) || defined(_M_ARM64) || \
     defined(__hppa__) || defined(__ia64__) || \
     defined(__mips__) || \
+    defined(__loongarch__) || \
     defined(__nios2__) || defined(__ghs) || \
     defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__) || \
     defined(_POWER) || defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \
index 325b7a1514146bbc29ce34db5bae29c00728e243..504d946b7f56cdc497cf85b912eb3102240c393a 100644 (file)
@@ -5889,3 +5889,89 @@ TEST(StringToDoubleCaseInsensitiveSpecialValues) {
   CHECK_EQ(1.0, converter.StringToDouble("+inf", 4, &processed));
   CHECK_EQ(0, processed);
 }
+
+
+TEST(StringToTemplate) {
+    // Test StringToDoubleConverter::StringTo<T>.
+
+    const StringToDoubleConverter converter(StringToDoubleConverter::ALLOW_HEX, 0.0, Double::NaN(), "inf", "nan");
+
+    // First simply check conversion from "0" and "1":
+    for (int i = 0; i <= 1; ++i)
+    {
+        const char c = '0' + i;
+
+        int processed = 0;
+        CHECK_EQ(static_cast<double>(i), converter.StringTo<double>(&c, 1, &processed));
+        CHECK_EQ(1, processed);
+
+        processed = 0;
+        CHECK_EQ(static_cast<float>(i), converter.StringTo<float>(&c, 1, &processed));
+        CHECK_EQ(1, processed);
+
+        const uc16 buffer16[1] = { static_cast<uc16>(c) };
+
+        processed = 0;
+        CHECK_EQ(static_cast<double>(i), converter.StringTo<double>(buffer16, 1, &processed));
+        CHECK_EQ(1, processed);
+
+        processed = 0;
+        CHECK_EQ(static_cast<float>(i), converter.StringTo<float>(buffer16, 1, &processed));
+        CHECK_EQ(1, processed);
+    }
+    {
+        // A number that can be represented by a double, but not by a float.
+        // Allows testing that StringTo<double> behaves like StringToDouble
+        // (and not like StringToFloat).
+        const char buffer[] = "1e+100";
+        const int length = DOUBLE_CONVERSION_ARRAY_SIZE(buffer) - 1;
+
+        int processed1 = 1;
+        int processed2 = 2;
+
+        CHECK_EQ(converter.StringToDouble(buffer, length, &processed1),
+                 converter.StringTo<double>(buffer, length, &processed2));
+        CHECK_EQ(processed1, processed2);
+
+        uc16 buffer16[DOUBLE_CONVERSION_ARRAY_SIZE(buffer)];
+
+        for (int i = 0; i <= length; ++i) {
+            buffer16[i] = buffer[i];
+        }
+
+        processed1 = 1;
+        processed2 = 2;
+
+        CHECK_EQ(converter.StringToDouble(buffer16, length, &processed1),
+                 converter.StringTo<double>(buffer16, length, &processed2));
+        CHECK_EQ(processed1, processed2);
+    }
+    {
+        // The double rounding example from TEST(StringToFloatHexString), which
+        // yields a slightly different result from StringToFloat than from
+        // StringToDouble. Allows testing that StringTo<float> behaves like
+        // StringToFloat (rather than like StringToDouble). 
+        const char buffer[] = "0x100000100000008";
+        const int length = DOUBLE_CONVERSION_ARRAY_SIZE(buffer) - 1;
+
+        int processed1 = 1;
+        int processed2 = 2;
+
+        CHECK_EQ(converter.StringToFloat(buffer, length, &processed1),
+                 converter.StringTo<float>(buffer, length, &processed2));
+        CHECK_EQ(processed1, processed2);
+
+        uc16 buffer16[DOUBLE_CONVERSION_ARRAY_SIZE(buffer)];
+
+        for (int i = 0; i <= length; ++i) {
+            buffer16[i] = buffer[i];
+        }
+
+        processed1 = 1;
+        processed2 = 2;
+
+        CHECK_EQ(converter.StringToFloat(buffer16, length, &processed1),
+                 converter.StringTo<float>(buffer16, length, &processed2));
+        CHECK_EQ(processed1, processed2);
+    }
+}