ICU-20058 Fix mimimum significant digits in engineering notation

- Follow the spec to calculate the mimimum significant digits in engineering notation
- The bug is regression since ICU 58. The new test still passes on
ICU58-based DecimalFormat
- Maximum significant digits is not changed
This commit is contained in:
Victor Chang 2018-09-14 14:24:05 +01:00 committed by Shane Carr
parent cc5bf22a0c
commit b62200061c
No known key found for this signature in database
GPG Key ID: FCED3B24AAB18B5C
4 changed files with 40 additions and 9 deletions

View File

@ -225,8 +225,8 @@ MacroProps NumberPropertyMapper::oldToNew(const DecimalFormatProperties& propert
// TODO: Overriding here is a bit of a hack. Should this logic go earlier?
if (macros.precision.fType == Precision::PrecisionType::RND_FRACTION) {
// For the purposes of rounding, get the original min/max int/frac, since the local
// variables
// have been manipulated for display purposes.
// variables have been manipulated for display purposes.
int maxInt_ = properties.maximumIntegerDigits;
int minInt_ = properties.minimumIntegerDigits;
int minFrac_ = properties.minimumFractionDigits;
int maxFrac_ = properties.maximumFractionDigits;
@ -237,9 +237,15 @@ MacroProps NumberPropertyMapper::oldToNew(const DecimalFormatProperties& propert
// Patterns like "#.##E0" (no zeros in the mantissa), which mean round to maxFrac+1
macros.precision = Precision::constructSignificant(1, maxFrac_ + 1).withMode(roundingMode);
} else {
// All other scientific patterns, which mean round to minInt+maxFrac
macros.precision = Precision::constructSignificant(
minInt_ + minFrac_, minInt_ + maxFrac_).withMode(roundingMode);
int maxSig_ = minInt_ + maxFrac_;
// Bug #20058: if maxInt_ > minInt_ > 1, then minInt_ should be 1.
if (maxInt_ > minInt_ && minInt_ > 1) {
minInt_ = 1;
}
int minSig_ = minInt_ + minFrac_;
// To avoid regression, maxSig is not reset when minInt_ set to 1.
// TODO: Reset maxSig_ = 1 + minFrac_ to follow the spec.
macros.precision = Precision::constructSignificant(minSig_, maxSig_).withMode(roundingMode);
}
}
}

View File

@ -353,6 +353,15 @@ minIntegerDigits maxIntegerDigits minFractionDigits maxFractionDigits output bre
// JDK fails here because it tries to use 9 + 6 = 15 sig digits.
2 9 1 6 29.979246E7 K
test ticket 20058
set locale en
begin
pattern format output breaks
#00.0##E0 0 0.0E0 K
#00.0##E0 1.2 1.2E0 K
#00.0E0 0 0.0E0 K
#00.0E0 1.2 1.2E0 K
test significant digits scientific
set locale en
set pattern #E0

View File

@ -263,8 +263,8 @@ final class NumberPropertyMapper {
// TODO: Overriding here is a bit of a hack. Should this logic go earlier?
if (macros.precision instanceof FractionPrecision) {
// For the purposes of rounding, get the original min/max int/frac, since the local
// variables
// have been manipulated for display purposes.
// variables have been manipulated for display purposes.
int maxInt_ = properties.getMaximumIntegerDigits();
int minInt_ = properties.getMinimumIntegerDigits();
int minFrac_ = properties.getMinimumFractionDigits();
int maxFrac_ = properties.getMaximumFractionDigits();
@ -275,8 +275,15 @@ final class NumberPropertyMapper {
// Patterns like "#.##E0" (no zeros in the mantissa), which mean round to maxFrac+1
macros.precision = Precision.constructSignificant(1, maxFrac_ + 1).withMode(mathContext);
} else {
// All other scientific patterns, which mean round to minInt+maxFrac
macros.precision = Precision.constructSignificant(minInt_ + minFrac_, minInt_ + maxFrac_)
int maxSig_ = minInt_ + maxFrac_;
// Bug #20058: if maxInt_ > minInt_ > 1, then minInt_ should be 1.
if (maxInt_ > minInt_ && minInt_ > 1) {
minInt_ = 1;
}
int minSig_ = minInt_ + minFrac_;
// To avoid regression, maxSig is not reset when minInt_ set to 1.
// TODO: Reset maxSig_ = 1 + minFrac_ to follow the spec.
macros.precision = Precision.constructSignificant(minSig_, maxSig_)
.withMode(mathContext);
}
}

View File

@ -353,6 +353,15 @@ minIntegerDigits maxIntegerDigits minFractionDigits maxFractionDigits output bre
// JDK fails here because it tries to use 9 + 6 = 15 sig digits.
2 9 1 6 29.979246E7 K
test ticket 20058
set locale en
begin
pattern format output breaks
#00.0##E0 0 0.0E0 K
#00.0##E0 1.2 1.2E0 K
#00.0E0 0 0.0E0 K
#00.0E0 1.2 1.2E0 K
test significant digits scientific
set locale en
set pattern #E0