diff options
author | Steven R. Loomis <srloomis@us.ibm.com> | 2018-03-26 15:29:02 -0700 |
---|---|---|
committer | Steven R. Loomis <srloomis@us.ibm.com> | 2018-04-02 18:18:28 -0700 |
commit | 64211405dab824a570e52d000891c49415cc42b8 (patch) | |
tree | 4c196d0e2c19e083db1e124139dd4ba6272fd049 /deps/icu-small/source/i18n/number_decimalquantity.cpp | |
parent | 88773af540a36b23a47af0d6c4ce03b8cc3ef9aa (diff) | |
download | android-node-v8-64211405dab824a570e52d000891c49415cc42b8.tar.gz android-node-v8-64211405dab824a570e52d000891c49415cc42b8.tar.bz2 android-node-v8-64211405dab824a570e52d000891c49415cc42b8.zip |
deps: ICU 61.1 bump
- Update to released ICU 61.1, including:
- CLDR 33 (many new languages and data improvements)
- Many small API additions, improvements, and bug fixes
- note: 'icu::' namespace is no longer used by default
(Necessated https://github.com/nodejs/node/pull/18667 )
PR-URL: https://github.com/nodejs/node/pull/19621
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'deps/icu-small/source/i18n/number_decimalquantity.cpp')
-rw-r--r-- | deps/icu-small/source/i18n/number_decimalquantity.cpp | 67 |
1 files changed, 45 insertions, 22 deletions
diff --git a/deps/icu-small/source/i18n/number_decimalquantity.cpp b/deps/icu-small/source/i18n/number_decimalquantity.cpp index 7246357666..b68df26ba2 100644 --- a/deps/icu-small/source/i18n/number_decimalquantity.cpp +++ b/deps/icu-small/source/i18n/number_decimalquantity.cpp @@ -14,12 +14,15 @@ #include "decContext.h" #include "decNumber.h" #include "number_roundingutils.h" +#include "double-conversion.h" #include "unicode/plurrule.h" using namespace icu; using namespace icu::number; using namespace icu::number::impl; +using icu::double_conversion::DoubleToStringConverter; + namespace { int8_t NEGATIVE_FLAG = 1; @@ -265,6 +268,10 @@ bool DecimalQuantity::isNegative() const { return (flags & NEGATIVE_FLAG) != 0; } +int8_t DecimalQuantity::signum() const { + return isNegative() ? -1 : isZero() ? 0 : 1; +} + bool DecimalQuantity::isInfinite() const { return (flags & INFINITY_FLAG) != 0; } @@ -392,31 +399,27 @@ void DecimalQuantity::_setToDoubleFast(double n) { } void DecimalQuantity::convertToAccurateDouble() { - double n = origDouble; - U_ASSERT(n != 0); + U_ASSERT(origDouble != 0); int32_t delta = origDelta; - setBcdToZero(); - // Call the slow oracle function (Double.toString in Java, sprintf in C++). - // The <float.h> constant DBL_DIG defines a platform-specific number of digits in a double. - // However, this tends to be too low (see #11318). Instead, we always use 14 decimal places. - static constexpr size_t CAP = 1 + 14 + 8; // Extra space for '+', '.', e+NNN, and '\0' - char dstr[CAP]; - snprintf(dstr, CAP, "%+1.14e", n); - - // uprv_decNumberFromString() will parse the string expecting '.' as a - // decimal separator, however sprintf() can use ',' in certain locales. - // Overwrite a ',' with '.' here before proceeding. - char *decimalSeparator = strchr(dstr, ','); - if (decimalSeparator != nullptr) { - *decimalSeparator = '.'; - } - - StringPiece sp(dstr); - DecNumberWithStorage dn; - stringToDecNumber(dstr, dn); - _setToDecNumber(dn.getAlias()); + // Call the slow oracle function (Double.toString in Java, DoubleToAscii in C++). + char buffer[DoubleToStringConverter::kBase10MaximalLength + 1]; + bool sign; // unused; always positive + int32_t length; + int32_t point; + DoubleToStringConverter::DoubleToAscii( + origDouble, + DoubleToStringConverter::DtoaMode::SHORTEST, + 0, + buffer, + sizeof(buffer), + &sign, + &length, + &point + ); + setBcdToZero(); + readDoubleConversionToBcd(buffer, length, point); scale += delta; explicitExactDouble = true; } @@ -833,6 +836,26 @@ void DecimalQuantity::readDecNumberToBcd(decNumber *dn) { precision = dn->digits; } +void DecimalQuantity::readDoubleConversionToBcd( + const char* buffer, int32_t length, int32_t point) { + // NOTE: Despite the fact that double-conversion's API is called + // "DoubleToAscii", they actually use '0' (as opposed to u8'0'). + if (length > 16) { + ensureCapacity(length); + for (int32_t i = 0; i < length; i++) { + fBCD.bcdBytes.ptr[i] = buffer[length-i-1] - '0'; + } + } else { + uint64_t result = 0L; + for (int32_t i = 0; i < length; i++) { + result |= static_cast<uint64_t>(buffer[length-i-1] - '0') << (4 * i); + } + fBCD.bcdLong = result; + } + scale = point - length; + precision = length; +} + void DecimalQuantity::compact() { if (usingBytes) { int32_t delta = 0; |