From 1cec5dc1088e29c0b1ceb22a4faf4dcd4581ff3a Mon Sep 17 00:00:00 2001 From: macchiati Date: Tue, 14 May 2024 13:55:48 -0700 Subject: [PATCH] CLDR-17298 Catch case where the denominator is just a constant; also format with e notation. --- .../org/unicode/cldr/util/UnitConverter.java | 30 ++++++- .../org/unicode/cldr/unittest/TestUnits.java | 78 ++++++++++--------- 2 files changed, 70 insertions(+), 38 deletions(-) diff --git a/tools/cldr-code/src/main/java/org/unicode/cldr/util/UnitConverter.java b/tools/cldr-code/src/main/java/org/unicode/cldr/util/UnitConverter.java index 9da77ae9364..44620cfbb13 100644 --- a/tools/cldr-code/src/main/java/org/unicode/cldr/util/UnitConverter.java +++ b/tools/cldr-code/src/main/java/org/unicode/cldr/util/UnitConverter.java @@ -1073,6 +1073,7 @@ public int compare(String o1, String o2) { } Comparator UNIT_COMPARATOR = new UnitComparator(); + static final Pattern TRAILING_ZEROS = Pattern.compile("0+$"); /** Only handles the canonical units; no kilo-, only normalized, etc. */ // Thus we do not need to handle specials here @@ -1174,7 +1175,7 @@ public String toString() { for (int i = 1; i >= 0; --i) { // two passes, numerator then den. boolean positivePass = i > 0; if (positivePass && !factor.numerator.equals(BigInteger.ONE)) { - builder.append(factor.numerator); + builder.append(shortConstant(factor.numerator)); } Map target = positivePass ? numUnitsToPowers : denUnitsToPowers; @@ -1190,7 +1191,7 @@ public String toString() { firstDenominator = false; builder.append("per-"); if (!factor.denominator.equals(BigInteger.ONE)) { - builder.append(factor.denominator).append('-'); + builder.append(shortConstant(factor.denominator)).append('-'); } } } @@ -1213,10 +1214,35 @@ public String toString() { } builder.append(unit); } + if (!positivePass + && firstDenominator + && !factor.denominator.equals(BigInteger.ONE)) { + builder.append("-per-").append(shortConstant(factor.denominator)); + } } return builder.toString(); } + /** + * Return a string format. If larger than 7 digits, use 1eN format. + * + * @param source + * @return + */ + public String shortConstant(BigInteger source) { + // don't bother optimizing + String result = source.toString(); + if (result.length() < 8) { + return result; + } + Matcher matcher = TRAILING_ZEROS.matcher(result); + if (matcher.find()) { + int zeroCount = matcher.group().length(); + return result.substring(0, result.length() - zeroCount) + "e" + zeroCount; + } + return result; + } + public String toString( LocaleStringProvider resolvedFile, String width, diff --git a/tools/cldr-code/src/test/java/org/unicode/cldr/unittest/TestUnits.java b/tools/cldr-code/src/test/java/org/unicode/cldr/unittest/TestUnits.java index dc0931a07b3..6904d41efa4 100644 --- a/tools/cldr-code/src/test/java/org/unicode/cldr/unittest/TestUnits.java +++ b/tools/cldr-code/src/test/java/org/unicode/cldr/unittest/TestUnits.java @@ -1,41 +1,5 @@ package org.unicode.cldr.unittest; -import com.google.common.base.Joiner; -import com.google.common.base.Splitter; -import com.google.common.collect.BiMap; -import com.google.common.collect.Comparators; -import com.google.common.collect.ComparisonChain; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableMultimap; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.ImmutableSortedSet; -import com.google.common.collect.LinkedHashMultimap; -import com.google.common.collect.Multimap; -import com.google.common.collect.Multimaps; -import com.google.common.collect.Ordering; -import com.google.common.collect.Sets; -import com.google.common.collect.Sets.SetView; -import com.google.common.collect.TreeMultimap; -import com.ibm.icu.dev.test.TestFmwk; -import com.ibm.icu.impl.Row; -import com.ibm.icu.impl.Row.R2; -import com.ibm.icu.impl.Row.R3; -import com.ibm.icu.number.FormattedNumber; -import com.ibm.icu.number.LocalizedNumberFormatter; -import com.ibm.icu.number.Notation; -import com.ibm.icu.number.NumberFormatter; -import com.ibm.icu.number.NumberFormatter.UnitWidth; -import com.ibm.icu.number.Precision; -import com.ibm.icu.number.UnlocalizedNumberFormatter; -import com.ibm.icu.text.PluralRules; -import com.ibm.icu.text.UnicodeSet; -import com.ibm.icu.util.ICUUncheckedIOException; -import com.ibm.icu.util.Measure; -import com.ibm.icu.util.MeasureUnit; -import com.ibm.icu.util.Output; -import com.ibm.icu.util.ULocale; import java.io.File; import java.io.IOException; import java.io.OutputStreamWriter; @@ -68,6 +32,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import java.util.stream.StreamSupport; + import org.unicode.cldr.draft.FileUtilities; import org.unicode.cldr.test.CheckCLDR.CheckStatus; import org.unicode.cldr.test.CheckCLDR.Options; @@ -124,6 +89,43 @@ import org.unicode.cldr.util.XMLSource; import org.unicode.cldr.util.XPathParts; +import com.google.common.base.Joiner; +import com.google.common.base.Splitter; +import com.google.common.collect.BiMap; +import com.google.common.collect.Comparators; +import com.google.common.collect.ComparisonChain; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSortedSet; +import com.google.common.collect.LinkedHashMultimap; +import com.google.common.collect.Multimap; +import com.google.common.collect.Multimaps; +import com.google.common.collect.Ordering; +import com.google.common.collect.Sets; +import com.google.common.collect.Sets.SetView; +import com.google.common.collect.TreeMultimap; +import com.ibm.icu.dev.test.TestFmwk; +import com.ibm.icu.impl.Row; +import com.ibm.icu.impl.Row.R2; +import com.ibm.icu.impl.Row.R3; +import com.ibm.icu.number.FormattedNumber; +import com.ibm.icu.number.LocalizedNumberFormatter; +import com.ibm.icu.number.Notation; +import com.ibm.icu.number.NumberFormatter; +import com.ibm.icu.number.NumberFormatter.UnitWidth; +import com.ibm.icu.number.Precision; +import com.ibm.icu.number.UnlocalizedNumberFormatter; +import com.ibm.icu.text.PluralRules; +import com.ibm.icu.text.UnicodeSet; +import com.ibm.icu.util.ICUUncheckedIOException; +import com.ibm.icu.util.Measure; +import com.ibm.icu.util.MeasureUnit; +import com.ibm.icu.util.Output; +import com.ibm.icu.util.ULocale; + public class TestUnits extends TestFmwk { private static final boolean DEBUG = System.getProperty("TestUnits:DEBUG") != null; private static final boolean TEST_ICU = System.getProperty("TestUnits:TEST_ICU") != null; @@ -3197,6 +3199,10 @@ public void TestUnitOrder() { checkNormalization("test case", "newton-meter"); checkNormalization("test case", "acre-foot"); + checkNormalization("test case", "portion-per-1e9"); + checkNormalization("test case", "portion-per-1000"); + checkNormalization("test case", "1e9-meter"); + checkNormalization("test case", "1000-meter"); String stdAcre = converter.getStandardUnit("acre");