summaryrefslogtreecommitdiff
path: root/deps/icu-small/source/i18n/number_decimalquantity.cpp
diff options
context:
space:
mode:
authorSteven R. Loomis <srloomis@us.ibm.com>2018-03-26 15:29:02 -0700
committerSteven R. Loomis <srloomis@us.ibm.com>2018-04-02 18:18:28 -0700
commit64211405dab824a570e52d000891c49415cc42b8 (patch)
tree4c196d0e2c19e083db1e124139dd4ba6272fd049 /deps/icu-small/source/i18n/number_decimalquantity.cpp
parent88773af540a36b23a47af0d6c4ce03b8cc3ef9aa (diff)
downloadandroid-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.cpp67
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;