Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8677,4 +8677,41 @@ public void testStrictParse() throws java.text.ParseException {
}
}
}

/**
* Test that BigDecimal scale is correctly preserved when parsing numbers with trailing zeros.
* This is a regression test for ICU-22872.
*/
@Test
public void TestParseBigDecimalScale() throws ParseException {
DecimalFormat df = new DecimalFormat("0.00");
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new test depends on the JVM default locale using '.' as the decimal separator (inputs like "0.0"/"1.00"). If the test suite runs under a locale with ',' decimal separators, parsing these literals can fail or behave differently. Consider constructing the DecimalFormat with explicit DecimalFormatSymbols for a fixed locale (for example en-US) to make the test deterministic.

Suggested change
DecimalFormat df = new DecimalFormat("0.00");
DecimalFormat df = new DecimalFormat("0.00", DecimalFormatSymbols.getInstance(ULocale.US));

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better would be (DecimalFormat) NumberFormat.getInstance(ULocale.ROOT)

df.setParseBigDecimal(true);

// Test cases: input string, expected scale
Object[][] testCases = {
{"0.0", 1},
{"1.0", 1},
{"1.00", 2},
{"1.10", 2},
{"0.10", 2},
{"123.450", 3},
{"5.0000", 4},
};
Comment on lines +8690 to +8699
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The production change in ParsedNumber.getNumber() has a branch that skips the scale adjustment when an exponent is present (FLAG_HAS_EXPONENT). This test suite currently doesn't include any exponent inputs (for example "1.00E0" or "1.0E3") to lock in the intended behavior and prevent regressions.

Copilot uses AI. Check for mistakes.

for (Object[] testCase : testCases) {
String input = (String) testCase[0];
int expectedScale = (Integer) testCase[1];
Number result = df.parse(input);
assertTrue(
"Result should be BigDecimal for input: " + input,
result instanceof BigDecimal);
BigDecimal bd = (BigDecimal) result;
assertEquals("Scale mismatch for input: " + input, expectedScale, bd.scale());
}

// Verify values are correct, not just scales
assertEquals("Value check for 0.0", new BigDecimal("0.0"), df.parse("0.0"));
assertEquals("Value check for 1.00", new BigDecimal("1.00"), df.parse("1.00"));
assertEquals("Value check for 123.450", new BigDecimal("123.450"), df.parse("123.450"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -710,7 +710,13 @@ public BigDecimal toBigDecimal() {
// Converting to a BigDecimal requires Double.toString().
convertToAccurateDouble();
}
return bcdToBigDecimal();
BigDecimal result = bcdToBigDecimal();
// Preserve trailing zeros recorded by setMinFraction
int minScale = -getLowerDisplayMagnitude();
if (minScale > result.scale()) {
result = result.setScale(minScale);
}
return result;
}

private static int safeSubtract(int a, int b) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,7 @@ public boolean match(StringSegment segment, ParsedNumber result, int exponentSig

// Adjust for fraction part.
digitsConsumed.adjustMagnitude(-digitsAfterDecimalPlace);
digitsConsumed.setMinFraction(digitsAfterDecimalPlace);

// Set the digits, either normal or exponent.
if (exponentSign != 0 && segment.getOffset() != initialOffset) {
Expand Down
Loading