8281317: CompactNumberFormat displays 4-digit values when rounding to a new range

Reviewed-by: joehw
This commit is contained in:
Naoto Sato 2022-02-17 19:03:08 +00:00
parent cd9a3cf05b
commit 129277653e
2 changed files with 42 additions and 11 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -589,6 +589,10 @@ public final class CompactNumberFormat extends NumberFormat {
if (compactDataIndex != -1) { if (compactDataIndex != -1) {
long divisor = (Long) divisors.get(compactDataIndex); long divisor = (Long) divisors.get(compactDataIndex);
int iPart = getIntegerPart(number, divisor); int iPart = getIntegerPart(number, divisor);
if (checkIncrement(iPart, compactDataIndex, divisor)) {
divisor = (Long) divisors.get(++compactDataIndex);
iPart = getIntegerPart(number, divisor);
}
String prefix = getAffix(false, true, isNegative, compactDataIndex, iPart); String prefix = getAffix(false, true, isNegative, compactDataIndex, iPart);
String suffix = getAffix(false, false, isNegative, compactDataIndex, iPart); String suffix = getAffix(false, false, isNegative, compactDataIndex, iPart);
@ -658,6 +662,10 @@ public final class CompactNumberFormat extends NumberFormat {
if (compactDataIndex != -1) { if (compactDataIndex != -1) {
long divisor = (Long) divisors.get(compactDataIndex); long divisor = (Long) divisors.get(compactDataIndex);
int iPart = getIntegerPart(number, divisor); int iPart = getIntegerPart(number, divisor);
if (checkIncrement(iPart, compactDataIndex, divisor)) {
divisor = (Long) divisors.get(++compactDataIndex);
iPart = getIntegerPart(number, divisor);
}
String prefix = getAffix(false, true, isNegative, compactDataIndex, iPart); String prefix = getAffix(false, true, isNegative, compactDataIndex, iPart);
String suffix = getAffix(false, false, isNegative, compactDataIndex, iPart); String suffix = getAffix(false, false, isNegative, compactDataIndex, iPart);
if (!prefix.isEmpty() || !suffix.isEmpty()) { if (!prefix.isEmpty() || !suffix.isEmpty()) {
@ -753,6 +761,10 @@ public final class CompactNumberFormat extends NumberFormat {
if (compactDataIndex != -1) { if (compactDataIndex != -1) {
Number divisor = divisors.get(compactDataIndex); Number divisor = divisors.get(compactDataIndex);
int iPart = getIntegerPart(number.doubleValue(), divisor.doubleValue()); int iPart = getIntegerPart(number.doubleValue(), divisor.doubleValue());
if (checkIncrement(iPart, compactDataIndex, divisor.doubleValue())) {
divisor = divisors.get(++compactDataIndex);
iPart = getIntegerPart(number.doubleValue(), divisor.doubleValue());
}
String prefix = getAffix(false, true, isNegative, compactDataIndex, iPart); String prefix = getAffix(false, true, isNegative, compactDataIndex, iPart);
String suffix = getAffix(false, false, isNegative, compactDataIndex, iPart); String suffix = getAffix(false, false, isNegative, compactDataIndex, iPart);
if (!prefix.isEmpty() || !suffix.isEmpty()) { if (!prefix.isEmpty() || !suffix.isEmpty()) {
@ -820,6 +832,10 @@ public final class CompactNumberFormat extends NumberFormat {
if (compactDataIndex != -1) { if (compactDataIndex != -1) {
Number divisor = divisors.get(compactDataIndex); Number divisor = divisors.get(compactDataIndex);
int iPart = getIntegerPart(number.doubleValue(), divisor.doubleValue()); int iPart = getIntegerPart(number.doubleValue(), divisor.doubleValue());
if (checkIncrement(iPart, compactDataIndex, divisor.doubleValue())) {
divisor = divisors.get(++compactDataIndex);
iPart = getIntegerPart(number.doubleValue(), divisor.doubleValue());
}
String prefix = getAffix(false, true, isNegative, compactDataIndex, iPart); String prefix = getAffix(false, true, isNegative, compactDataIndex, iPart);
String suffix = getAffix(false, false, isNegative, compactDataIndex, iPart); String suffix = getAffix(false, false, isNegative, compactDataIndex, iPart);
if (!prefix.isEmpty() || !suffix.isEmpty()) { if (!prefix.isEmpty() || !suffix.isEmpty()) {
@ -875,7 +891,7 @@ public final class CompactNumberFormat extends NumberFormat {
* Appends the {@code prefix} to the {@code result} and also set the * Appends the {@code prefix} to the {@code result} and also set the
* {@code NumberFormat.Field.SIGN} and {@code NumberFormat.Field.PREFIX} * {@code NumberFormat.Field.SIGN} and {@code NumberFormat.Field.PREFIX}
* field positions. * field positions.
* @param result the resulting string, where the pefix is to be appended * @param result the resulting string, where the prefix is to be appended
* @param prefix prefix to append * @param prefix prefix to append
* @param delegate notified of the locations of * @param delegate notified of the locations of
* {@code NumberFormat.Field.SIGN} and * {@code NumberFormat.Field.SIGN} and
@ -910,7 +926,7 @@ public final class CompactNumberFormat extends NumberFormat {
* @param result the resulting string, where the text is to be appended * @param result the resulting string, where the text is to be appended
* @param string the text to append * @param string the text to append
* @param delegate notified of the locations of sub fields * @param delegate notified of the locations of sub fields
* @param positions a list of {@code FieldPostion} in the given * @param positions a list of {@code FieldPosition} in the given
* string * string
*/ */
private void append(StringBuffer result, String string, private void append(StringBuffer result, String string,
@ -956,10 +972,10 @@ public final class CompactNumberFormat extends NumberFormat {
} }
/** /**
* Returns a list of {@code FieldPostion} in the given {@code pattern}. * Returns a list of {@code FieldPosition} in the given {@code pattern}.
* @param pattern the pattern to be parsed for {@code FieldPosition} * @param pattern the pattern to be parsed for {@code FieldPosition}
* @param field whether a PREFIX or SUFFIX field * @param field whether a PREFIX or SUFFIX field
* @return a list of {@code FieldPostion} * @return a list of {@code FieldPosition}
*/ */
private List<FieldPosition> getFieldPositions(String pattern, Field field) { private List<FieldPosition> getFieldPositions(String pattern, Field field) {
List<FieldPosition> positions = new ArrayList<>(); List<FieldPosition> positions = new ArrayList<>();
@ -1769,7 +1785,7 @@ public final class CompactNumberFormat extends NumberFormat {
if (cnfMultiplier.longValue() != 1L) { if (cnfMultiplier.longValue() != 1L) {
double doubleResult = number.doubleValue() * cnfMultiplier.doubleValue(); double doubleResult = number.doubleValue() * cnfMultiplier.doubleValue();
doubleResult = (double) convertIfNegative(doubleResult, status, gotLongMin); doubleResult = (double) convertIfNegative(doubleResult, status, gotLongMin);
// Check if a double can be represeneted as a long // Check if a double can be represented as a long
long longResult = (long) doubleResult; long longResult = (long) doubleResult;
gotDouble = ((doubleResult != (double) longResult) gotDouble = ((doubleResult != (double) longResult)
|| (doubleResult == 0.0 && 1 / doubleResult < 0.0)); || (doubleResult == 0.0 && 1 / doubleResult < 0.0));
@ -2396,6 +2412,19 @@ public final class CompactNumberFormat extends NumberFormat {
.divide(BigDecimal.valueOf(divisor), roundingMode).intValue(); .divide(BigDecimal.valueOf(divisor), roundingMode).intValue();
} }
// Checks whether the iPart is incremented by the BigDecimal division in
// getIntegerPart(), and affects the compact number index.
private boolean checkIncrement(int iPart, int index, double divisor) {
if (index < compactPatterns.length - 1 &&
!"".equals(compactPatterns[index])) { // ignore empty pattern
var nextDiv = divisors.get(index + 1).doubleValue();
if (divisor != nextDiv) {
return Math.log10(iPart) == Math.log10(nextDiv) - Math.log10(divisor);
}
}
return false;
}
/** /**
* Returns LDML's tag from the plurals rules * Returns LDML's tag from the plurals rules
* *

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -22,7 +22,7 @@
*/ */
/* /*
* @test * @test
* @bug 8177552 8217254 8251499 * @bug 8177552 8217254 8251499 8281317
* @summary Checks the validity of compact number patterns specified through * @summary Checks the validity of compact number patterns specified through
* CompactNumberFormat constructor * CompactNumberFormat constructor
* @run testng/othervm TestCompactPatternsValidity * @run testng/othervm TestCompactPatternsValidity
@ -101,8 +101,9 @@ public class TestCompactPatternsValidity {
{COMPACT_PATTERN5, List.of(100, 1000, 30000), List.of("100", "1K", "K3")}, {COMPACT_PATTERN5, List.of(100, 1000, 30000), List.of("100", "1K", "K3")},
{COMPACT_PATTERN6, List.of(20.99, 1000, 30000), List.of("21", ".1K", ".30K")}, {COMPACT_PATTERN6, List.of(20.99, 1000, 30000), List.of("21", ".1K", ".30K")},
{COMPACT_PATTERN7, List.of(100, 1000, new BigInteger("12345678987654321")), List.of("100", "1K,", "12345678987654K,")}, {COMPACT_PATTERN7, List.of(100, 1000, new BigInteger("12345678987654321")), List.of("100", "1K,", "12345678987654K,")},
{COMPACT_PATTERN8, List.of(new BigInteger("223565686837667632"), new BigDecimal("12322456774334.89766"), 30000, 3456.78), {COMPACT_PATTERN8, List.of(new BigInteger("223565686837667632"), new BigDecimal("12322456774334.89766"), 30000, 3456.78,
List.of("223566T", "12T", "30K", "3K")}, new BigInteger("999999999999"), new BigDecimal("999999999999.0"), 999_999, 999_999_999),
List.of("223566T", "12T", "30K", "3K", "1T", "1T", "1M", "1B")},
{COMPACT_PATTERN9, List.of(new BigInteger("223566000000000000"), new BigDecimal("12345678987654567"), 30000, 3000), {COMPACT_PATTERN9, List.of(new BigInteger("223566000000000000"), new BigDecimal("12345678987654567"), 30000, 3000),
List.of("223,566,000,000,000,000", "12,345,678,987,654,567", "30,000", "3,000")}, List.of("223,566,000,000,000,000", "12,345,678,987,654,567", "30,000", "3,000")},
{COMPACT_PATTERN10, List.of(new BigInteger("100000000000000000"), new BigInteger("10000000000000000000"), new BigDecimal("555555555555555555555.89766"), 30000), {COMPACT_PATTERN10, List.of(new BigInteger("100000000000000000"), new BigInteger("10000000000000000000"), new BigDecimal("555555555555555555555.89766"), 30000),
@ -110,7 +111,8 @@ public class TestCompactPatternsValidity {
{COMPACT_PATTERN11, List.of(20.99, -20.99, 1000, -1000, 30000, -30000, new BigInteger("12345678987654321"), new BigInteger("-12345678987654321")), {COMPACT_PATTERN11, List.of(20.99, -20.99, 1000, -1000, 30000, -30000, new BigInteger("12345678987654321"), new BigInteger("-12345678987654321")),
List.of("21", "-21", "elfu 1", "elfu -1", "elfu 30", "elfu -30", "milioni 12345678988", "milioni -12345678988")}, List.of("21", "-21", "elfu 1", "elfu -1", "elfu 30", "elfu -30", "milioni 12345678988", "milioni -12345678988")},
{COMPACT_PATTERN12, List.of(0, 500, -500, 30000, -3000, 5000000), List.of("0", "H5H", "H-5H", "30K", "3K-", "H50G")}, {COMPACT_PATTERN12, List.of(0, 500, -500, 30000, -3000, 5000000), List.of("0", "H5H", "H-5H", "30K", "3K-", "H50G")},
{COMPACT_PATTERN13, List.of(1000, new BigInteger("10000000000000000000")), List.of("Thousand", "BeyondLong")}, {COMPACT_PATTERN13, List.of(1000, new BigInteger("10000000000000000000"), new BigDecimal("9999999999999999999.9")),
List.of("Thousand", "BeyondLong", "BeyondLong")},
}; };
} }