settings.fIncrement = increment;
settings.fMinFrac = static_cast<digits_t>(minFrac);
// One of the few pre-computed quantities:
+ // Note: it is possible for minFrac to be more than maxFrac... (misleading)
settings.fMaxFrac = roundingutils::doubleFractionLength(increment);
RounderUnion union_;
union_.increment = settings;
return;
}
double increment = dq.toDouble();
- macros.rounder = Rounder::increment(increment);
+
+ // We also need to figure out how many digits. Do a brute force string operation.
+ int decimalOffset = 0;
+ while (decimalOffset < segment.length() && segment.charAt(decimalOffset) != '.') {
+ decimalOffset++;
+ }
+ if (decimalOffset == segment.length()) {
+ macros.rounder = Rounder::increment(increment);
+ } else {
+ int32_t fractionLength = segment.length() - decimalOffset - 1;
+ macros.rounder = Rounder::increment(increment).withMinFraction(fractionLength);
+ }
}
-void blueprint_helpers::generateIncrementOption(double increment, UnicodeString& sb, UErrorCode&) {
+void blueprint_helpers::generateIncrementOption(double increment, int32_t trailingZeros, UnicodeString& sb,
+ UErrorCode&) {
// Utilize DecimalQuantity/double_conversion to format this for us.
DecimalQuantity dq;
dq.setToDouble(increment);
dq.roundToInfinity();
sb.append(dq.toPlainString());
+
+ // We might need to append extra trailing zeros for min fraction...
+ if (trailingZeros > 0) {
+ appendMultiple(sb, u'0', trailingZeros);
+ }
}
bool
} else if (macros.rounder.fType == Rounder::RND_INCREMENT) {
const Rounder::IncrementSettings& impl = macros.rounder.fUnion.increment;
sb.append(u"round-increment/", -1);
- blueprint_helpers::generateIncrementOption(impl.fIncrement, sb, status);
+ blueprint_helpers::generateIncrementOption(
+ impl.fIncrement,
+ impl.fMinFrac - impl.fMaxFrac,
+ sb,
+ status);
} else if (macros.rounder.fType == Rounder::RND_CURRENCY) {
UCurrencyUsage usage = macros.rounder.fUnion.currencyUsage;
if (usage == UCURR_USAGE_STANDARD) {
void parseIncrementOption(const StringSegment& segment, MacroProps& macros, UErrorCode& status);
-void generateIncrementOption(double increment, UnicodeString& sb, UErrorCode& status);
+void
+generateIncrementOption(double increment, int32_t trailingZeros, UnicodeString& sb, UErrorCode& status);
/** @return Whether we successfully found and parsed a rounding mode. */
bool parseRoundingModeOption(const StringSegment& segment, MacroProps& macros, UErrorCode& status);
assertFormatSingle(
u"MeasureUnit form without {0} in CLDR pattern and wide base form",
- u"measure-unit/temperature-kelvin .0000000000 unit-width-full-name",
+ u"measure-unit/temperature-kelvin .00000000000000000000 unit-width-full-name",
NumberFormatter::with().rounding(Rounder::fixedFraction(20))
.unit(KELVIN)
.unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME),
u"$444,444.00");
assertFormatSingle(
- u"currency/USD sign-accounting",
u"Sign Accounting Negative",
+ u"currency/USD sign-accounting",
NumberFormatter::with().sign(UNumberSignDisplay::UNUM_SIGN_ACCOUNTING).unit(USD),
Locale::getEnglish(),
-444444,
assertFormatSingle(
"MeasureUnit form without {0} in CLDR pattern and wide base form",
- "measure-unit/temperature-kelvin .0000000000 unit-width-full-name",
+ "measure-unit/temperature-kelvin .00000000000000000000 unit-width-full-name",
NumberFormatter.with()
- .rounding(Rounder.fixedFraction(10))
+ .rounding(Rounder.fixedFraction(20))
.unit(MeasureUnit.KELVIN)
.unitWidth(UnitWidth.FULL_NAME),
ULocale.forLanguageTag("es-MX"),
@Test
public void unitCompoundMeasure() {
assertFormatDescending(
- "Meters Per Second Short (unit that simplifies)",
+ "Meters Per Second Short (unit that simplifies) and perUnit method",
"measure-unit/length-meter per-measure-unit/duration-second",
NumberFormatter.with().unit(MeasureUnit.METER).perUnit(MeasureUnit.SECOND),
ULocale.ENGLISH,