ICU-20974 Correctly handle extreme values of double.
This commit is contained in:
parent
be3ee4cc63
commit
0b7f6b1864
@ -439,9 +439,6 @@ void DecimalQuantity::_setToDoubleFast(double n) {
|
||||
// TODO: Make a fast path for other types of doubles.
|
||||
if (!std::numeric_limits<double>::is_iec559) {
|
||||
convertToAccurateDouble();
|
||||
// Turn off the approximate double flag, since the value is now exact.
|
||||
isApproximate = false;
|
||||
origDouble = 0.0;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -456,8 +453,14 @@ void DecimalQuantity::_setToDoubleFast(double n) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (exponent == -1023 || exponent == 1024) {
|
||||
// The extreme values of exponent are special; use slow path.
|
||||
convertToAccurateDouble();
|
||||
return;
|
||||
}
|
||||
|
||||
// 3.3219... is log2(10)
|
||||
auto fracLength = static_cast<int32_t> ((52 - exponent) / 3.32192809489);
|
||||
auto fracLength = static_cast<int32_t> ((52 - exponent) / 3.32192809488736234787031942948939017586);
|
||||
if (fracLength >= 0) {
|
||||
int32_t i = fracLength;
|
||||
// 1e22 is the largest exact double.
|
||||
|
@ -1391,6 +1391,30 @@ void NumberFormatterApiTest::roundingOther() {
|
||||
u"1",
|
||||
u"1",
|
||||
u"0");
|
||||
|
||||
assertFormatSingle(
|
||||
u"ICU-20974 Double.MIN_NORMAL",
|
||||
u"scientific",
|
||||
u"E0",
|
||||
NumberFormatter::with().notation(Notation::scientific()),
|
||||
Locale::getEnglish(),
|
||||
DBL_MIN,
|
||||
u"2.225074E-308");
|
||||
|
||||
#ifndef DBL_TRUE_MIN
|
||||
#define DBL_TRUE_MIN 4.9E-324
|
||||
#endif
|
||||
|
||||
// Note: this behavior is intentionally different from Java; see
|
||||
// https://github.com/google/double-conversion/issues/126
|
||||
assertFormatSingle(
|
||||
u"ICU-20974 Double.MIN_VALUE",
|
||||
u"scientific",
|
||||
u"E0",
|
||||
NumberFormatter::with().notation(Notation::scientific()),
|
||||
Locale::getEnglish(),
|
||||
DBL_TRUE_MIN,
|
||||
u"5E-324");
|
||||
}
|
||||
|
||||
void NumberFormatterApiTest::grouping() {
|
||||
|
@ -488,8 +488,14 @@ public abstract class DecimalQuantity_AbstractBCD implements DecimalQuantity {
|
||||
return;
|
||||
}
|
||||
|
||||
if (exponent == -1023 || exponent == 1024) {
|
||||
// The extreme values of exponent are special; use slow path.
|
||||
convertToAccurateDouble();
|
||||
return;
|
||||
}
|
||||
|
||||
// 3.3219... is log2(10)
|
||||
int fracLength = (int) ((52 - exponent) / 3.32192809489);
|
||||
int fracLength = (int) ((52 - exponent) / 3.32192809488736234787031942948939017586);
|
||||
if (fracLength >= 0) {
|
||||
int i = fracLength;
|
||||
// 1e22 is the largest exact double.
|
||||
|
@ -1350,6 +1350,24 @@ public class NumberFormatterApiTest {
|
||||
"1",
|
||||
"1",
|
||||
"0");
|
||||
|
||||
assertFormatSingle(
|
||||
"ICU-20974 Double.MIN_NORMAL",
|
||||
"scientific",
|
||||
"E0",
|
||||
NumberFormatter.with().notation(Notation.scientific()),
|
||||
ULocale.ENGLISH,
|
||||
Double.MIN_NORMAL,
|
||||
"2.225074E-308");
|
||||
|
||||
assertFormatSingle(
|
||||
"ICU-20974 Double.MIN_VALUE",
|
||||
"scientific",
|
||||
"E0",
|
||||
NumberFormatter.with().notation(Notation.scientific()),
|
||||
ULocale.ENGLISH,
|
||||
Double.MIN_VALUE,
|
||||
"4.9E-324");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
Loading…
Reference in New Issue
Block a user