undefect. CWE-407 — 63 sites patched across 27 ecosystems
Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com Patches, unit tests, benchmarks, whitepaper, and outreach briefs. Public domain — no copyright claimed. Use freely.
This commit is contained in:
commit
0a580b313d
70422 changed files with 17213626 additions and 0 deletions
50
test/jdk/java/text/Format/DecimalFormat/AffixTest.java
Normal file
50
test/jdk/java/text/Format/DecimalFormat/AffixTest.java
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8351074
|
||||
* @summary Test input value check for DecimalFormat affix setter methods
|
||||
* @run junit AffixTest
|
||||
*/
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
public class AffixTest {
|
||||
|
||||
@Test
|
||||
public void nullPrefixTest() {
|
||||
assertThrows(NullPointerException.class, () -> new DecimalFormat().setPositivePrefix(null));
|
||||
assertThrows(NullPointerException.class, () -> new DecimalFormat().setNegativePrefix(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullSuffixTest() {
|
||||
assertThrows(NullPointerException.class, () -> new DecimalFormat().setPositiveSuffix(null));
|
||||
assertThrows(NullPointerException.class, () -> new DecimalFormat().setNegativeSuffix(null));
|
||||
}
|
||||
}
|
||||
129
test/jdk/java/text/Format/DecimalFormat/Bug6609740.java
Normal file
129
test/jdk/java/text/Format/DecimalFormat/Bug6609740.java
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* @test
|
||||
* @bug 6609740
|
||||
* @summary Checks the formatting and parsing of a number based
|
||||
* on the positive and negative sub-patterns, also
|
||||
* checks few invalid number patterns
|
||||
*/
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.ParseException;
|
||||
import java.util.Locale;
|
||||
|
||||
public class Bug6609740 {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
double dNumber = -3456.349347;
|
||||
String fOutput = "(3,456.35)";
|
||||
String[] validCases = {"#,##0.0#;(#,##0.0#)", "#,##0.0#;(#)",
|
||||
"#,##0.0#;(#,##0)"};
|
||||
|
||||
// formatting with the valid cases
|
||||
NumberFormat nf = NumberFormat.getInstance(Locale.US);
|
||||
for (String pattern : validCases) {
|
||||
formatOnPattern(nf, pattern, dNumber, fOutput);
|
||||
}
|
||||
|
||||
// parsing with the valid cases
|
||||
String parseString = "(3,456.35)";
|
||||
Number pOutput = -3456.35;
|
||||
for (String pattern : validCases) {
|
||||
parseOnPattern(nf, pattern, parseString, pOutput);
|
||||
}
|
||||
|
||||
// should throw parse exception
|
||||
String[] invalidParseCases = {"#,##0.0#;0", "#,##0.0#;()"};
|
||||
for (String pattern : invalidParseCases) {
|
||||
if (nf instanceof DecimalFormat) {
|
||||
((DecimalFormat) nf).applyPattern(pattern);
|
||||
}
|
||||
|
||||
try {
|
||||
nf.parse(parseString);
|
||||
} catch (ParseException ex) {
|
||||
continue;
|
||||
}
|
||||
throw new RuntimeException("[FAILED: Should throw"
|
||||
+ " ParseException for pattern: "
|
||||
+ pattern + " and input: " + parseString + "]");
|
||||
}
|
||||
|
||||
// should throw exception on invalid patterns
|
||||
// invalid patterns: no positive subpattern, zero after non-zero in
|
||||
// the decimal part i.e. 0#0, multiple decimal separators,
|
||||
// multiple percent, malformed pattern
|
||||
String[] invalidPatterns = {";(#,##0.0#)", "#,##0.0#0;(#)",
|
||||
"#,##0.0.#", "#,##0%%", ".#,##0"};
|
||||
for (String pattern : invalidPatterns) {
|
||||
if (nf instanceof DecimalFormat) {
|
||||
try {
|
||||
((DecimalFormat) nf).applyPattern(pattern);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
continue;
|
||||
}
|
||||
throw new RuntimeException("[FAILED: Should throw"
|
||||
+ " IllegalArgumentException for invalid pattern: "
|
||||
+ pattern + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void formatOnPattern(NumberFormat nf, String pattern,
|
||||
double number, String expected) {
|
||||
|
||||
if (nf instanceof DecimalFormat) {
|
||||
((DecimalFormat) nf).applyPattern(pattern);
|
||||
}
|
||||
|
||||
String formatted = nf.format(number);
|
||||
if (!formatted.equals(expected)) {
|
||||
throw new RuntimeException("[FAILED: Unable to format the number"
|
||||
+ " based on the pattern: '" + pattern + "', Expected : '"
|
||||
+ expected + "', Found: '" + formatted + "']");
|
||||
}
|
||||
}
|
||||
|
||||
private static void parseOnPattern(NumberFormat nf, String pattern,
|
||||
String parseString, Number expected) {
|
||||
|
||||
if (nf instanceof DecimalFormat) {
|
||||
((DecimalFormat) nf).applyPattern(pattern);
|
||||
}
|
||||
|
||||
try {
|
||||
Number output = nf.parse(parseString);
|
||||
if (expected.doubleValue() != output.doubleValue()) {
|
||||
throw new RuntimeException("[FAILED: Unable to parse the number"
|
||||
+ " based on the pattern: '" + pattern + "', Expected : '"
|
||||
+ expected + "', Found: '" + output + "']");
|
||||
}
|
||||
} catch (ParseException ex) {
|
||||
throw new RuntimeException("[FAILED: Unable to parse the pattern:"
|
||||
+ " '" + pattern + "']", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
73
test/jdk/java/text/Format/DecimalFormat/Bug7196316.java
Normal file
73
test/jdk/java/text/Format/DecimalFormat/Bug7196316.java
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* @test
|
||||
* @bug 7196316
|
||||
* @summary Confirm that a non-default rounding mode is used even after deserialization.
|
||||
*/
|
||||
|
||||
|
||||
import java.io.*;
|
||||
import java.math.*;
|
||||
import java.text.*;
|
||||
|
||||
public class Bug7196316 {
|
||||
|
||||
private static final String filename = "bug7196316.ser";
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
DecimalFormat df;
|
||||
RoundingMode mode = RoundingMode.DOWN;
|
||||
double given = 6.6;
|
||||
String expected;
|
||||
String actual;
|
||||
|
||||
try (ObjectOutputStream os
|
||||
= new ObjectOutputStream(new FileOutputStream(filename))) {
|
||||
df = new DecimalFormat("#");
|
||||
df.setRoundingMode(mode);
|
||||
expected = df.format(given);
|
||||
os.writeObject(df);
|
||||
}
|
||||
|
||||
try (ObjectInputStream is
|
||||
= new ObjectInputStream(new FileInputStream(filename))) {
|
||||
df = (DecimalFormat)is.readObject();
|
||||
}
|
||||
|
||||
RoundingMode newMode = df.getRoundingMode();
|
||||
if (mode != newMode) {
|
||||
throw new RuntimeException("Unexpected roundig mode: " + newMode);
|
||||
} else {
|
||||
actual = df.format(given);
|
||||
if (!expected.equals(actual)) {
|
||||
throw new RuntimeException("Unexpected formatted result: \""
|
||||
+ actual + "\"");
|
||||
} else {
|
||||
System.out.println("Passed: Expected rounding mode (" + newMode
|
||||
+ ") & formatted result: \"" + actual + "\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
95
test/jdk/java/text/Format/DecimalFormat/Bug8165466.java
Normal file
95
test/jdk/java/text/Format/DecimalFormat/Bug8165466.java
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* @test
|
||||
* @bug 8165466
|
||||
* @summary Checks the subsequent function calls of the DecimalFormat.format()
|
||||
* method in which the minimumFractionDigit is set to 0 and one of
|
||||
* the format() call include formatting of the number with zero
|
||||
* fraction value e.g. 0.00, 9.00
|
||||
*/
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Locale;
|
||||
|
||||
public class Bug8165466 {
|
||||
|
||||
public static void main(String[] args) {
|
||||
DecimalFormat nf = (DecimalFormat) DecimalFormat
|
||||
.getPercentInstance(Locale.US);
|
||||
nf.setMaximumFractionDigits(3);
|
||||
nf.setMinimumFractionDigits(0);
|
||||
nf.setMultiplier(1);
|
||||
|
||||
double d = 0.005678;
|
||||
String result = nf.format(d);
|
||||
if (!result.equals("0.006%")) {
|
||||
throw new RuntimeException("[Failed while formatting the double"
|
||||
+ " value: " + d + " Expected: 0.006%, Found: " + result
|
||||
+ "]");
|
||||
}
|
||||
|
||||
d = 0.00;
|
||||
result = nf.format(d);
|
||||
if (!result.equals("0%")) {
|
||||
throw new RuntimeException("[Failed while formatting the double"
|
||||
+ " value: " + d + " Expected: 0%, Found: " + result
|
||||
+ "]");
|
||||
}
|
||||
|
||||
d = 0.005678;
|
||||
result = nf.format(d);
|
||||
if (!result.equals("0.006%")) {
|
||||
throw new RuntimeException("[Failed while formatting the double"
|
||||
+ " value: " + d + " Expected: 0.006%, Found: " + result
|
||||
+ "]");
|
||||
}
|
||||
|
||||
//checking with the non zero value
|
||||
d = 0.005678;
|
||||
result = nf.format(d);
|
||||
if (!result.equals("0.006%")) {
|
||||
throw new RuntimeException("[Failed while formatting the double"
|
||||
+ " value: " + d + " Expected: 0.006%, Found: " + result
|
||||
+ "]");
|
||||
}
|
||||
|
||||
d = 9.00;
|
||||
result = nf.format(d);
|
||||
if (!result.equals("9%")) {
|
||||
throw new RuntimeException("[Failed while formatting the double"
|
||||
+ " value: " + d + " Expected: 9%, Found: " + result
|
||||
+ "]");
|
||||
}
|
||||
|
||||
d = 0.005678;
|
||||
result = nf.format(d);
|
||||
if (!result.equals("0.006%")) {
|
||||
throw new RuntimeException("[Failed while formatting the double"
|
||||
+ " value: " + d + " Expected: 0.006%, Found: " + result
|
||||
+ "]");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
156
test/jdk/java/text/Format/DecimalFormat/CloneTest.java
Normal file
156
test/jdk/java/text/Format/DecimalFormat/CloneTest.java
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8354522 8358880 8367324
|
||||
* @summary Check for cloning interference
|
||||
* @library /test/lib
|
||||
* @run junit/othervm --add-opens=java.base/java.text=ALL-UNNAMED CloneTest
|
||||
*/
|
||||
|
||||
import jtreg.SkippedException;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.math.BigDecimal;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class CloneTest {
|
||||
|
||||
// Note: this is a white-box test that may fail if the implementation is changed
|
||||
@Test
|
||||
public void testClone() {
|
||||
DecimalFormat df = new DecimalFormat("#");
|
||||
new CloneTester(df).testClone();
|
||||
}
|
||||
|
||||
// Note: this is a white-box test that may fail if the implementation is changed
|
||||
@Test
|
||||
public void testCloneAfterInit() {
|
||||
DecimalFormat df = new DecimalFormat("#");
|
||||
|
||||
// This initial use of the formatter initialises its internal state, which could
|
||||
// subsequently be shared across clones. This is key to reproducing this specific
|
||||
// issue.
|
||||
String _ = df.format(Math.PI);
|
||||
new CloneTester(df).testClone();
|
||||
}
|
||||
|
||||
private static class CloneTester {
|
||||
private final Field digitListField;
|
||||
private final Class<?> digitListClass;
|
||||
private final DecimalFormat original;
|
||||
|
||||
public CloneTester(DecimalFormat original) {
|
||||
this.original = original;
|
||||
try {
|
||||
digitListField = DecimalFormat.class.getDeclaredField("digitList");
|
||||
digitListField.setAccessible(true);
|
||||
|
||||
DecimalFormat df = new DecimalFormat();
|
||||
Object digitList = digitListField.get(df);
|
||||
|
||||
digitListClass = digitList.getClass();
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new SkippedException("reflective access in white-box test failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void testClone() {
|
||||
try {
|
||||
DecimalFormat dfClone = (DecimalFormat) original.clone();
|
||||
|
||||
Object digits = valFromDigitList(original, "digits");
|
||||
assertNotSame(digits, valFromDigitList(dfClone, "digits"));
|
||||
|
||||
assertEquals(digitListField.get(original), digitListField.get(dfClone));
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new SkippedException("reflective access in white-box test failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
private Object valFromDigitList(DecimalFormat df, String fieldName) throws ReflectiveOperationException {
|
||||
Object digitList = digitListField.get(df);
|
||||
Field field = digitListClass.getDeclaredField(fieldName);
|
||||
field.setAccessible(true);
|
||||
|
||||
return field.get(digitList);
|
||||
}
|
||||
}
|
||||
|
||||
// Tests that when DecimalFormat is cloned after use with
|
||||
// a long double/BigDecimal, clones will be independent. This is not an
|
||||
// exhaustive test. This tests for the issue of the same DigitList.data
|
||||
// array being reused across clones of DecimalFormat.
|
||||
|
||||
@Test
|
||||
public void testCloneIndependence() {
|
||||
AtomicInteger mismatchCount = new AtomicInteger(0);
|
||||
DecimalFormat df = new DecimalFormat("#");
|
||||
CountDownLatch startSignal = new CountDownLatch(1);
|
||||
|
||||
// This initial use of the formatter initialises its internal state, which could
|
||||
// subsequently be shared across clones. This is key to reproducing this specific
|
||||
// issue.
|
||||
String _ = df.format(Math.PI);
|
||||
|
||||
try (var ex = Executors.newThreadPerTaskExecutor(Thread.ofPlatform().factory())) {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
final int finalI = i;
|
||||
// Each thread gets its own clone of df
|
||||
DecimalFormat threadDf = (DecimalFormat) df.clone();
|
||||
Runnable task = () -> {
|
||||
try {
|
||||
startSignal.await();
|
||||
for (int j = 0; j < 1_000; j++) {
|
||||
if (mismatchCount.get() > 0) {
|
||||
// Exit early if mismatch has already occurred
|
||||
break;
|
||||
}
|
||||
|
||||
int value = finalI * j;
|
||||
String dfString = threadDf.format(BigDecimal.valueOf(value));
|
||||
String str = String.valueOf(value);
|
||||
if (!str.equals(dfString)) {
|
||||
mismatchCount.getAndIncrement();
|
||||
System.err.println("mismatch: str = " + str + " dfString = " + dfString);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
};
|
||||
ex.execute(task);
|
||||
}
|
||||
startSignal.countDown(); // let all tasks start working at the same time
|
||||
}
|
||||
assertEquals(0, mismatchCount.get());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,328 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4068067 4101150 8366401
|
||||
* @library /java/text/testlib
|
||||
* @build HexDumpReader
|
||||
* @summary Check serialization of DecimalFormatSymbols. That is, ensure the
|
||||
* behavior for each stream version is correct during de-serialization.
|
||||
* @run junit/othervm --add-opens java.base/java.text=ALL-UNNAMED DFSSerializationTest
|
||||
*/
|
||||
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InvalidObjectException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Field;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
import java.util.Currency;
|
||||
import java.util.Locale;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
public class DFSSerializationTest {
|
||||
|
||||
// Test that rely on hex dump files that were written from older JDK versions
|
||||
@Nested
|
||||
class HexDumpTests {
|
||||
|
||||
@Test // See 4068067 and CDFS which is the class in the serialized hex dump
|
||||
void JDK1_1_4Test() {
|
||||
// Reconstruct a class serialized during 1.1.4 which has a DFS holder
|
||||
var cdfs = (CheckDecimalFormatSymbols) assertDoesNotThrow(
|
||||
() -> deSer("DecimalFormatSymbols.114.txt"));
|
||||
assertDoesNotThrow(cdfs::Update); // Checks getDigit call succeeds
|
||||
}
|
||||
|
||||
@Test // See 4068067
|
||||
void JDK1_4_2Test() {
|
||||
// Reconstruct a 1.4.2 DFS
|
||||
var dfs = (DecimalFormatSymbols) assertDoesNotThrow(
|
||||
() -> deSer("DecimalFormatSymbols.142.txt"));
|
||||
// Checks curr symbol is saved, and exponent separator default set
|
||||
assertEquals("E", dfs.getExponentSeparator());
|
||||
assertEquals("*SpecialCurrencySymbol*", dfs.getCurrencySymbol());
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
class StreamVersionTests {
|
||||
|
||||
// Ensure correct monetarySeparator and exponential field defaults
|
||||
// Reads monetary from decimal, and sets exponential to 'E'
|
||||
@Test
|
||||
void version0Test() {
|
||||
var crafted = new DFSBuilder()
|
||||
.setVer(0)
|
||||
.set("monetarySeparator", '~')
|
||||
.set("exponential", 'Z')
|
||||
.build();
|
||||
var bytes = ser(crafted);
|
||||
var dfs = assertDoesNotThrow(() -> deSer(bytes));
|
||||
// Check exponential is set to proper default 'E', not 'Z'
|
||||
assertEquals('E', readField(dfs, "exponential"));
|
||||
// Ensure that mSep is based on dSep, and is not '~'
|
||||
assertNotEquals('~', dfs.getMonetaryDecimalSeparator());
|
||||
assertEquals(dfs.getDecimalSeparator(), dfs.getMonetaryDecimalSeparator());
|
||||
}
|
||||
|
||||
// Version 1 did not have a locale field, and it defaulted to Locale.ROOT.
|
||||
// Note that other versions did allow a locale field, which was nullable.
|
||||
// E.g. see nullableLocaleTest which does not set locale when it is `null`
|
||||
@Test
|
||||
void version1Test() {
|
||||
var crafted = new DFSBuilder()
|
||||
.setVer(1)
|
||||
.set("locale", null)
|
||||
.build();
|
||||
var bytes = ser(crafted);
|
||||
var dfs = assertDoesNotThrow(() -> deSer(bytes));
|
||||
assertEquals(Locale.ROOT, dfs.getLocale());
|
||||
}
|
||||
|
||||
// Version 2 did not have an exponential separator, and created it via exponent
|
||||
// char field.
|
||||
@Test
|
||||
void version2Test() {
|
||||
var crafted = new DFSBuilder()
|
||||
.setVer(2)
|
||||
.set("exponentialSeparator", null)
|
||||
.set("exponential", '~')
|
||||
.build();
|
||||
var bytes = ser(crafted);
|
||||
var dfs = assertDoesNotThrow(() -> deSer(bytes));
|
||||
assertEquals("~", dfs.getExponentSeparator());
|
||||
}
|
||||
|
||||
// Version 3 didn't have perMillText, percentText, and minusSignText.
|
||||
// These were created from the corresponding char equivalents.
|
||||
@Test
|
||||
void version3Test() {
|
||||
var crafted = new DFSBuilder()
|
||||
.setVer(3)
|
||||
.set("perMillText", null)
|
||||
.set("percentText", null)
|
||||
.set("minusSignText", null)
|
||||
.set("perMill", '~')
|
||||
.set("percent", '~')
|
||||
.set("minusSign", '~')
|
||||
.build();
|
||||
var bytes = ser(crafted);
|
||||
var dfs = assertDoesNotThrow(() -> deSer(bytes));
|
||||
// Need to check these String fields using reflection, since they
|
||||
// are not exposed via the public API
|
||||
assertEquals("~", readField(dfs, "perMillText"));
|
||||
assertEquals("~", readField(dfs, "percentText"));
|
||||
assertEquals("~", readField(dfs, "minusSignText"));
|
||||
}
|
||||
|
||||
// Version 4 did not have monetaryGroupingSeparator. It should be based
|
||||
// off of groupingSeparator.
|
||||
@Test
|
||||
void version4Test() {
|
||||
var crafted = new DFSBuilder()
|
||||
.setVer(4)
|
||||
.set("monetaryGroupingSeparator", 'Z')
|
||||
.set("groupingSeparator", '~')
|
||||
.build();
|
||||
var bytes = ser(crafted);
|
||||
var dfs = assertDoesNotThrow(() -> deSer(bytes));
|
||||
assertEquals(dfs.getGroupingSeparator(), dfs.getMonetaryGroupingSeparator());
|
||||
}
|
||||
}
|
||||
|
||||
// Up-to-date DFS stream versions do not expect a null locale since the
|
||||
// standard DecimalFormatSymbols API forbids it. However, this was not always
|
||||
// the case and previous stream versions can contain a null locale. Thus,
|
||||
// ensure that a null locale does not cause number data loading to fail.
|
||||
@Test
|
||||
void nullableLocaleTest() {
|
||||
var bytes = ser(new DFSBuilder()
|
||||
.set("locale", null)
|
||||
.set("minusSignText", "zFoo")
|
||||
.set("minusSign", 'z') // Set so that char/String forms agree
|
||||
.build());
|
||||
var dfs = assertDoesNotThrow(() -> deSer(bytes));
|
||||
assertNull(dfs.getLocale());
|
||||
// LMS should be based off of minusSignText when locale is null
|
||||
assertEquals("zFoo", readField(dfs, "lenientMinusSigns"));
|
||||
}
|
||||
|
||||
// readObject fails when the {@code char} and {@code String} representations
|
||||
// of percent, per mille, and/or minus sign disagree.
|
||||
@Test
|
||||
void disagreeingTextTest() {
|
||||
var expected = "'char' and 'String' representations of either percent, " +
|
||||
"per mille, and/or minus sign disagree.";
|
||||
assertEquals(expected, assertThrows(InvalidObjectException.class, () ->
|
||||
deSer(ser(new DFSBuilder()
|
||||
.set("minusSignText", "Z")
|
||||
.set("minusSign", 'X')
|
||||
.build()))).getMessage());
|
||||
assertEquals(expected, assertThrows(InvalidObjectException.class, () ->
|
||||
deSer(ser(new DFSBuilder()
|
||||
.set("perMillText", "Z")
|
||||
.set("perMill", 'X')
|
||||
.build()))).getMessage());
|
||||
assertEquals(expected, assertThrows(InvalidObjectException.class, () ->
|
||||
deSer(ser(new DFSBuilder()
|
||||
.set("percentText", "Z")
|
||||
.set("percent", 'X')
|
||||
.build()))).getMessage());
|
||||
}
|
||||
|
||||
// Ensure the serial version is updated to the current after de-serialization.
|
||||
@Test
|
||||
void updatedVersionTest() {
|
||||
var bytes = ser(new DFSBuilder().setVer(-25).build());
|
||||
var dfs = assertDoesNotThrow(() -> deSer(bytes));
|
||||
assertEquals(5, readField(dfs, "serialVersionOnStream"));
|
||||
}
|
||||
|
||||
// Should set currency from 4217 code when it is valid.
|
||||
@Test
|
||||
void validIntlCurrencyTest() {
|
||||
var bytes = ser(new DFSBuilder().set("intlCurrencySymbol", "JPY").build());
|
||||
var dfs = assertDoesNotThrow(() -> deSer(bytes));
|
||||
assertEquals(Currency.getInstance("JPY"), dfs.getCurrency());
|
||||
}
|
||||
|
||||
// Should not set currency when 4217 code is invalid, it remains null.
|
||||
@Test
|
||||
void invalidIntlCurrencyTest() {
|
||||
var bytes = ser(new DFSBuilder()
|
||||
.set("intlCurrencySymbol", ">.,")
|
||||
.set("locale", Locale.JAPAN)
|
||||
.build());
|
||||
var dfs = assertDoesNotThrow(() -> deSer(bytes));
|
||||
// Can not init off invalid 4217 code, remains null
|
||||
assertNull(dfs.getCurrency());
|
||||
}
|
||||
|
||||
// Ensure the currency symbol is read properly
|
||||
@Test
|
||||
void currencySymbolTest() {
|
||||
var crafted = new DecimalFormatSymbols();
|
||||
crafted.setCurrencySymbol("*SpecialCurrencySymbol*");
|
||||
var bytes = ser(crafted);
|
||||
var dfs = assertDoesNotThrow(() -> deSer(bytes));
|
||||
assertEquals("*SpecialCurrencySymbol*", dfs.getCurrencySymbol());
|
||||
}
|
||||
|
||||
// Ensure the exponent separator is read properly
|
||||
@Test
|
||||
void exponentSeparatorTest() {
|
||||
var crafted = new DecimalFormatSymbols();
|
||||
crafted.setExponentSeparator("*SpecialExponentSeparator*");
|
||||
var bytes = ser(crafted);
|
||||
var dfs = assertDoesNotThrow(() -> deSer(bytes));
|
||||
assertEquals("*SpecialExponentSeparator*", dfs.getExponentSeparator());
|
||||
}
|
||||
|
||||
// Utilities ----
|
||||
|
||||
// Utility to serialize
|
||||
private static byte[] ser(Object obj) {
|
||||
return assertDoesNotThrow(() -> {
|
||||
try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(byteArrayOutputStream)) {
|
||||
oos.writeObject(obj);
|
||||
return byteArrayOutputStream.toByteArray();
|
||||
}
|
||||
}, "Unexpected error during serialization");
|
||||
}
|
||||
|
||||
// Utility to deserialize from byte array
|
||||
private static DecimalFormatSymbols deSer(byte[] bytes) throws IOException, ClassNotFoundException {
|
||||
try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
|
||||
ObjectInputStream ois = new ObjectInputStream(byteArrayInputStream)) {
|
||||
return (DecimalFormatSymbols) ois.readObject();
|
||||
}
|
||||
}
|
||||
|
||||
// Utility to deserialize from file in hex format
|
||||
private static Object deSer(String file) throws IOException, ClassNotFoundException {
|
||||
try (InputStream stream = HexDumpReader.getStreamFromHexDump(file);
|
||||
ObjectInputStream ois = new ObjectInputStream(stream)) {
|
||||
return ois.readObject();
|
||||
}
|
||||
}
|
||||
|
||||
// Utility to read a private field
|
||||
private static Object readField(DecimalFormatSymbols dfs, String name) {
|
||||
return assertDoesNotThrow(() -> {
|
||||
var field = DecimalFormatSymbols.class.getDeclaredField(name);
|
||||
field.setAccessible(true);
|
||||
return field.get(dfs);
|
||||
}, "Unexpected error during field reading");
|
||||
}
|
||||
|
||||
// Utility class to build instances of DFS via reflection
|
||||
private static class DFSBuilder {
|
||||
|
||||
private final DecimalFormatSymbols dfs;
|
||||
|
||||
private DFSBuilder() {
|
||||
dfs = new DecimalFormatSymbols();
|
||||
}
|
||||
|
||||
private DFSBuilder setVer(Object value) {
|
||||
return set("serialVersionOnStream", value);
|
||||
}
|
||||
|
||||
private DFSBuilder set(String field, Object value) {
|
||||
return assertDoesNotThrow(() -> {
|
||||
Field f = dfs.getClass().getDeclaredField(field);
|
||||
f.setAccessible(true);
|
||||
f.set(dfs, value);
|
||||
return this;
|
||||
}, "Unexpected error during reflection setting");
|
||||
}
|
||||
|
||||
private DecimalFormatSymbols build() {
|
||||
return dfs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Not nested, so that it can be cast correctly for the 1.1.4 test
|
||||
class CheckDecimalFormatSymbols implements Serializable {
|
||||
DecimalFormatSymbols _decFormatSymbols = new DecimalFormatSymbols();
|
||||
public char Update()
|
||||
{
|
||||
return _decFormatSymbols.getDigit();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
#
|
||||
# Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
# Hex dump of a serialized DecimalFormat for SerializationLoadTest.
|
||||
|
||||
aced000573720012436865636b446563696d616c466f726d6174aa9218d3b530
|
||||
540a0200014c000a5f646563466f726d61747400194c6a6176612f746578742f
|
||||
446563696d616c466f726d61743b7870737200176a6176612e746578742e4465
|
||||
63696d616c466f726d61740bff0362d872303a0200085a001b646563696d616c
|
||||
536570617261746f72416c7761797353686f776e42000c67726f7570696e6753
|
||||
697a6549000a6d756c7469706c6965724c000e6e656761746976655072656669
|
||||
787400124c6a6176612f6c616e672f537472696e673b4c000e6e656761746976
|
||||
655375666669787400124c6a6176612f6c616e672f537472696e673b4c000e70
|
||||
6f7369746976655072656669787400124c6a6176612f6c616e672f537472696e
|
||||
673b4c000e706f7369746976655375666669787400124c6a6176612f6c616e67
|
||||
2f537472696e673b4c000773796d626f6c737400204c6a6176612f746578742f
|
||||
446563696d616c466f726d617453796d626f6c733b787200166a6176612e7465
|
||||
78742e4e756d626572466f726d6174dff6b3bf137d07e80200065a000c67726f
|
||||
7570696e67557365644200116d61784672616374696f6e446967697473420010
|
||||
6d6178496e74656765724469676974734200116d696e4672616374696f6e4469
|
||||
676974734200106d696e496e74656765724469676974735a0010706172736549
|
||||
6e74656765724f6e6c79787200106a6176612e746578742e466f726d6174fbd8
|
||||
bc12e90f1843020000787001037f0001000003000000017400012d7400007400
|
||||
007400007372001e6a6176612e746578742e446563696d616c466f726d617453
|
||||
796d626f6c73501d17990868939c02000c430010646563696d616c5365706172
|
||||
61746f72430005646967697443001167726f7570696e67536570617261746f72
|
||||
4300096d696e75735369676e4300107061747465726e536570617261746f7243
|
||||
00077065724d696c6c43000770657263656e744300097a65726f44696769744c
|
||||
00034e614e7400124c6a6176612f6c616e672f537472696e673b4c000e637572
|
||||
72656e637953796d626f6c7400124c6a6176612f6c616e672f537472696e673b
|
||||
4c0008696e66696e6974797400124c6a6176612f6c616e672f537472696e673b
|
||||
4c0012696e746c43757272656e637953796d626f6c7400124c6a6176612f6c61
|
||||
6e672f537472696e673b7870002e0023002c002d003b203000250030740003ef
|
||||
bfbd74000124740003e2889e740003555344
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
#
|
||||
# Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
# Hex dump of a serialized DecimalFormatSymbols for SerializationLoadTest.
|
||||
|
||||
aced000573720019436865636b446563696d616c466f726d617453796d626f6c
|
||||
737763237e1aa359bb0200014c00115f646563466f726d617453796d626f6c73
|
||||
7400204c6a6176612f746578742f446563696d616c466f726d617453796d626f
|
||||
6c733b78707372001e6a6176612e746578742e446563696d616c466f726d6174
|
||||
53796d626f6c73501d17990868939c02000c430010646563696d616c53657061
|
||||
7261746f72430005646967697443001167726f7570696e67536570617261746f
|
||||
724300096d696e75735369676e4300107061747465726e536570617261746f72
|
||||
4300077065724d696c6c43000770657263656e744300097a65726f4469676974
|
||||
4c00034e614e7400124c6a6176612f6c616e672f537472696e673b4c000e6375
|
||||
7272656e637953796d626f6c7400124c6a6176612f6c616e672f537472696e67
|
||||
3b4c0008696e66696e6974797400124c6a6176612f6c616e672f537472696e67
|
||||
3b4c0012696e746c43757272656e637953796d626f6c7400124c6a6176612f6c
|
||||
616e672f537472696e673b7870002e0023002c002d003b203000250030740003
|
||||
efbfbd74000124740003e2889e740003555344
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
#
|
||||
# Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
# Hex dump of a serialized DecimalFormatSymbols for SerializationLoadTest.
|
||||
|
||||
aced00057372001e6a6176612e746578742e446563696d616c466f726d617453
|
||||
796d626f6c73501d17990868939c020010430010646563696d616c5365706172
|
||||
61746f72430005646967697443000b6578706f6e656e7469616c43001167726f
|
||||
7570696e67536570617261746f724300096d696e75735369676e4300116d6f6e
|
||||
6574617279536570617261746f724300107061747465726e536570617261746f
|
||||
724300077065724d696c6c43000770657263656e7449001573657269616c5665
|
||||
7273696f6e4f6e53747265616d4300097a65726f44696769744c00034e614e74
|
||||
00124c6a6176612f6c616e672f537472696e673b4c000e63757272656e637953
|
||||
796d626f6c71007e00014c0008696e66696e69747971007e00014c0012696e74
|
||||
6c43757272656e637953796d626f6c71007e00014c00066c6f63616c65740012
|
||||
4c6a6176612f7574696c2f4c6f63616c653b7870002e00230045002c002d002e
|
||||
003b20300025000000020030740003efbfbd7400172a5370656369616c437572
|
||||
72656e637953796d626f6c2a740003e2889e740003434e59737200106a617661
|
||||
2e7574696c2e4c6f63616c657ef811609c30f9ec03000449000868617368636f
|
||||
64654c0007636f756e74727971007e00014c00086c616e677561676571007e00
|
||||
014c000776617269616e7471007e00017870ffffffff740002434e7400027a68
|
||||
74000078
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8362448
|
||||
* @summary Verify DecimalFormat::format on doubles.
|
||||
* @run junit DoubleFormattingTest
|
||||
* @run junit/othervm -Djdk.compat.DecimalFormat=true DoubleFormattingTest
|
||||
*/
|
||||
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Formatter;
|
||||
import java.util.Locale;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class DoubleFormattingTest {
|
||||
|
||||
private static final boolean COMPAT = Boolean.getBoolean("jdk.compat.DecimalFormat");
|
||||
|
||||
static Stream<Arguments> testFormat() {
|
||||
return Stream.of(
|
||||
Arguments.of(4.8726570057E288, 0),
|
||||
Arguments.of(7.3879E20, 0),
|
||||
Arguments.of(1.9400994884341945E25, 0),
|
||||
Arguments.of(6.3E-322, 324)
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
void testFormat(double v, int minFractionDigits) {
|
||||
DecimalFormat df = (DecimalFormat) NumberFormat.getNumberInstance(Locale.ROOT);
|
||||
df.setGroupingUsed(false);
|
||||
df.setMinimumFractionDigits(minFractionDigits);
|
||||
String actual = df.format(v);
|
||||
Formatter fmt = new Formatter(Locale.ROOT);
|
||||
fmt.format("%." + minFractionDigits + "f", v);
|
||||
String expected = fmt.toString();
|
||||
if (COMPAT) {
|
||||
assertNotEquals(expected, actual);
|
||||
} else {
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
53
test/jdk/java/text/Format/DecimalFormat/EqualityTest.java
Normal file
53
test/jdk/java/text/Format/DecimalFormat/EqualityTest.java
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8327640
|
||||
* @summary Check parseStrict correctness for DecimalFormat.equals()
|
||||
* @run junit EqualityTest
|
||||
*/
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
|
||||
public class EqualityTest {
|
||||
|
||||
private static final DecimalFormat fmt1 = new DecimalFormat();
|
||||
private static final DecimalFormat fmt2 = new DecimalFormat();
|
||||
|
||||
// Ensure that parseStrict is reflected correctly for DecimalFormat.equals()
|
||||
@Test
|
||||
public void checkStrictTest() {
|
||||
// parseStrict is false by default
|
||||
assertEquals(fmt1, fmt2);
|
||||
fmt1.setStrict(true);
|
||||
assertNotEquals(fmt1, fmt2);
|
||||
fmt2.setStrict(true);
|
||||
assertEquals(fmt1, fmt2);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,926 @@
|
|||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 7050528
|
||||
* @summary Set of micro-benchmarks testing throughput of java.text.DecimalFormat.format()
|
||||
* @author Olivier Lagneau
|
||||
* @run main FormatMicroBenchmark
|
||||
*/
|
||||
|
||||
/* This is a set of micro-benchmarks testing throughput of java.text.DecimalFormat.format().
|
||||
* It never fails.
|
||||
*
|
||||
* Usage and arguments:
|
||||
* - Run with no argument skips the whole benchmark and exits.
|
||||
* - Run with "-help" as first argument calls the usage() method and exits.
|
||||
* - Run with "-doit" runs the benchmark with summary details.
|
||||
* - Run with "-verbose" provides additional details on the run.
|
||||
*
|
||||
* Example run :
|
||||
* java -Xms500m -Xmx500m -XX:NewSize=400m FormatMicroBenchmark -doit -verbose
|
||||
*
|
||||
* Running with jtreg:
|
||||
* The jtreg header "run" tag options+args must be changed to avoid skipping
|
||||
* the execution. here is an example of run options:
|
||||
* "main/othervm -Xms500m -Xmx500m -XX:NewSize=400m FormatMicroBenchmark -doit"
|
||||
*
|
||||
* Note:
|
||||
* - Vm options -Xms, -Xmx, -XX:NewSize must be set correctly for
|
||||
* getting reliable numbers. Otherwise GC activity may corrupt results.
|
||||
* As of jdk80b48 using "-Xms500m -Xmx500m -XX:NewSize=400m" covers
|
||||
* all cases.
|
||||
* - Optionally using "-Xlog:gc" option provides information that
|
||||
* helps checking any GC activity while benches are run.
|
||||
*
|
||||
* Vm Options:
|
||||
* - Vm options to use (as of jdk80b48):
|
||||
* fast-path case : -Xms128m -Xmx128m -XX:NewSize=100m
|
||||
* non fast-path case: -Xms500m -Xmx500m -XX:NewSize=400m
|
||||
* or use worst case (non fast-path above) with both types of algorithm.
|
||||
*
|
||||
* - use -Xlog:gc to verify memory consumption of the benchmarks.
|
||||
* (See "Checking Memory Consumption" below).
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* Fast-path algorithm for format(double...) call stack is very different of
|
||||
* the standard call stack. Where the standard algorithm for formating double
|
||||
* uses internal class sun.misc.FloatingDecimal and its dtoa(double) method to
|
||||
* provide digits, fast-path embeds its own algorithm for binary to decimal
|
||||
* string conversion.
|
||||
*
|
||||
* FloatingDecimal always converts completely the passed double to a string.
|
||||
* Fast-path converts only to the needed digits since it follows constraints
|
||||
* on both the pattern rule, the DecimalFormat instance properties, and the
|
||||
* passed double.
|
||||
*
|
||||
* Micro benchmarks below measure the throughput for formating double values
|
||||
* using NumberFormat.format(double) call stack. The standard DecimalFormat
|
||||
* call stack as well as the fast-path algorithm implementation are sensitive
|
||||
* to the nature of the passed double values regarding throughput performance.
|
||||
*
|
||||
* These benchmarks are useful both for measuring the global performance gain
|
||||
* of fast-path and to check that any modification done on fast-path algorithm
|
||||
* does not bring any regression in the performance boost of fast-path.
|
||||
*
|
||||
* Note that these benchmarks will provide numbers without any knowledge of
|
||||
* the implementation of DecimalFormat class. So to check regression any run
|
||||
* should be compared to another reference run with a previous JDK, whether or
|
||||
* not this previous reference JDK contains fast-path implementation.
|
||||
*
|
||||
* The eight benchmarks below are dedicated to measure throughput on different
|
||||
* kinds of double that all fall in the fast-path case (all in Integer range):
|
||||
*
|
||||
* - Integer case : used double values are all "integer-like" (ex: -12345.0).
|
||||
* This is the benchFormatInteger micro-benchmark.
|
||||
*
|
||||
* - Fractional case : double values are "fractional" (ex: -0.12345).
|
||||
* This is the benchFormatFractional micro-benchmark.
|
||||
*
|
||||
* - Small integral case : like Integer case but double values are all limited
|
||||
* in their magnitude, from -500.0 to 500.0 if the number of iterations N is
|
||||
* set to 500000.
|
||||
* This is the benchFormatSmallIntegral micro-benchmark.
|
||||
*
|
||||
* - Fractional All Nines : doubles values have fractional part that is very
|
||||
* close to "999" (decimal pattern), or "99" (currency pattern),
|
||||
* or "0000...".
|
||||
* This is the benchFormatFractionalAllNines micro-benchmark.
|
||||
*
|
||||
* - All Nines : double values are such that both integral and fractional
|
||||
* part consist only of '9' digits. None of these values are rounded up.
|
||||
* This is the benchFormatAllNines micro-benchmark.
|
||||
*
|
||||
* - Fair simple case : calling J the loop variable and iterating over
|
||||
* the N number of iterations, used double values are computed as
|
||||
* d = (double) J + J*seed
|
||||
* where seed is a very small value that adds a fractional part and adds a
|
||||
* small number to integral part. Provides fairly distributed double values.
|
||||
* This is the benchFormatFairSimple micro-benchmark.
|
||||
*
|
||||
* - Fair case : this is a combination of small integral case and fair simple
|
||||
* case. Double values are limited in their magnitude but follow a parabolic
|
||||
* curve y = x**2 / K, keeping large magnitude only for large values of J.
|
||||
* The intent is trying to reproduce a distribution of double values as could
|
||||
* be found in a business application, with most values in either the low
|
||||
* range or the high range.
|
||||
* This is the benchFormatFair micro-benchmark.
|
||||
*
|
||||
* - Tie cases: values are very close to a tie case (iii...ii.fff5)
|
||||
* That is the worst situation that can happen for Fast-path algorithm when
|
||||
* considering throughput.
|
||||
* This is the benchFormatTie micro-benchmark.
|
||||
*
|
||||
* For all of the micro-benchmarks, the throughput load of the eventual
|
||||
* additional computations inside the loop is calculated prior to running the
|
||||
* benchmark, and provided in the output. That may be useful since this load
|
||||
* may vary for each architecture or machine configuration.
|
||||
*
|
||||
* The "-verbose" flag, when set, provides the throughput load numbers, the
|
||||
* time spent for each run of a benchmark, as well as an estimation of the
|
||||
* memory consumed by the runs. Beware of incremental GCs, see "Checking
|
||||
* Memory Consumption" section below. Every run should be done with correct
|
||||
* ms, mx, and NewSize vm options to get fully reliable numbers.
|
||||
*
|
||||
* The output provides the mean time needed for a benchmark after the server
|
||||
* jit compiler has done its optimization work if any. Thus only the last but
|
||||
* first three runs are taken into account in the time measurement (server jit
|
||||
* compiler shows to have done full optimization in most cases after the
|
||||
* second run, given a base number of iterations set to 500000).
|
||||
*
|
||||
* The program cleans up memory (stabilizeMemory() method) between each run of
|
||||
* the benchmarks to make sure that no garbage collection activity happens in
|
||||
* measurements. However that does not preclude incremental GCs activity that
|
||||
* may happen during the micro-benchmark if -Xms, -Xmx, and NewSize options
|
||||
* have not been tuned and set correctly.
|
||||
*
|
||||
* Checking Memory Consumption:
|
||||
*
|
||||
* For getting confidence in the throughput numbers, there must not give any
|
||||
* GC activity during the benchmark runs. That means that specific VM options
|
||||
* related to memory must be tuned for any given implementation of the JDK.
|
||||
*
|
||||
* Running with "-verbose" arguments will provide clues of the memory consumed
|
||||
* but is not enough, since any unexpected incremental GC may lower
|
||||
* artificially the estimation of the memory consumption.
|
||||
*
|
||||
* Options to set are -Xms, -Xmx, -XX:NewSize, plus -Xlog:gc to evaluate
|
||||
* correctly the values of these options. When running "-verbose", varying
|
||||
* numbers reported for memory consumption may indicate bad choices for these
|
||||
* options.
|
||||
*
|
||||
* For jdk80b25, fast-path shows a consuption of ~60Mbs for 500000 iterations
|
||||
* while a jdk without fast-path will consume ~260Mbs for each benchmark run.
|
||||
* Indeed these values will vary depending on the jdk used.
|
||||
*
|
||||
* Correct option settings found jdk80b48 were :
|
||||
* fast-path : -Xms128m -Xmx128m -XX:NewSize=100m
|
||||
* non fast-path : -Xms500m -Xmx500m -XX:NewSize=400m
|
||||
* Greater values can be provided safely but not smaller ones.
|
||||
* ----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
import java.util.*;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
public class FormatMicroBenchmark {
|
||||
|
||||
// The number of times the bench method will be run (must be at least 4).
|
||||
private static final int NB_RUNS = 20;
|
||||
|
||||
// The bench* methods below all iterates over [-MAX_RANGE , +MAX_RANGE] integer values.
|
||||
private static final int MAX_RANGE = 500000;
|
||||
|
||||
// Flag for more details on each bench run (default is no).
|
||||
private static boolean Verbose = false;
|
||||
|
||||
// Should we really execute the benches ? (no by default).
|
||||
private static boolean DoIt = false;
|
||||
|
||||
// Prints out a message describing how to run the program.
|
||||
private static void usage() {
|
||||
System.out.println(
|
||||
"This is a set of micro-benchmarks testing throughput of " +
|
||||
"java.text.DecimalFormat.format(). It never fails.\n\n" +
|
||||
"Usage and arguments:\n" +
|
||||
" - Run with no argument skips the whole benchmark and exits.\n" +
|
||||
" - Run with \"-help\" as first argument prints this message and exits.\n" +
|
||||
" - Run with \"-doit\" runs the benchmark with summary details.\n" +
|
||||
" - Run with \"-verbose\" provides additional details on the run.\n\n" +
|
||||
"Example run :\n" +
|
||||
" java -Xms500m -Xmx500m -XX:NewSize=400m FormatMicroBenchmark -doit -verbose\n\n" +
|
||||
"Note: \n" +
|
||||
" - Vm options -Xms, -Xmx, -XX:NewSize must be set correctly for \n" +
|
||||
" getting reliable numbers. Otherwise GC activity may corrupt results.\n" +
|
||||
" As of jdk80b48 using \"-Xms500m -Xmx500m -XX:NewSize=400m\" covers \n" +
|
||||
" all cases.\n" +
|
||||
" - Optionally using \"-Xlog:gc\" option provides information that \n" +
|
||||
" helps checking any GC activity while benches are run.\n\n" +
|
||||
"Look at the heading comments and description in source code for " +
|
||||
"detailed information.\n");
|
||||
}
|
||||
|
||||
/* We will call stabilizeMemory before each call of benchFormat***().
|
||||
* This in turn tries to clean up as much memory as possible.
|
||||
* As a safe bound we limit number of System.gc() calls to 10,
|
||||
* but most of the time two calls to System.gc() will be enough.
|
||||
* If memory reporting is asked for, the method returns the difference
|
||||
* of free memory between entering an leaving the method.
|
||||
*/
|
||||
private static long stabilizeMemory(boolean reportConsumedMemory) {
|
||||
final long oneMegabyte = 1024L * 1024L;
|
||||
|
||||
long refMemory = 0;
|
||||
long initialMemoryLeft = Runtime.getRuntime().freeMemory();
|
||||
long currMemoryLeft = initialMemoryLeft;
|
||||
int nbGCCalls = 0;
|
||||
|
||||
do {
|
||||
nbGCCalls++;
|
||||
|
||||
refMemory = currMemoryLeft;
|
||||
System.gc();
|
||||
currMemoryLeft = Runtime.getRuntime().freeMemory();
|
||||
|
||||
} while ((Math.abs(currMemoryLeft - refMemory) > oneMegabyte) &&
|
||||
(nbGCCalls < 10));
|
||||
|
||||
if (Verbose &&
|
||||
reportConsumedMemory)
|
||||
System.out.println("Memory consumed by previous run : " +
|
||||
(currMemoryLeft - initialMemoryLeft)/oneMegabyte + "Mbs.");
|
||||
|
||||
return currMemoryLeft;
|
||||
}
|
||||
|
||||
|
||||
// ---------- Integer only based bench --------------------
|
||||
private static final String INTEGER_BENCH = "benchFormatInteger";
|
||||
private static String benchFormatInteger(NumberFormat nf) {
|
||||
String str = "";
|
||||
for (int j = - MAX_RANGE; j <= MAX_RANGE; j++)
|
||||
str = nf.format((double) j);
|
||||
return str;
|
||||
}
|
||||
|
||||
// This reproduces the throughput load added in benchFormatInteger
|
||||
static double integerThroughputLoad() {
|
||||
double d = 0.0d;
|
||||
for (int j = - MAX_RANGE; j <= MAX_RANGE; j++) {
|
||||
d = (double) j;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
// Runs integerThroughputLoad and calculate its mean load
|
||||
static void calculateIntegerThroughputLoad() {
|
||||
int nbRuns = NB_RUNS;
|
||||
long elapsedTime = 0;
|
||||
double foo;
|
||||
|
||||
for (int i = 1; i <= nbRuns; i++) {
|
||||
|
||||
long startTime = System.nanoTime();
|
||||
foo = integerThroughputLoad();
|
||||
long estimatedTime = System.nanoTime() - startTime;
|
||||
if (i > 3) elapsedTime += estimatedTime / 1000;
|
||||
}
|
||||
|
||||
|
||||
if (Verbose)
|
||||
System.out.println(
|
||||
"calculated throughput load for " + INTEGER_BENCH +
|
||||
" bench is = " + (elapsedTime / (nbRuns - 3)) + " microseconds");
|
||||
}
|
||||
|
||||
// ---------- Fractional only based bench --------------------
|
||||
private static final String FRACTIONAL_BENCH = "benchFormatFractional";
|
||||
private static String benchFormatFractional(NumberFormat nf) {
|
||||
String str = "";
|
||||
double floatingN = 1.0d / (double) MAX_RANGE;
|
||||
for (int j = - MAX_RANGE; j <= MAX_RANGE; j++)
|
||||
str = nf.format(floatingN * (double) j);
|
||||
return str;
|
||||
}
|
||||
|
||||
// This reproduces the throughput load added in benchFormatFractional
|
||||
static double fractionalThroughputLoad() {
|
||||
double d = 0.0d;
|
||||
double floatingN = 1.0d / (double) MAX_RANGE;
|
||||
for (int j = - MAX_RANGE; j <= MAX_RANGE; j++) {
|
||||
d = floatingN * (double) j;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
// Runs fractionalThroughputLoad and calculate its mean load
|
||||
static void calculateFractionalThroughputLoad() {
|
||||
int nbRuns = NB_RUNS;
|
||||
long elapsedTime = 0;
|
||||
double foo;
|
||||
|
||||
for (int i = 1; i <= nbRuns; i++) {
|
||||
|
||||
long startTime = System.nanoTime();
|
||||
foo = fractionalThroughputLoad();
|
||||
long estimatedTime = System.nanoTime() - startTime;
|
||||
if (i > 3) elapsedTime += estimatedTime / 1000;
|
||||
}
|
||||
|
||||
if (Verbose)
|
||||
System.out.println(
|
||||
"calculated throughput load for " + FRACTIONAL_BENCH +
|
||||
" bench is = " + (elapsedTime / (nbRuns - 3)) + " microseconds");
|
||||
}
|
||||
|
||||
// ---------- An Small Integral bench --------------------
|
||||
// that limits the magnitude of tested double values
|
||||
private static final String SMALL_INTEGRAL_BENCH = "benchFormatSmallIntegral";
|
||||
private static String benchFormatSmallIntegral(NumberFormat nf) {
|
||||
String str = "";
|
||||
for (int j = - MAX_RANGE; j <= MAX_RANGE; j++)
|
||||
str = nf.format(((double) j) / 1000.0d);
|
||||
return str;
|
||||
}
|
||||
|
||||
// This reproduces the throughput load added in benchFormatSmallIntegral
|
||||
static double smallIntegralThroughputLoad() {
|
||||
double d = 0.0d;
|
||||
for (int j = - MAX_RANGE; j <= MAX_RANGE; j++) {
|
||||
d = (double) j / 1000.0d;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
// Runs small_integralThroughputLoad and calculate its mean load
|
||||
static void calculateSmallIntegralThroughputLoad() {
|
||||
int nbRuns = NB_RUNS;
|
||||
long elapsedTime = 0;
|
||||
double foo;
|
||||
|
||||
for (int i = 1; i <= nbRuns; i++) {
|
||||
|
||||
long startTime = System.nanoTime();
|
||||
foo = smallIntegralThroughputLoad();
|
||||
long estimatedTime = System.nanoTime() - startTime;
|
||||
if (i > 3) elapsedTime += estimatedTime / 1000;
|
||||
}
|
||||
|
||||
if (Verbose)
|
||||
System.out.println(
|
||||
"calculated throughput load for " + SMALL_INTEGRAL_BENCH +
|
||||
" bench is = " + (elapsedTime / (nbRuns - 3)) + " microseconds");
|
||||
}
|
||||
|
||||
// ---------- A fair and simple bench --------------------
|
||||
private static final String FAIR_SIMPLE_BENCH = "benchFormatFairSimple";
|
||||
private static String benchFormatFairSimple(NumberFormat nf, boolean isCurrency) {
|
||||
String str = "";
|
||||
double seed = isCurrency ? 0.0010203040506070809 : 0.00010203040506070809;
|
||||
double d = (double) -MAX_RANGE;
|
||||
for (int j = - MAX_RANGE; j <= MAX_RANGE; j++) {
|
||||
d = d + 1.0d + seed;
|
||||
str = nf.format(d);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
// This reproduces the throughput load added in benchFormatFairSimple
|
||||
static double fairSimpleThroughputLoad() {
|
||||
double seed = 0.00010203040506070809;
|
||||
double delta = 0.0d;
|
||||
double d = (double) -MAX_RANGE;
|
||||
for (int j = - MAX_RANGE; j <= MAX_RANGE; j++) {
|
||||
d = d + 1.0d + seed;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
// Runs fairThroughputLoad and calculate its mean load
|
||||
static void calculateFairSimpleThroughputLoad() {
|
||||
int nbRuns = NB_RUNS;
|
||||
long elapsedTime = 0;
|
||||
double foo;
|
||||
|
||||
for (int i = 1; i <= nbRuns; i++) {
|
||||
|
||||
long startTime = System.nanoTime();
|
||||
foo = fairSimpleThroughputLoad();
|
||||
long estimatedTime = System.nanoTime() - startTime;
|
||||
if (i > 3) elapsedTime += estimatedTime / 1000;
|
||||
}
|
||||
|
||||
if (Verbose)
|
||||
System.out.println(
|
||||
"calculated throughput load for " + FAIR_SIMPLE_BENCH +
|
||||
" bench is = " + (elapsedTime / (nbRuns - 3)) + " microseconds");
|
||||
}
|
||||
|
||||
// ---------- Fractional part is only made of nines bench --------------
|
||||
private static final String FRACTIONAL_ALL_NINES_BENCH = "benchFormatFractionalAllNines";
|
||||
private static String benchFormatFractionalAllNines(NumberFormat nf, boolean isCurrency) {
|
||||
String str = "";
|
||||
double fractionalEven = isCurrency ? 0.993000001 : 0.99930000001;
|
||||
double fractionalOdd = isCurrency ? 0.996000001 : 0.99960000001;
|
||||
double fractional;
|
||||
double d;
|
||||
for (int j = - MAX_RANGE; j <= MAX_RANGE; j++) {
|
||||
if ((j & 1) == 0)
|
||||
fractional = fractionalEven;
|
||||
else
|
||||
fractional = fractionalOdd;
|
||||
if ( j >= 0)
|
||||
d = (double ) j + fractional;
|
||||
else d = (double) j - fractional;
|
||||
str = nf.format(d);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
// This reproduces the throughput load added in benchFormatFractionalAllNines
|
||||
static double fractionalAllNinesThroughputLoad() {
|
||||
double fractionalEven = 0.99930000001;
|
||||
double fractionalOdd = 0.99960000001;
|
||||
double fractional;
|
||||
double d = 0.0d;
|
||||
for (int j = - MAX_RANGE; j <= MAX_RANGE; j++) {
|
||||
if ((j & 1) == 0)
|
||||
fractional = fractionalEven;
|
||||
else fractional = fractionalOdd;
|
||||
if ( j >= 0)
|
||||
d = (double ) j + fractional;
|
||||
else d = (double) j - fractional;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
// Runs fractionalAllNinesThroughputLoad and calculate its mean load
|
||||
static void calculateFractionalAllNinesThroughputLoad() {
|
||||
int nbRuns = NB_RUNS;
|
||||
long elapsedTime = 0;
|
||||
double foo;
|
||||
|
||||
for (int i = 1; i <= nbRuns; i++) {
|
||||
|
||||
long startTime = System.nanoTime();
|
||||
foo = fractionalAllNinesThroughputLoad();
|
||||
long estimatedTime = System.nanoTime() - startTime;
|
||||
if (i > 3) elapsedTime += estimatedTime / 1000;
|
||||
}
|
||||
|
||||
if (Verbose)
|
||||
System.out.println(
|
||||
"calculated throughput load for " + FRACTIONAL_ALL_NINES_BENCH +
|
||||
" bench is = " + (elapsedTime / (nbRuns - 3)) + " microseconds");
|
||||
}
|
||||
|
||||
// ---------- Number is only made of nines bench --------------
|
||||
private static final String ALL_NINES_BENCH = "benchFormatAllNines";
|
||||
private static String benchFormatAllNines(NumberFormat nf, boolean isCurrency) {
|
||||
String str = "";
|
||||
double[] decimaAllNines =
|
||||
{9.9993, 99.9993, 999.9993, 9999.9993, 99999.9993,
|
||||
999999.9993, 9999999.9993, 99999999.9993, 999999999.9993};
|
||||
double[] currencyAllNines =
|
||||
{9.993, 99.993, 999.993, 9999.993, 99999.993,
|
||||
999999.993, 9999999.993, 99999999.993, 999999999.993};
|
||||
double[] valuesArray = (isCurrency) ? currencyAllNines : decimaAllNines;
|
||||
double seed = 1.0 / (double) MAX_RANGE;
|
||||
double d;
|
||||
int id;
|
||||
for (int j = - MAX_RANGE; j <= MAX_RANGE; j++) {
|
||||
id = (j >= 0) ? j % 9 : -j % 9;
|
||||
if ((j & 1) == 0)
|
||||
d = valuesArray[id] + id * seed;
|
||||
else
|
||||
d = valuesArray[id] - id * seed;
|
||||
str = nf.format(d);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
// This reproduces the throughput load added in benchFormatAllNines
|
||||
static double allNinesThroughputLoad() {
|
||||
double[] decimaAllNines =
|
||||
{9.9993, 99.9993, 999.9993, 9999.9993, 99999.9993,
|
||||
999999.9993, 9999999.9993, 99999999.9993, 999999999.9993};
|
||||
double[] valuesArray = decimaAllNines;
|
||||
double seed = 1.0 / (double) MAX_RANGE;
|
||||
double d = 0.0d;
|
||||
int id;
|
||||
for (int j = - MAX_RANGE; j <= MAX_RANGE; j++) {
|
||||
id = (j >= 0) ? j % 9 : -j % 9;
|
||||
if ((j & 1) == 0)
|
||||
d = valuesArray[id] + id * seed;
|
||||
else
|
||||
d = valuesArray[id] - id * seed;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
// Runs allNinesThroughputLoad and calculate its mean load
|
||||
static void calculateAllNinesThroughputLoad() {
|
||||
int nbRuns = NB_RUNS;
|
||||
long elapsedTime = 0;
|
||||
double foo;
|
||||
|
||||
for (int i = 1; i <= nbRuns; i++) {
|
||||
|
||||
long startTime = System.nanoTime();
|
||||
foo = allNinesThroughputLoad();
|
||||
long estimatedTime = System.nanoTime() - startTime;
|
||||
if (i > 3) elapsedTime += estimatedTime / 1000;
|
||||
}
|
||||
|
||||
if (Verbose)
|
||||
System.out.println(
|
||||
"calculated throughput load for " + ALL_NINES_BENCH +
|
||||
" bench is = " + (elapsedTime / (nbRuns - 3)) + " microseconds");
|
||||
}
|
||||
|
||||
|
||||
|
||||
// --- A fair bench trying (hopefully) to reproduce business applicatons ---
|
||||
|
||||
/* benchFormatFair uses the following formula :
|
||||
* y = F(x) = sign(x) * x**2 * ((1000/MAX_RANGE)**2).
|
||||
*
|
||||
* which converts in the loop as (if j is the loop index) :
|
||||
* x = double(j)
|
||||
* k = 1000.0d * double(MAX_RANGE)
|
||||
* y = sign(j) * x**2 * k**2
|
||||
*
|
||||
* This is a flattened parabolic curve where only the j values
|
||||
* in [-1000, 1000] will provide y results in [-1, +1] interval,
|
||||
* and for abs(j) >= 1000 the result y will be greater than 1.
|
||||
*
|
||||
* The difference with benchFormatSmallIntegral is that since y results
|
||||
* follow a parabolic curve the magnitude of y grows much more rapidly
|
||||
* and closer to j values when abs(j) >= 1000:
|
||||
* - for |j| < 1000, SmallIntegral(j) < 1.0 and fair(j) < 1.0
|
||||
* - for j in [1000, 10000[
|
||||
* SmallIntegral(j) is in [1, 10[
|
||||
* Fair(j) is in [4, 400[
|
||||
* - for j in [10000,100000[
|
||||
* SmallIntegral(j) is in [10, 100[
|
||||
* Fair(j) is in [400,40000[
|
||||
* - for j in [100000,1000000[
|
||||
* SmallIntegral(j) is in [100, 1000[
|
||||
* Fair(j) is in [40000, 4000000[
|
||||
*
|
||||
* Since double values for j less than 100000 provide only 4 digits in the
|
||||
* integral, values greater than 250000 provide at least 6 digits, and 500000
|
||||
* computes to 1000000, the distribution is roughly half with less than 5
|
||||
* digits and half with at least 6 digits in the integral part.
|
||||
*
|
||||
* Compared to FairSimple bench, this represents an application where 20% of
|
||||
* the double values to format are less than 40000.0 absolute value.
|
||||
*
|
||||
* Fair(j) is close to the magnitude of j when j > 100000 and is hopefully
|
||||
* more representative of what may be found in general in business apps.
|
||||
* (assumption : there will be mainly either small or large values, and
|
||||
* less values in middle range).
|
||||
*
|
||||
* We could get even more precise distribution of values using formula :
|
||||
* y = sign(x) * abs(x)**n * ((1000 / MAX_RANGE)**n) where n > 2,
|
||||
* or even well-known statistics function to fine target such distribution,
|
||||
* but we have considred that the throughput load for calculating y would
|
||||
* then be too high. We thus restrain the use of a power of 2 formula.
|
||||
*/
|
||||
|
||||
private static final String FAIR_BENCH = "benchFormatFair";
|
||||
private static String benchFormatFair(NumberFormat nf) {
|
||||
String str = "";
|
||||
double k = 1000.0d / (double) MAX_RANGE;
|
||||
k *= k;
|
||||
|
||||
double d;
|
||||
double absj;
|
||||
double jPowerOf2;
|
||||
for (int j = - MAX_RANGE; j <= MAX_RANGE; j++) {
|
||||
absj = (double) j;
|
||||
jPowerOf2 = absj * absj;
|
||||
d = k * jPowerOf2;
|
||||
if (j < 0) d = -d;
|
||||
str = nf.format(d);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
// This is the exact throughput load added in benchFormatFair
|
||||
static double fairThroughputLoad() {
|
||||
double k = 1000.0d / (double) MAX_RANGE;
|
||||
k *= k;
|
||||
|
||||
double d = 0.0d;
|
||||
double absj;
|
||||
double jPowerOf2;
|
||||
for (int j = - MAX_RANGE; j <= MAX_RANGE; j++) {
|
||||
absj = (double) j;
|
||||
jPowerOf2 = absj * absj;
|
||||
d = k * jPowerOf2;
|
||||
if (j < 0) d = -d;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
// Runs fairThroughputLoad and calculate its mean load
|
||||
static void calculateFairThroughputLoad() {
|
||||
int nbRuns = NB_RUNS;
|
||||
long elapsedTime = 0;
|
||||
double foo;
|
||||
|
||||
for (int i = 1; i <= nbRuns; i++) {
|
||||
|
||||
long startTime = System.nanoTime();
|
||||
foo = fairThroughputLoad();
|
||||
long estimatedTime = System.nanoTime() - startTime;
|
||||
if (i > 3) elapsedTime += estimatedTime / 1000;
|
||||
}
|
||||
|
||||
if (Verbose)
|
||||
System.out.println(
|
||||
"calculated throughput load for " + FAIR_BENCH +
|
||||
" bench is = " + (elapsedTime / (nbRuns - 3)) + " microseconds");
|
||||
}
|
||||
|
||||
// ---------- All double values are very close to a tie --------------------
|
||||
// i.e. like 123.1235 (for decimal case) or 123.125 (for currency case).
|
||||
|
||||
private static final String TIE_BENCH = "benchFormatTie";
|
||||
private static String benchFormatTie(NumberFormat nf, boolean isCurrency) {
|
||||
double d;
|
||||
String str = "";
|
||||
double fractionaScaling = (isCurrency) ? 1000.0d : 10000.0d;
|
||||
int fixedFractionalPart = (isCurrency) ? 125 : 1235;
|
||||
for (int j = - MAX_RANGE; j <= MAX_RANGE; j++) {
|
||||
d = (((double) j * fractionaScaling) +
|
||||
(double) fixedFractionalPart) / fractionaScaling;
|
||||
str = nf.format(d);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
// This is the exact throughput load added in benchFormatTie
|
||||
static double tieThroughputLoad(boolean isCurrency) {
|
||||
double d = 0.0d;
|
||||
double fractionaScaling = (isCurrency) ? 1000.0d : 10000.0d;
|
||||
int fixedFractionalPart = (isCurrency) ? 125 : 1235;
|
||||
for (int j = - MAX_RANGE; j <= MAX_RANGE; j++) {
|
||||
d = (((double) j * fractionaScaling) +
|
||||
(double) fixedFractionalPart) / fractionaScaling;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
// Runs tieThroughputLoad and calculate its mean load
|
||||
static void calculateTieThroughputLoad(boolean isCurrency) {
|
||||
int nbRuns = NB_RUNS;
|
||||
long elapsedTime = 0;
|
||||
double foo;
|
||||
|
||||
for (int i = 1; i <= nbRuns; i++) {
|
||||
|
||||
long startTime = System.nanoTime();
|
||||
foo = tieThroughputLoad(isCurrency);
|
||||
long estimatedTime = System.nanoTime() - startTime;
|
||||
if (i > 3) elapsedTime += estimatedTime / 1000;
|
||||
}
|
||||
|
||||
if (Verbose)
|
||||
System.out.println(
|
||||
"calculated throughput load for " + TIE_BENCH +
|
||||
" bench is = " + (elapsedTime / (nbRuns - 3)) + " microseconds");
|
||||
}
|
||||
|
||||
|
||||
// Print statistics for passed times results of benchName.
|
||||
static void printPerfResults(long[] times, String benchName) {
|
||||
int nbBenches = times.length;
|
||||
|
||||
long totalTimeSpent = 0;
|
||||
long meanTimeSpent;
|
||||
|
||||
double variance = 0;
|
||||
double standardDeviation = 0;
|
||||
|
||||
// Calculates mean spent time
|
||||
for (int i = 1; i <= nbBenches; i++)
|
||||
totalTimeSpent += times[i-1];
|
||||
meanTimeSpent = totalTimeSpent / nbBenches;
|
||||
|
||||
// Calculates standard deviation
|
||||
for (int j = 1; j <= nbBenches; j++)
|
||||
variance += Math.pow(((double)times[j-1] - (double)meanTimeSpent), 2);
|
||||
variance = variance / (double) times.length;
|
||||
standardDeviation = Math.sqrt(variance) / meanTimeSpent;
|
||||
|
||||
// Print result and statistics for benchName
|
||||
System.out.println(
|
||||
"Statistics (starting at 4th bench) for bench " + benchName +
|
||||
"\n for last " + nbBenches +
|
||||
" runs out of " + NB_RUNS +
|
||||
" , each with 2x" + MAX_RANGE + " format(double) calls : " +
|
||||
"\n mean exec time = " + meanTimeSpent + " microseconds" +
|
||||
"\n standard deviation = " + String.format("%.3f", standardDeviation) + "% \n");
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
if (args.length >= 1) {
|
||||
// Parse args, just checks expected ones. Ignore others or dups.
|
||||
if (args[0].equals("-help")) {
|
||||
usage();
|
||||
return;
|
||||
}
|
||||
|
||||
for (String s : args) {
|
||||
if (s.equals("-doit"))
|
||||
DoIt = true;
|
||||
else if (s.equals("-verbose"))
|
||||
Verbose = true;
|
||||
}
|
||||
} else {
|
||||
// No arguments, skips the benchmarks and exits.
|
||||
System.out.println(
|
||||
"Test skipped with success by default. See -help for details.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!DoIt) {
|
||||
if (Verbose)
|
||||
usage();
|
||||
System.out.println(
|
||||
"Test skipped and considered successful.");
|
||||
return;
|
||||
}
|
||||
|
||||
System.out.println("Single Threaded micro benchmark evaluating " +
|
||||
"the throughput of java.text.DecimalFormat.format() call stack.\n");
|
||||
|
||||
String fooString = "";
|
||||
|
||||
// Run benches for decimal instance
|
||||
DecimalFormat df = (DecimalFormat) NumberFormat.getInstance(Locale.US);
|
||||
System.out.println("Running with a decimal instance of DecimalFormat.");
|
||||
|
||||
calculateIntegerThroughputLoad();
|
||||
fooString =
|
||||
BenchType.INTEGER_BENCH.runBenchAndPrintStatistics(NB_RUNS, df, false);
|
||||
|
||||
calculateFractionalThroughputLoad();
|
||||
fooString =
|
||||
BenchType.FRACTIONAL_BENCH.runBenchAndPrintStatistics(NB_RUNS, df, false);
|
||||
|
||||
calculateSmallIntegralThroughputLoad();
|
||||
fooString =
|
||||
BenchType.SMALL_INTEGRAL_BENCH.runBenchAndPrintStatistics(NB_RUNS, df, false);
|
||||
|
||||
calculateFractionalAllNinesThroughputLoad();
|
||||
fooString =
|
||||
BenchType.FRACTIONAL_ALL_NINES_BENCH.runBenchAndPrintStatistics(NB_RUNS, df, false);
|
||||
|
||||
calculateAllNinesThroughputLoad();
|
||||
fooString =
|
||||
BenchType.ALL_NINES_BENCH.runBenchAndPrintStatistics(NB_RUNS, df, false);
|
||||
|
||||
calculateFairSimpleThroughputLoad();
|
||||
fooString =
|
||||
BenchType.FAIR_SIMPLE_BENCH.runBenchAndPrintStatistics(NB_RUNS, df, false);
|
||||
|
||||
calculateFairThroughputLoad();
|
||||
fooString =
|
||||
BenchType.FAIR_BENCH.runBenchAndPrintStatistics(NB_RUNS, df, false);
|
||||
|
||||
calculateTieThroughputLoad(false);
|
||||
fooString =
|
||||
BenchType.TIE_BENCH.runBenchAndPrintStatistics(NB_RUNS, df, false);
|
||||
|
||||
// Run benches for currency instance
|
||||
DecimalFormat cf = (DecimalFormat) NumberFormat.getCurrencyInstance(Locale.US);
|
||||
System.out.println("Running with a currency instance of DecimalFormat.");
|
||||
|
||||
calculateIntegerThroughputLoad();
|
||||
fooString =
|
||||
BenchType.INTEGER_BENCH.runBenchAndPrintStatistics(NB_RUNS, cf, false);
|
||||
|
||||
calculateFractionalThroughputLoad();
|
||||
fooString =
|
||||
BenchType.FRACTIONAL_BENCH.runBenchAndPrintStatistics(NB_RUNS, cf, false);
|
||||
|
||||
calculateSmallIntegralThroughputLoad();
|
||||
fooString =
|
||||
BenchType.SMALL_INTEGRAL_BENCH.runBenchAndPrintStatistics(NB_RUNS, cf, false);
|
||||
|
||||
calculateFractionalAllNinesThroughputLoad();
|
||||
fooString =
|
||||
BenchType.FRACTIONAL_ALL_NINES_BENCH.runBenchAndPrintStatistics(NB_RUNS, cf, false);
|
||||
|
||||
calculateAllNinesThroughputLoad();
|
||||
fooString =
|
||||
BenchType.ALL_NINES_BENCH.runBenchAndPrintStatistics(NB_RUNS, cf, false);
|
||||
|
||||
calculateFairSimpleThroughputLoad();
|
||||
fooString =
|
||||
BenchType.FAIR_SIMPLE_BENCH.runBenchAndPrintStatistics(NB_RUNS, cf, false);
|
||||
|
||||
calculateFairThroughputLoad();
|
||||
fooString =
|
||||
BenchType.FAIR_BENCH.runBenchAndPrintStatistics(NB_RUNS, cf, false);
|
||||
|
||||
calculateTieThroughputLoad(false);
|
||||
fooString =
|
||||
BenchType.TIE_BENCH.runBenchAndPrintStatistics(NB_RUNS, cf, false);
|
||||
|
||||
}
|
||||
|
||||
// This class to factorise what would be duplicated otherwise.
|
||||
static enum BenchType {
|
||||
|
||||
INTEGER_BENCH("benchFormatInteger"),
|
||||
FRACTIONAL_BENCH("benchFormatFractional"),
|
||||
SMALL_INTEGRAL_BENCH("benchFormatSmallIntegral"),
|
||||
FAIR_SIMPLE_BENCH("benchFormatFairSimple"),
|
||||
FRACTIONAL_ALL_NINES_BENCH("benchFormatFractionalAllNines"),
|
||||
ALL_NINES_BENCH("benchFormatAllNines"),
|
||||
FAIR_BENCH("benchFormatFair"),
|
||||
TIE_BENCH("benchFormatTie");
|
||||
|
||||
private final String name;
|
||||
|
||||
BenchType(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
String runBenchAndPrintStatistics(int nbRuns,
|
||||
NumberFormat nf,
|
||||
boolean isCurrency) {
|
||||
|
||||
// We eliminate the first 3 runs in the time measurements
|
||||
// to let C2 do complete compilation and optimization work.
|
||||
long[] elapsedTimes = new long[nbRuns - 3];
|
||||
|
||||
System.out.println("Now running " + nbRuns + " times bench " + name);
|
||||
|
||||
String str = "";
|
||||
for (int i = 1; i <= nbRuns; i++) {
|
||||
|
||||
stabilizeMemory(false);
|
||||
long startTime = System.nanoTime();
|
||||
|
||||
switch(this) {
|
||||
case INTEGER_BENCH :
|
||||
str = benchFormatInteger(nf);
|
||||
break;
|
||||
case FRACTIONAL_BENCH :
|
||||
str = benchFormatFractional(nf);
|
||||
break;
|
||||
case SMALL_INTEGRAL_BENCH :
|
||||
str = benchFormatSmallIntegral(nf);
|
||||
break;
|
||||
case FRACTIONAL_ALL_NINES_BENCH :
|
||||
str = benchFormatFractionalAllNines(nf, isCurrency);
|
||||
break;
|
||||
case ALL_NINES_BENCH :
|
||||
str = benchFormatAllNines(nf, isCurrency);
|
||||
break;
|
||||
case FAIR_SIMPLE_BENCH :
|
||||
str = benchFormatFairSimple(nf, isCurrency);
|
||||
break;
|
||||
case FAIR_BENCH :
|
||||
str = benchFormatFair(nf);
|
||||
break;
|
||||
case TIE_BENCH :
|
||||
str = benchFormatTie(nf, isCurrency);
|
||||
break;
|
||||
|
||||
default:
|
||||
}
|
||||
|
||||
|
||||
long estimatedTime = System.nanoTime() - startTime;
|
||||
if (i > 3)
|
||||
elapsedTimes[i-4] = estimatedTime / 1000;
|
||||
|
||||
if (Verbose)
|
||||
System.out.println(
|
||||
"calculated time for " + name +
|
||||
" bench " + i + " is = " +
|
||||
(estimatedTime / 1000) + " microseconds");
|
||||
else System.out.print(".");
|
||||
|
||||
stabilizeMemory(true);
|
||||
}
|
||||
|
||||
System.out.println(name + " Done.");
|
||||
|
||||
printPerfResults(elapsedTimes, name);
|
||||
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
965
test/jdk/java/text/Format/DecimalFormat/GoldenDoubleValues.java
Normal file
965
test/jdk/java/text/Format/DecimalFormat/GoldenDoubleValues.java
Normal file
|
|
@ -0,0 +1,965 @@
|
|||
/*
|
||||
* Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* Set of constants and values used in RoundingAndPropertyTest.java.
|
||||
*
|
||||
* There are 5 different information in this class:
|
||||
* - TestLocale is the locale used by RoundingAndPropertyTest regression test
|
||||
* when calling DecimalFormat.format() on either the set of DecimalGoldenValues
|
||||
* or CurrencyGoldenValues.
|
||||
* See main method of RoundingAndPropertyTest.
|
||||
*
|
||||
* - FullLocalizationTestLocale is the locale used by RoundingAndPropertyTest
|
||||
* regression test when calling DecimalFormat.format() on the set of values
|
||||
* (DecimalLocalizationValues) used to test that localization of digits
|
||||
* happens correctly when needed.
|
||||
* See main method of RoundingAndPropertyTest.
|
||||
*
|
||||
* - DecimalLocalizationValues is an array containing all the double values used
|
||||
* to check that localization of digits happens correctly when needed.
|
||||
* See RoundingAndPropertyTest.testLocalizationValues() method.
|
||||
*
|
||||
* - DecimalGoldenValues and CurrencyGoldenValues are arrays containing all the
|
||||
* double values that will be used as input when checking correctness of
|
||||
* results returned by DecimalFormat.format().
|
||||
* 2 arrays are needed since decimal and currency formatting patterns require
|
||||
* a different number of digits after decimal point.
|
||||
* See RoundingAndPropertyTest.testGoldenValues() method.
|
||||
*
|
||||
* - PROPERTY_CHECK_POSITIVE_VALUE and PROPERTY_CHECK_NEGATIVE_VALUE are the
|
||||
* double values used for testing the validity of the property changes call
|
||||
* in the fast-path case. The locale used in that case is TestLocale.
|
||||
* See RoundingAndPropertyTest.testSettersAndFastPath() method.
|
||||
*/
|
||||
|
||||
import java.util.*;
|
||||
|
||||
class GoldenDoubleValues {
|
||||
|
||||
// TestLocale is the testing locale used by RoundingAndPropertyTest test,
|
||||
// when testing the golden double values
|
||||
static final Locale TestLocale = Locale.US;
|
||||
|
||||
|
||||
// FullTestLocale is the testing locale used by RoundingAndPropertyTest test,
|
||||
// when testing full localization of double values.
|
||||
static final Locale FullLocalizationTestLocale = Locale.of("hi", "IN");
|
||||
|
||||
|
||||
/* Below are the two double values used for exercising the changes of
|
||||
* of DecimalFormat properties and symbols. These values are also used
|
||||
* as golden values (see golden arrays below).
|
||||
*/
|
||||
|
||||
/* PROPERTY_CHECK_NEGATIVE_VALUE is the negative double value used for
|
||||
* testing the validity of the property changes for fast-path.
|
||||
* See testSettersAndFastPath() in RoundingAndPropertyTest test.
|
||||
*/
|
||||
static final double PROPERTY_CHECK_NEGATIVE_VALUE = -2147483646.2334997d;
|
||||
|
||||
/* PROPERTY_CHECK_POSITIVE_VALUE is the positive double value used for
|
||||
* testing the validity of the property changes for fast-path.
|
||||
* See testSettersAndFastPath() in RoundingAndPropertyTest test.
|
||||
*/
|
||||
static final double PROPERTY_CHECK_POSITIVE_VALUE = 2147483646.2335003d;
|
||||
|
||||
/* --- Array of double values to test localization ------------------------
|
||||
*
|
||||
* For most locales, effective localization does not happen on digits, i.e.
|
||||
* the digits are not changed due to localization. In order to check that
|
||||
* fast-path localize correctly digits in such a case, the array of double
|
||||
* values below deals with all the case of localization that may happen on
|
||||
* digits
|
||||
*/
|
||||
static final double[] DecimalLocalizationValues = {
|
||||
1.123,
|
||||
12.123,
|
||||
123.123,
|
||||
1234.123,
|
||||
12345.123,
|
||||
123456.123,
|
||||
1234567.123,
|
||||
12345678.123,
|
||||
123456789.123,
|
||||
1234567890.123,
|
||||
1234.0,
|
||||
1234.9,
|
||||
1234.99,
|
||||
1234.999
|
||||
};
|
||||
|
||||
|
||||
/* --- Arrays of golden double values ----------------------------------
|
||||
*
|
||||
* The GoldenValues arrays are used as input values for checking the
|
||||
* correctness of the DecimalFormat.format() call results done in
|
||||
* RoundingAndPropertyTest regression test. The results are compared to the
|
||||
* expected ones found in GoldenFormattedValues. For each value in the
|
||||
* arrays there is a corresponding expected string result found,
|
||||
* represented as an array of unicode values, at the same index in the
|
||||
* related GoldenFormattedValues array. The string returned by the format
|
||||
* call and the found in GoldenFormattedValues array must be equal for the
|
||||
* result to be considered valid.
|
||||
* See RoundingAndPropertyTest.testGoldenValues() method.
|
||||
*
|
||||
* We need 2 such GoldenValues arrays since the decimal and currency
|
||||
* formatting rules require different number of digits after decimal point.
|
||||
*
|
||||
* Thus we have two different arrays of golden values:
|
||||
* - DecimalGoldenValues for the decimal case.
|
||||
* - CurrencyGoldenValues for the currency case.
|
||||
*
|
||||
* They are associated to related GoldenFormattedValues arrays, generated by
|
||||
* running RoundingAndPropertyTest with a "gengold" argument:
|
||||
* - DecimalGoldenFormattedValues for the decimal case.
|
||||
* - CurrencyGoldenFormattedValues for the currency case.
|
||||
* These two generated arrays are found in GoldenFormattedValues.java file.
|
||||
*
|
||||
* The impact of the formatting rules is as follows, because the pattern
|
||||
* rule for the fractional part is different for decimal and currency
|
||||
* patterns:
|
||||
* - in decimal case one must output the first non-zero 3 digits of
|
||||
* fractional part 1.1232 => "1.123" and 1.12016789 => "1.12"
|
||||
* - in currency case the first 2 fractional digits are always output
|
||||
* 1.1232 => "1.12" and 1.0016789 => "1.00"
|
||||
*
|
||||
* Thus we need a different number of fractional digits when we specify
|
||||
* below the golden double values to check, and most of the decimal and
|
||||
* currency golden values differ only in the number of fractional digits.
|
||||
*
|
||||
* The list below exercises almost all code pathes of the fast-path
|
||||
* algorithm except localization of digits.
|
||||
*/
|
||||
|
||||
// --- The set of golden values for the Decimal formatting case --------
|
||||
static final double[] DecimalGoldenValues = {
|
||||
// Testing of specific values
|
||||
+0.0,
|
||||
-0.0,
|
||||
Double.MIN_VALUE,
|
||||
Double.MIN_NORMAL,
|
||||
PROPERTY_CHECK_NEGATIVE_VALUE,
|
||||
PROPERTY_CHECK_POSITIVE_VALUE,
|
||||
-2147483647.9996,
|
||||
2147483647.9996,
|
||||
-1999999999.9994997,
|
||||
1999999999.9995003,
|
||||
// Testing fast-path range checks (all outside bounds)
|
||||
Double.NaN,
|
||||
Double.POSITIVE_INFINITY,
|
||||
Double.NEGATIVE_INFINITY,
|
||||
Double.MAX_VALUE,
|
||||
-9876543210.9876543,
|
||||
9876543210.9876543,
|
||||
-1234567890.1234567E128,
|
||||
1234567890.1234567E128,
|
||||
// Testing of integral string size
|
||||
1.123,
|
||||
12.123,
|
||||
123.123,
|
||||
1234.123,
|
||||
12345.123,
|
||||
123456.123,
|
||||
1234567.123,
|
||||
12345678.123,
|
||||
123456789.123,
|
||||
1234567890.123,
|
||||
-1.123,
|
||||
-12.123,
|
||||
-123.123,
|
||||
-1234.123,
|
||||
-12345.123,
|
||||
-123456.123,
|
||||
-1234567.123,
|
||||
-12345678.123,
|
||||
-123456789.123,
|
||||
-1234567890.123,
|
||||
// Testing of fractional string size
|
||||
0.1,
|
||||
0.12,
|
||||
0.123,
|
||||
0.1234,
|
||||
10.1,
|
||||
10.12,
|
||||
10.123,
|
||||
10.1234,
|
||||
100.1,
|
||||
100.12,
|
||||
100.123,
|
||||
100.1234,
|
||||
1000.1,
|
||||
1000.12,
|
||||
1000.123,
|
||||
1000.1234,
|
||||
10000.1,
|
||||
10000.12,
|
||||
10000.123,
|
||||
10000.1234,
|
||||
100000.1,
|
||||
100000.12,
|
||||
100000.123,
|
||||
100000.1234,
|
||||
1000000.1,
|
||||
1000000.12,
|
||||
1000000.123,
|
||||
1000000.1234,
|
||||
10000000.1,
|
||||
10000000.12,
|
||||
10000000.123,
|
||||
10000000.1234,
|
||||
100000000.1,
|
||||
100000000.12,
|
||||
100000000.123,
|
||||
100000000.1234,
|
||||
1000000000.1,
|
||||
1000000000.12,
|
||||
1000000000.123,
|
||||
1000000000.1234,
|
||||
-0.1,
|
||||
-0.12,
|
||||
-0.123,
|
||||
-0.1234,
|
||||
-10.1,
|
||||
-10.12,
|
||||
-10.123,
|
||||
-10.1234,
|
||||
-100.1,
|
||||
-100.12,
|
||||
-100.123,
|
||||
-100.1234,
|
||||
-1000.1,
|
||||
-1000.12,
|
||||
-1000.123,
|
||||
-1000.1234,
|
||||
-10000.1,
|
||||
-10000.12,
|
||||
-10000.123,
|
||||
-10000.1234,
|
||||
-100000.1,
|
||||
-100000.12,
|
||||
-100000.123,
|
||||
-100000.1234,
|
||||
-1000000.1,
|
||||
-1000000.12,
|
||||
-1000000.123,
|
||||
-1000000.1234,
|
||||
-10000000.1,
|
||||
-10000000.12,
|
||||
-10000000.123,
|
||||
-10000000.1234,
|
||||
-100000000.1,
|
||||
-100000000.12,
|
||||
-100000000.123,
|
||||
-100000000.1234,
|
||||
-1000000000.1,
|
||||
-1000000000.12,
|
||||
-1000000000.123,
|
||||
-1000000000.1234,
|
||||
// Testing of special rounding cases
|
||||
1.9993,
|
||||
12.9993,
|
||||
123.9993,
|
||||
1234.9993,
|
||||
12345.9993,
|
||||
123456.9993,
|
||||
1234567.9993,
|
||||
12345678.9993,
|
||||
123456789.9993,
|
||||
1234567890.9993,
|
||||
1.9996,
|
||||
12.9996,
|
||||
123.9996,
|
||||
1234.9996,
|
||||
12345.9996,
|
||||
123456.9996,
|
||||
1234567.9996,
|
||||
12345678.9996,
|
||||
123456789.9996,
|
||||
1234567890.9996,
|
||||
-1.9993,
|
||||
-12.9993,
|
||||
-123.9993,
|
||||
-1234.9993,
|
||||
-12345.9993,
|
||||
-123456.9993,
|
||||
-1234567.9993,
|
||||
-12345678.9993,
|
||||
-123456789.9993,
|
||||
-1234567890.9993,
|
||||
-1.9996,
|
||||
-12.9996,
|
||||
-123.9996,
|
||||
-1234.9996,
|
||||
-12345.9996,
|
||||
-123456.9996,
|
||||
-1234567.9996,
|
||||
-12345678.9996,
|
||||
-123456789.9996,
|
||||
-1234567890.9996,
|
||||
109.9996,
|
||||
1099.9996,
|
||||
10999.9996,
|
||||
109999.9996,
|
||||
1099999.9996,
|
||||
10999999.9996,
|
||||
109999999.9996,
|
||||
1099999999.9996,
|
||||
-109.9996,
|
||||
-1099.9996,
|
||||
-10999.9996,
|
||||
-109999.9996,
|
||||
-1099999.9996,
|
||||
-10999999.9996,
|
||||
-109999999.9996,
|
||||
-1099999999.9996,
|
||||
1.9996,
|
||||
19.9996,
|
||||
199.9996,
|
||||
1999.9996,
|
||||
19999.9996,
|
||||
199999.9996,
|
||||
1999999.9996,
|
||||
19999999.9996,
|
||||
199999999.9996,
|
||||
1999999999.9996,
|
||||
-1.9996,
|
||||
-19.9996,
|
||||
-199.9996,
|
||||
-1999.9996,
|
||||
-19999.9996,
|
||||
-199999.9996,
|
||||
-1999999.9996,
|
||||
-19999999.9996,
|
||||
-199999999.9996,
|
||||
-1999999999.9996,
|
||||
// Testing for all nines cases
|
||||
9.9996,
|
||||
99.9996,
|
||||
999.9996,
|
||||
9999.9996,
|
||||
99999.9996,
|
||||
999999.9996,
|
||||
9999999.9996,
|
||||
99999999.9996,
|
||||
999999999.9996,
|
||||
9.999,
|
||||
99.999,
|
||||
999.999,
|
||||
9999.999,
|
||||
99999.999,
|
||||
999999.999,
|
||||
9999999.999,
|
||||
99999999.999,
|
||||
999999999.999,
|
||||
-9.9996,
|
||||
-99.9996,
|
||||
-999.9996,
|
||||
-9999.9996,
|
||||
-99999.9996,
|
||||
-999999.9996,
|
||||
-9999999.9996,
|
||||
-99999999.9996,
|
||||
-999999999.9996,
|
||||
-9.999,
|
||||
-99.999,
|
||||
-999.999,
|
||||
-9999.999,
|
||||
-99999.999,
|
||||
-999999.999,
|
||||
-9999999.999,
|
||||
-99999999.999,
|
||||
-999999999.999,
|
||||
// Testing for no Fractional part cases
|
||||
1.0,
|
||||
12.0,
|
||||
123.0,
|
||||
1234.0,
|
||||
12345.0,
|
||||
123456.0,
|
||||
1234567.0,
|
||||
12345678.0,
|
||||
123456789.0,
|
||||
1234567890.0,
|
||||
-1.0,
|
||||
-12.0,
|
||||
-123.0,
|
||||
-1234.0,
|
||||
-12345.0,
|
||||
-123456.0,
|
||||
-1234567.0,
|
||||
-12345678.0,
|
||||
-123456789.0,
|
||||
-1234567890.0,
|
||||
// Testing of tricky cases
|
||||
-2599.399999990123,
|
||||
-2599.339999990123,
|
||||
-2599.333999990123,
|
||||
1.000099999999818,
|
||||
1.000199999999818,
|
||||
1.000299999999818,
|
||||
1.000399999999818,
|
||||
1.000499999999818,
|
||||
1.000599999999818,
|
||||
1.000699999999818,
|
||||
1.000799999999818,
|
||||
1.000899999999818,
|
||||
1.000999999999818,
|
||||
1.2224999999999980,
|
||||
1.2224999999999981,
|
||||
1.2224999999999982,
|
||||
1.2224999999999983,
|
||||
1.2224999999999984,
|
||||
1.2224999999999985,
|
||||
1.2224999999999986,
|
||||
1.2224999999999987,
|
||||
1.2224999999999988,
|
||||
1.2224999999999989,
|
||||
1.2224999999999990,
|
||||
1.2224999999999991,
|
||||
1.2224999999999992,
|
||||
1.2224999999999993,
|
||||
1.2224999999999994,
|
||||
1.2224999999999995,
|
||||
1.2224999999999996,
|
||||
1.2224999999999997,
|
||||
1.2224999999999998,
|
||||
// 1.2225 and 1.2224999999999999 have the same double approximation
|
||||
1.2225,
|
||||
1.2225000000000001,
|
||||
1.2225000000000002,
|
||||
1.2225000000000003,
|
||||
1.2225000000000004,
|
||||
1.2225000000000005,
|
||||
1.2225000000000006,
|
||||
1.2225000000000007,
|
||||
1.2225000000000008,
|
||||
1.2225000000000009,
|
||||
1.2225000000000010,
|
||||
1.2225000000000011,
|
||||
1.2225000000000012,
|
||||
1.2225000000000013,
|
||||
1.2225000000000014,
|
||||
1.2225000000000015,
|
||||
1.2225000000000016,
|
||||
1.2225000000000017,
|
||||
1.2225000000000018,
|
||||
1.2225000000000019,
|
||||
// Tricky rounding cases around tie values
|
||||
100913.67050000005,
|
||||
199999.99895901306,
|
||||
251846.3465,
|
||||
253243.8825000001,
|
||||
365045.85349999997,
|
||||
314734.9615,
|
||||
541133.9755,
|
||||
858372.1225,
|
||||
1000999.9995000001,
|
||||
1347505.7825,
|
||||
3358844.1975,
|
||||
9997979.4085,
|
||||
9993743.1585,
|
||||
9938671.9085,
|
||||
3385302.5465,
|
||||
3404642.6605,
|
||||
3431280.0865,
|
||||
3438756.4754999997,
|
||||
3446053.7874999996,
|
||||
3457917.5125,
|
||||
3465393.9014999997,
|
||||
3484734.0154999997,
|
||||
3492031.3274999997,
|
||||
3503895.0525,
|
||||
3511371.4414999997,
|
||||
3518668.7534999996,
|
||||
3530532.4785,
|
||||
3538008.8674999997,
|
||||
3545306.1794999996,
|
||||
3557169.9045,
|
||||
3557348.9814999998,
|
||||
3564646.2934999997,
|
||||
3583986.4074999997,
|
||||
3591283.7194999997,
|
||||
3603147.4445,
|
||||
3610623.8334999997,
|
||||
3617921.1454999996,
|
||||
3629784.8705,
|
||||
3637261.2594999997,
|
||||
3656422.2965,
|
||||
3656601.3734999998,
|
||||
3663898.6854999997,
|
||||
3675762.4105,
|
||||
3683238.7994999997,
|
||||
3690536.1114999996,
|
||||
3702399.8365,
|
||||
3709876.2254999997,
|
||||
3717173.5374999996,
|
||||
3729037.2625,
|
||||
3736513.6514999997,
|
||||
3755853.7654999997,
|
||||
3763151.0774999997,
|
||||
3775014.8025,
|
||||
3782491.1914999997,
|
||||
3789788.5034999996,
|
||||
3801652.2285,
|
||||
3809128.6174999997,
|
||||
3816425.9294999996,
|
||||
3828289.6545,
|
||||
3828468.7314999998,
|
||||
3835766.0434999997,
|
||||
3855106.1574999997,
|
||||
3862403.4694999997,
|
||||
3874267.1945,
|
||||
3881743.5834999997,
|
||||
3889040.8954999996,
|
||||
3900904.6205,
|
||||
3908381.0094999997,
|
||||
3927542.0465,
|
||||
3927721.1234999998,
|
||||
3935018.4354999997,
|
||||
3946882.1605,
|
||||
3954358.5494999997,
|
||||
3961655.8614999996,
|
||||
3973519.5865,
|
||||
3980995.9754999997,
|
||||
3988293.2874999996,
|
||||
4000157.0125,
|
||||
4007633.4014999997,
|
||||
4026973.5154999997,
|
||||
4034270.8274999997,
|
||||
4046134.5525,
|
||||
4053610.9414999997,
|
||||
4060908.2534999996,
|
||||
4072771.9785,
|
||||
4080248.3674999997,
|
||||
4087545.6794999996,
|
||||
4099409.4045,
|
||||
4099588.4814999998,
|
||||
4106885.7934999997,
|
||||
4126225.9074999997,
|
||||
4133523.2194999997,
|
||||
4145386.9445,
|
||||
4152863.3334999997,
|
||||
4160160.6454999996,
|
||||
4172024.3705,
|
||||
4179500.7594999997,
|
||||
4198661.7965,
|
||||
4203407.2865,
|
||||
4210704.5985,
|
||||
4213435.4975
|
||||
};
|
||||
|
||||
// --- The set of golden values for the currency formatting case --------
|
||||
static final double[] CurrencyGoldenValues = {
|
||||
// Testing of specific values
|
||||
+0.0,
|
||||
-0.0,
|
||||
Double.MIN_VALUE,
|
||||
Double.MIN_NORMAL,
|
||||
PROPERTY_CHECK_NEGATIVE_VALUE,
|
||||
PROPERTY_CHECK_POSITIVE_VALUE,
|
||||
-2147483647.996,
|
||||
2147483647.996,
|
||||
-1999999999.9949997,
|
||||
1999999999.9950003,
|
||||
// Testing fast-path range checks (all outside bounds)
|
||||
Double.NaN,
|
||||
Double.POSITIVE_INFINITY,
|
||||
Double.NEGATIVE_INFINITY,
|
||||
Double.MAX_VALUE,
|
||||
-9876543210.9876543,
|
||||
9876543210.9876543,
|
||||
-1234567890.1234567E128,
|
||||
1234567890.1234567E128,
|
||||
// Testing of integral string size
|
||||
1.12,
|
||||
12.12,
|
||||
123.12,
|
||||
1234.12,
|
||||
12345.12,
|
||||
123456.12,
|
||||
1234567.12,
|
||||
12345678.12,
|
||||
123456789.12,
|
||||
1234567890.12,
|
||||
-1.12,
|
||||
-12.12,
|
||||
-123.12,
|
||||
-1234.12,
|
||||
-12345.12,
|
||||
-123456.12,
|
||||
-1234567.12,
|
||||
-12345678.12,
|
||||
-123456789.12,
|
||||
-1234567890.12,
|
||||
// Testing of fractional string size
|
||||
0.1,
|
||||
0.12,
|
||||
0.123,
|
||||
10.1,
|
||||
10.12,
|
||||
10.123,
|
||||
100.1,
|
||||
100.12,
|
||||
100.123,
|
||||
1000.1,
|
||||
1000.12,
|
||||
1000.123,
|
||||
10000.1,
|
||||
10000.12,
|
||||
10000.123,
|
||||
100000.1,
|
||||
100000.12,
|
||||
100000.123,
|
||||
1000000.1,
|
||||
1000000.12,
|
||||
1000000.123,
|
||||
10000000.1,
|
||||
10000000.12,
|
||||
10000000.123,
|
||||
100000000.1,
|
||||
100000000.12,
|
||||
100000000.123,
|
||||
1000000000.1,
|
||||
1000000000.12,
|
||||
1000000000.123,
|
||||
-0.1,
|
||||
-0.12,
|
||||
-0.123,
|
||||
-10.1,
|
||||
-10.12,
|
||||
-10.123,
|
||||
-100.1,
|
||||
-100.12,
|
||||
-100.123,
|
||||
-1000.1,
|
||||
-1000.12,
|
||||
-1000.123,
|
||||
-10000.1,
|
||||
-10000.12,
|
||||
-10000.123,
|
||||
-100000.1,
|
||||
-100000.12,
|
||||
-100000.123,
|
||||
-1000000.1,
|
||||
-1000000.12,
|
||||
-1000000.123,
|
||||
-10000000.1,
|
||||
-10000000.12,
|
||||
-10000000.123,
|
||||
-100000000.1,
|
||||
-100000000.12,
|
||||
-100000000.123,
|
||||
-1000000000.1,
|
||||
-1000000000.12,
|
||||
-1000000000.123,
|
||||
// Testing of special rounding cases
|
||||
1.993,
|
||||
12.993,
|
||||
123.993,
|
||||
1234.993,
|
||||
12345.993,
|
||||
123456.993,
|
||||
1234567.993,
|
||||
12345678.993,
|
||||
123456789.993,
|
||||
1234567890.993,
|
||||
1.996,
|
||||
12.996,
|
||||
123.996,
|
||||
1234.996,
|
||||
12345.996,
|
||||
123456.996,
|
||||
1234567.996,
|
||||
12345678.996,
|
||||
123456789.996,
|
||||
1234567890.996,
|
||||
-1.993,
|
||||
-12.993,
|
||||
-123.993,
|
||||
-1234.993,
|
||||
-12345.993,
|
||||
-123456.993,
|
||||
-1234567.993,
|
||||
-12345678.993,
|
||||
-123456789.993,
|
||||
-1234567890.993,
|
||||
-1.996,
|
||||
-12.996,
|
||||
-123.996,
|
||||
-1234.996,
|
||||
-12345.996,
|
||||
-123456.996,
|
||||
-1234567.996,
|
||||
-12345678.996,
|
||||
-123456789.996,
|
||||
-1234567890.996,
|
||||
109.996,
|
||||
1099.996,
|
||||
10999.996,
|
||||
109999.996,
|
||||
1099999.996,
|
||||
10999999.996,
|
||||
109999999.996,
|
||||
1099999999.996,
|
||||
-109.996,
|
||||
-1099.996,
|
||||
-10999.996,
|
||||
-109999.996,
|
||||
-1099999.996,
|
||||
-10999999.996,
|
||||
-109999999.996,
|
||||
-1099999999.996,
|
||||
1.996,
|
||||
19.996,
|
||||
199.996,
|
||||
1999.996,
|
||||
19999.996,
|
||||
199999.996,
|
||||
1999999.996,
|
||||
19999999.996,
|
||||
199999999.996,
|
||||
1999999999.996,
|
||||
-1.996,
|
||||
-19.996,
|
||||
-199.996,
|
||||
-1999.996,
|
||||
-19999.996,
|
||||
-199999.996,
|
||||
-1999999.996,
|
||||
-19999999.996,
|
||||
-199999999.996,
|
||||
-1999999999.996,
|
||||
// Testing of all nines cases
|
||||
9.996,
|
||||
99.996,
|
||||
999.996,
|
||||
9999.996,
|
||||
99999.996,
|
||||
999999.996,
|
||||
9999999.996,
|
||||
99999999.996,
|
||||
999999999.996,
|
||||
9.99,
|
||||
99.99,
|
||||
999.99,
|
||||
9999.99,
|
||||
99999.99,
|
||||
999999.99,
|
||||
9999999.99,
|
||||
99999999.99,
|
||||
999999999.99,
|
||||
-9.996,
|
||||
-99.996,
|
||||
-999.996,
|
||||
-9999.996,
|
||||
-99999.996,
|
||||
-999999.996,
|
||||
-9999999.996,
|
||||
-99999999.996,
|
||||
-999999999.996,
|
||||
-9.99,
|
||||
-99.99,
|
||||
-999.99,
|
||||
-9999.99,
|
||||
-99999.99,
|
||||
-999999.99,
|
||||
-9999999.99,
|
||||
-99999999.99,
|
||||
-999999999.99,
|
||||
// Testing of no Fractional part cases
|
||||
1.0,
|
||||
12.0,
|
||||
123.0,
|
||||
1234.0,
|
||||
12345.0,
|
||||
123456.0,
|
||||
1234567.0,
|
||||
12345678.0,
|
||||
123456789.0,
|
||||
1234567890.0,
|
||||
-1.0,
|
||||
-12.0,
|
||||
-123.0,
|
||||
-1234.0,
|
||||
-12345.0,
|
||||
-123456.0,
|
||||
-1234567.0,
|
||||
-12345678.0,
|
||||
-123456789.0,
|
||||
-1234567890.0,
|
||||
// Testing of tricky cases
|
||||
-2599.399999990123,
|
||||
-2599.339999990123,
|
||||
-2599.333999990123,
|
||||
1.000999999999818,
|
||||
1.001999999999818,
|
||||
1.002999999999818,
|
||||
1.003999999999818,
|
||||
1.004999999999818,
|
||||
1.005999999999818,
|
||||
1.006999999999818,
|
||||
1.007999999999818,
|
||||
1.008999999999818,
|
||||
1.009999999999818,
|
||||
1.224999999999980,
|
||||
1.224999999999981,
|
||||
1.224999999999982,
|
||||
1.224999999999983,
|
||||
1.224999999999984,
|
||||
1.224999999999985,
|
||||
1.224999999999986,
|
||||
1.224999999999987,
|
||||
1.224999999999988,
|
||||
1.224999999999989,
|
||||
1.224999999999990,
|
||||
1.224999999999991,
|
||||
1.224999999999992,
|
||||
1.224999999999993,
|
||||
1.224999999999994,
|
||||
1.224999999999995,
|
||||
1.224999999999996,
|
||||
1.224999999999997,
|
||||
1.224999999999998,
|
||||
1.224999999999999,
|
||||
1.225,
|
||||
1.225000000000001,
|
||||
1.225000000000002,
|
||||
1.225000000000003,
|
||||
1.225000000000004,
|
||||
1.225000000000005,
|
||||
1.225000000000006,
|
||||
1.225000000000007,
|
||||
1.225000000000008,
|
||||
1.225000000000009,
|
||||
1.225000000000010,
|
||||
1.225000000000011,
|
||||
1.225000000000012,
|
||||
1.225000000000013,
|
||||
1.225000000000014,
|
||||
1.225000000000015,
|
||||
1.225000000000016,
|
||||
1.225000000000017,
|
||||
1.225000000000018,
|
||||
1.225000000000019,
|
||||
// Tricky rounding cases around tie values
|
||||
1009136.7050000005,
|
||||
2518463.465,
|
||||
2532438.825000001,
|
||||
3650458.5349999997,
|
||||
3147349.615,
|
||||
5411339.755,
|
||||
8583721.225,
|
||||
13475057.825,
|
||||
33588441.975,
|
||||
99979794.085,
|
||||
99937431.585,
|
||||
99386719.085,
|
||||
33853025.465,
|
||||
34046426.605,
|
||||
34312800.865,
|
||||
34387564.754999997,
|
||||
34460537.874999996,
|
||||
34579175.125,
|
||||
34653939.014999997,
|
||||
34847340.154999997,
|
||||
34920313.274999997,
|
||||
35038950.525,
|
||||
35113714.414999997,
|
||||
35186687.534999996,
|
||||
35305324.785,
|
||||
35380088.674999997,
|
||||
35453061.794999996,
|
||||
35571699.045,
|
||||
35573489.814999998,
|
||||
35646462.934999997,
|
||||
35839864.074999997,
|
||||
35912837.194999997,
|
||||
36031474.445,
|
||||
36106238.334999997,
|
||||
36179211.454999996,
|
||||
36297848.705,
|
||||
36372612.594999997,
|
||||
36564222.965,
|
||||
36566013.734999998,
|
||||
36638986.854999997,
|
||||
36757624.105,
|
||||
36832387.994999997,
|
||||
36905361.114999996,
|
||||
37023998.365,
|
||||
37098762.254999997,
|
||||
37171735.374999996,
|
||||
37290372.625,
|
||||
37365136.514999997,
|
||||
37558537.654999997,
|
||||
37631510.774999997,
|
||||
37750148.025,
|
||||
37824911.914999997,
|
||||
37897885.034999996,
|
||||
38016522.285,
|
||||
38091286.174999997,
|
||||
38164259.294999996,
|
||||
38282896.545,
|
||||
38284687.314999998,
|
||||
38357660.434999997,
|
||||
38551061.574999997,
|
||||
38624034.694999997,
|
||||
38742671.945,
|
||||
38817435.834999997,
|
||||
38890408.954999996,
|
||||
39009046.205,
|
||||
39083810.094999997,
|
||||
39275420.465,
|
||||
39277211.234999998,
|
||||
39350184.354999997,
|
||||
39468821.605,
|
||||
39543585.494999997,
|
||||
39616558.614999996,
|
||||
39735195.865,
|
||||
39809959.754999997,
|
||||
39882932.874999996,
|
||||
40001570.125,
|
||||
40076334.014999997,
|
||||
40269735.154999997,
|
||||
40342708.274999997,
|
||||
40461345.525,
|
||||
40536109.414999997,
|
||||
40609082.534999996,
|
||||
40727719.785,
|
||||
40802483.674999997,
|
||||
40875456.794999996,
|
||||
40994094.045,
|
||||
40995884.814999998,
|
||||
41068857.934999997,
|
||||
41262259.074999997,
|
||||
41335232.194999997,
|
||||
41453869.445,
|
||||
41528633.334999997,
|
||||
41601606.454999996,
|
||||
41720243.705,
|
||||
41795007.594999997,
|
||||
41986617.965,
|
||||
42034072.865,
|
||||
42107045.985,
|
||||
42134354.975
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,868 @@
|
|||
/*
|
||||
* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* This is a machine generated file - Please DO NOT EDIT !
|
||||
* Change RoundingAndPropertyTest instead,
|
||||
* and run with "-gengold" argument to regenerate (without copyright header).
|
||||
*/
|
||||
|
||||
/* This file contains the set of result Strings expected from calling inside
|
||||
* RoundingAndPropertyTest the method NumberFormat.format() upon the set of
|
||||
* double values provided in GoldenDoubleValues.java. It contains three arrays,
|
||||
* each containing arrays of unicode values representing the expected string
|
||||
* result when calling format() on the corresponding (i.e. same index) double
|
||||
* value found in GoldenDoubleValues arrays :
|
||||
* - DecimalDigitsLocalizedFormattedValues corresponds to DecimalLocalizationValues,
|
||||
* when using FullLocalizationTestLocale to format.
|
||||
* - DecimalGoldenFormattedValues corresponds to DecimalGoldenValues, when used
|
||||
* in the decimal pattern case together with TestLocale.
|
||||
* - CurrencyGoldenFormattedValues corresponds to CurrencyGoldenValues. when used
|
||||
* in the currency pattern case together with TestLocale.
|
||||
* Please see documentation in RoundingAndPropertyTest.java for more details.
|
||||
*
|
||||
* This file generated by running RoundingAndPropertyTest with "-gengold" argument.
|
||||
*/
|
||||
|
||||
class GoldenFormattedValues {
|
||||
|
||||
// The formatted values below were generated from golden values
|
||||
// listed in GoldenDoubleValues.java, using the following jvm version :
|
||||
// Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 1.9.0-internal-fastdebug
|
||||
// locale for golden double values : en_US
|
||||
// locale for testing digit localization : hi_IN
|
||||
|
||||
// The array of int[] unicode values storing the expected results
|
||||
// when experiencing full localization of digits on DecimalLocalizationValues.
|
||||
static int[][] DecimalDigitsLocalizedFormattedValues = {
|
||||
{ 49, 46, 49, 50, 51 },
|
||||
{ 49, 50, 46, 49, 50, 51 },
|
||||
{ 49, 50, 51, 46, 49, 50, 51 },
|
||||
{ 49, 44, 50, 51, 52, 46, 49, 50, 51 },
|
||||
{ 49, 50, 44, 51, 52, 53, 46, 49, 50, 51 },
|
||||
{ 49, 50, 51, 44, 52, 53, 54, 46, 49, 50, 51 },
|
||||
{ 49, 44, 50, 51, 52, 44, 53, 54, 55, 46, 49, 50, 51 },
|
||||
{ 49, 50, 44, 51, 52, 53, 44, 54, 55, 56, 46, 49, 50, 51 },
|
||||
{ 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 46, 49, 50, 51 },
|
||||
{ 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48, 46, 49, 50, 51 },
|
||||
{ 49, 44, 50, 51, 52 },
|
||||
{ 49, 44, 50, 51, 52, 46, 57 },
|
||||
{ 49, 44, 50, 51, 52, 46, 57, 57 },
|
||||
{ 49, 44, 50, 51, 52, 46, 57, 57, 57 },
|
||||
};
|
||||
|
||||
// The array of int[] unicode values storing the expected results
|
||||
// when calling Decimal.format(double) on the decimal GoldenDoubleValues.
|
||||
static int[][] DecimalGoldenFormattedValues = {
|
||||
{ 48 },
|
||||
{ 45, 48 },
|
||||
{ 48 },
|
||||
{ 48 },
|
||||
{ 45, 50, 44, 49, 52, 55, 44, 52, 56, 51, 44, 54, 52, 54, 46, 50, 51, 51 },
|
||||
{ 50, 44, 49, 52, 55, 44, 52, 56, 51, 44, 54, 52, 54, 46, 50, 51, 52 },
|
||||
{ 45, 50, 44, 49, 52, 55, 44, 52, 56, 51, 44, 54, 52, 56 },
|
||||
{ 50, 44, 49, 52, 55, 44, 52, 56, 51, 44, 54, 52, 56 },
|
||||
{ 45, 49, 44, 57, 57, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
|
||||
{ 50, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
|
||||
{ 78, 97, 78 },
|
||||
{ 8734 },
|
||||
{ 45, 8734 },
|
||||
{ 49, 55, 57, 44, 55, 54, 57, 44, 51, 49, 51, 44, 52, 56, 54, 44, 50, 51, 49, 44, 53, 55, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
|
||||
{ 45, 57, 44, 56, 55, 54, 44, 53, 52, 51, 44, 50, 49, 48, 46, 57, 56, 56 },
|
||||
{ 57, 44, 56, 55, 54, 44, 53, 52, 51, 44, 50, 49, 48, 46, 57, 56, 56 },
|
||||
{ 45, 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 44, 48, 49, 50, 44, 51, 52, 53, 44, 54, 55, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
|
||||
{ 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 44, 48, 49, 50, 44, 51, 52, 53, 44, 54, 55, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
|
||||
{ 49, 46, 49, 50, 51 },
|
||||
{ 49, 50, 46, 49, 50, 51 },
|
||||
{ 49, 50, 51, 46, 49, 50, 51 },
|
||||
{ 49, 44, 50, 51, 52, 46, 49, 50, 51 },
|
||||
{ 49, 50, 44, 51, 52, 53, 46, 49, 50, 51 },
|
||||
{ 49, 50, 51, 44, 52, 53, 54, 46, 49, 50, 51 },
|
||||
{ 49, 44, 50, 51, 52, 44, 53, 54, 55, 46, 49, 50, 51 },
|
||||
{ 49, 50, 44, 51, 52, 53, 44, 54, 55, 56, 46, 49, 50, 51 },
|
||||
{ 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 46, 49, 50, 51 },
|
||||
{ 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48, 46, 49, 50, 51 },
|
||||
{ 45, 49, 46, 49, 50, 51 },
|
||||
{ 45, 49, 50, 46, 49, 50, 51 },
|
||||
{ 45, 49, 50, 51, 46, 49, 50, 51 },
|
||||
{ 45, 49, 44, 50, 51, 52, 46, 49, 50, 51 },
|
||||
{ 45, 49, 50, 44, 51, 52, 53, 46, 49, 50, 51 },
|
||||
{ 45, 49, 50, 51, 44, 52, 53, 54, 46, 49, 50, 51 },
|
||||
{ 45, 49, 44, 50, 51, 52, 44, 53, 54, 55, 46, 49, 50, 51 },
|
||||
{ 45, 49, 50, 44, 51, 52, 53, 44, 54, 55, 56, 46, 49, 50, 51 },
|
||||
{ 45, 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 46, 49, 50, 51 },
|
||||
{ 45, 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48, 46, 49, 50, 51 },
|
||||
{ 48, 46, 49 },
|
||||
{ 48, 46, 49, 50 },
|
||||
{ 48, 46, 49, 50, 51 },
|
||||
{ 48, 46, 49, 50, 51 },
|
||||
{ 49, 48, 46, 49 },
|
||||
{ 49, 48, 46, 49, 50 },
|
||||
{ 49, 48, 46, 49, 50, 51 },
|
||||
{ 49, 48, 46, 49, 50, 51 },
|
||||
{ 49, 48, 48, 46, 49 },
|
||||
{ 49, 48, 48, 46, 49, 50 },
|
||||
{ 49, 48, 48, 46, 49, 50, 51 },
|
||||
{ 49, 48, 48, 46, 49, 50, 51 },
|
||||
{ 49, 44, 48, 48, 48, 46, 49 },
|
||||
{ 49, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 49, 44, 48, 48, 48, 46, 49, 50, 51 },
|
||||
{ 49, 44, 48, 48, 48, 46, 49, 50, 51 },
|
||||
{ 49, 48, 44, 48, 48, 48, 46, 49 },
|
||||
{ 49, 48, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 49, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
|
||||
{ 49, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
|
||||
{ 49, 48, 48, 44, 48, 48, 48, 46, 49 },
|
||||
{ 49, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 49, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
|
||||
{ 49, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
|
||||
{ 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49 },
|
||||
{ 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
|
||||
{ 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
|
||||
{ 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49 },
|
||||
{ 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
|
||||
{ 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
|
||||
{ 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49 },
|
||||
{ 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
|
||||
{ 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
|
||||
{ 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49 },
|
||||
{ 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
|
||||
{ 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
|
||||
{ 45, 48, 46, 49 },
|
||||
{ 45, 48, 46, 49, 50 },
|
||||
{ 45, 48, 46, 49, 50, 51 },
|
||||
{ 45, 48, 46, 49, 50, 51 },
|
||||
{ 45, 49, 48, 46, 49 },
|
||||
{ 45, 49, 48, 46, 49, 50 },
|
||||
{ 45, 49, 48, 46, 49, 50, 51 },
|
||||
{ 45, 49, 48, 46, 49, 50, 51 },
|
||||
{ 45, 49, 48, 48, 46, 49 },
|
||||
{ 45, 49, 48, 48, 46, 49, 50 },
|
||||
{ 45, 49, 48, 48, 46, 49, 50, 51 },
|
||||
{ 45, 49, 48, 48, 46, 49, 50, 51 },
|
||||
{ 45, 49, 44, 48, 48, 48, 46, 49 },
|
||||
{ 45, 49, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 45, 49, 44, 48, 48, 48, 46, 49, 50, 51 },
|
||||
{ 45, 49, 44, 48, 48, 48, 46, 49, 50, 51 },
|
||||
{ 45, 49, 48, 44, 48, 48, 48, 46, 49 },
|
||||
{ 45, 49, 48, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 45, 49, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
|
||||
{ 45, 49, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
|
||||
{ 45, 49, 48, 48, 44, 48, 48, 48, 46, 49 },
|
||||
{ 45, 49, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 45, 49, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
|
||||
{ 45, 49, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
|
||||
{ 45, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49 },
|
||||
{ 45, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 45, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
|
||||
{ 45, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
|
||||
{ 45, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49 },
|
||||
{ 45, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 45, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
|
||||
{ 45, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
|
||||
{ 45, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49 },
|
||||
{ 45, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 45, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
|
||||
{ 45, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
|
||||
{ 45, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49 },
|
||||
{ 45, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 45, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
|
||||
{ 45, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
|
||||
{ 49, 46, 57, 57, 57 },
|
||||
{ 49, 50, 46, 57, 57, 57 },
|
||||
{ 49, 50, 51, 46, 57, 57, 57 },
|
||||
{ 49, 44, 50, 51, 52, 46, 57, 57, 57 },
|
||||
{ 49, 50, 44, 51, 52, 53, 46, 57, 57, 57 },
|
||||
{ 49, 50, 51, 44, 52, 53, 54, 46, 57, 57, 57 },
|
||||
{ 49, 44, 50, 51, 52, 44, 53, 54, 55, 46, 57, 57, 57 },
|
||||
{ 49, 50, 44, 51, 52, 53, 44, 54, 55, 56, 46, 57, 57, 57 },
|
||||
{ 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 46, 57, 57, 57 },
|
||||
{ 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48, 46, 57, 57, 57 },
|
||||
{ 50 },
|
||||
{ 49, 51 },
|
||||
{ 49, 50, 52 },
|
||||
{ 49, 44, 50, 51, 53 },
|
||||
{ 49, 50, 44, 51, 52, 54 },
|
||||
{ 49, 50, 51, 44, 52, 53, 55 },
|
||||
{ 49, 44, 50, 51, 52, 44, 53, 54, 56 },
|
||||
{ 49, 50, 44, 51, 52, 53, 44, 54, 55, 57 },
|
||||
{ 49, 50, 51, 44, 52, 53, 54, 44, 55, 57, 48 },
|
||||
{ 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 49 },
|
||||
{ 45, 49, 46, 57, 57, 57 },
|
||||
{ 45, 49, 50, 46, 57, 57, 57 },
|
||||
{ 45, 49, 50, 51, 46, 57, 57, 57 },
|
||||
{ 45, 49, 44, 50, 51, 52, 46, 57, 57, 57 },
|
||||
{ 45, 49, 50, 44, 51, 52, 53, 46, 57, 57, 57 },
|
||||
{ 45, 49, 50, 51, 44, 52, 53, 54, 46, 57, 57, 57 },
|
||||
{ 45, 49, 44, 50, 51, 52, 44, 53, 54, 55, 46, 57, 57, 57 },
|
||||
{ 45, 49, 50, 44, 51, 52, 53, 44, 54, 55, 56, 46, 57, 57, 57 },
|
||||
{ 45, 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 46, 57, 57, 57 },
|
||||
{ 45, 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48, 46, 57, 57, 57 },
|
||||
{ 45, 50 },
|
||||
{ 45, 49, 51 },
|
||||
{ 45, 49, 50, 52 },
|
||||
{ 45, 49, 44, 50, 51, 53 },
|
||||
{ 45, 49, 50, 44, 51, 52, 54 },
|
||||
{ 45, 49, 50, 51, 44, 52, 53, 55 },
|
||||
{ 45, 49, 44, 50, 51, 52, 44, 53, 54, 56 },
|
||||
{ 45, 49, 50, 44, 51, 52, 53, 44, 54, 55, 57 },
|
||||
{ 45, 49, 50, 51, 44, 52, 53, 54, 44, 55, 57, 48 },
|
||||
{ 45, 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 49 },
|
||||
{ 49, 49, 48 },
|
||||
{ 49, 44, 49, 48, 48 },
|
||||
{ 49, 49, 44, 48, 48, 48 },
|
||||
{ 49, 49, 48, 44, 48, 48, 48 },
|
||||
{ 49, 44, 49, 48, 48, 44, 48, 48, 48 },
|
||||
{ 49, 49, 44, 48, 48, 48, 44, 48, 48, 48 },
|
||||
{ 49, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
|
||||
{ 49, 44, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
|
||||
{ 45, 49, 49, 48 },
|
||||
{ 45, 49, 44, 49, 48, 48 },
|
||||
{ 45, 49, 49, 44, 48, 48, 48 },
|
||||
{ 45, 49, 49, 48, 44, 48, 48, 48 },
|
||||
{ 45, 49, 44, 49, 48, 48, 44, 48, 48, 48 },
|
||||
{ 45, 49, 49, 44, 48, 48, 48, 44, 48, 48, 48 },
|
||||
{ 45, 49, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
|
||||
{ 45, 49, 44, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
|
||||
{ 50 },
|
||||
{ 50, 48 },
|
||||
{ 50, 48, 48 },
|
||||
{ 50, 44, 48, 48, 48 },
|
||||
{ 50, 48, 44, 48, 48, 48 },
|
||||
{ 50, 48, 48, 44, 48, 48, 48 },
|
||||
{ 50, 44, 48, 48, 48, 44, 48, 48, 48 },
|
||||
{ 50, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
|
||||
{ 50, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
|
||||
{ 50, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
|
||||
{ 45, 50 },
|
||||
{ 45, 50, 48 },
|
||||
{ 45, 50, 48, 48 },
|
||||
{ 45, 50, 44, 48, 48, 48 },
|
||||
{ 45, 50, 48, 44, 48, 48, 48 },
|
||||
{ 45, 50, 48, 48, 44, 48, 48, 48 },
|
||||
{ 45, 50, 44, 48, 48, 48, 44, 48, 48, 48 },
|
||||
{ 45, 50, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
|
||||
{ 45, 50, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
|
||||
{ 45, 50, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
|
||||
{ 49, 48 },
|
||||
{ 49, 48, 48 },
|
||||
{ 49, 44, 48, 48, 48 },
|
||||
{ 49, 48, 44, 48, 48, 48 },
|
||||
{ 49, 48, 48, 44, 48, 48, 48 },
|
||||
{ 49, 44, 48, 48, 48, 44, 48, 48, 48 },
|
||||
{ 49, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
|
||||
{ 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
|
||||
{ 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
|
||||
{ 57, 46, 57, 57, 57 },
|
||||
{ 57, 57, 46, 57, 57, 57 },
|
||||
{ 57, 57, 57, 46, 57, 57, 57 },
|
||||
{ 57, 44, 57, 57, 57, 46, 57, 57, 57 },
|
||||
{ 57, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
|
||||
{ 57, 57, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
|
||||
{ 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
|
||||
{ 57, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
|
||||
{ 57, 57, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
|
||||
{ 45, 49, 48 },
|
||||
{ 45, 49, 48, 48 },
|
||||
{ 45, 49, 44, 48, 48, 48 },
|
||||
{ 45, 49, 48, 44, 48, 48, 48 },
|
||||
{ 45, 49, 48, 48, 44, 48, 48, 48 },
|
||||
{ 45, 49, 44, 48, 48, 48, 44, 48, 48, 48 },
|
||||
{ 45, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
|
||||
{ 45, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
|
||||
{ 45, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
|
||||
{ 45, 57, 46, 57, 57, 57 },
|
||||
{ 45, 57, 57, 46, 57, 57, 57 },
|
||||
{ 45, 57, 57, 57, 46, 57, 57, 57 },
|
||||
{ 45, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
|
||||
{ 45, 57, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
|
||||
{ 45, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
|
||||
{ 45, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
|
||||
{ 45, 57, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
|
||||
{ 45, 57, 57, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
|
||||
{ 49 },
|
||||
{ 49, 50 },
|
||||
{ 49, 50, 51 },
|
||||
{ 49, 44, 50, 51, 52 },
|
||||
{ 49, 50, 44, 51, 52, 53 },
|
||||
{ 49, 50, 51, 44, 52, 53, 54 },
|
||||
{ 49, 44, 50, 51, 52, 44, 53, 54, 55 },
|
||||
{ 49, 50, 44, 51, 52, 53, 44, 54, 55, 56 },
|
||||
{ 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57 },
|
||||
{ 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48 },
|
||||
{ 45, 49 },
|
||||
{ 45, 49, 50 },
|
||||
{ 45, 49, 50, 51 },
|
||||
{ 45, 49, 44, 50, 51, 52 },
|
||||
{ 45, 49, 50, 44, 51, 52, 53 },
|
||||
{ 45, 49, 50, 51, 44, 52, 53, 54 },
|
||||
{ 45, 49, 44, 50, 51, 52, 44, 53, 54, 55 },
|
||||
{ 45, 49, 50, 44, 51, 52, 53, 44, 54, 55, 56 },
|
||||
{ 45, 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57 },
|
||||
{ 45, 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48 },
|
||||
{ 45, 50, 44, 53, 57, 57, 46, 52 },
|
||||
{ 45, 50, 44, 53, 57, 57, 46, 51, 52 },
|
||||
{ 45, 50, 44, 53, 57, 57, 46, 51, 51, 52 },
|
||||
{ 49 },
|
||||
{ 49 },
|
||||
{ 49 },
|
||||
{ 49 },
|
||||
{ 49 },
|
||||
{ 49, 46, 48, 48, 49 },
|
||||
{ 49, 46, 48, 48, 49 },
|
||||
{ 49, 46, 48, 48, 49 },
|
||||
{ 49, 46, 48, 48, 49 },
|
||||
{ 49, 46, 48, 48, 49 },
|
||||
{ 49, 46, 50, 50, 50 },
|
||||
{ 49, 46, 50, 50, 50 },
|
||||
{ 49, 46, 50, 50, 50 },
|
||||
{ 49, 46, 50, 50, 50 },
|
||||
{ 49, 46, 50, 50, 50 },
|
||||
{ 49, 46, 50, 50, 50 },
|
||||
{ 49, 46, 50, 50, 50 },
|
||||
{ 49, 46, 50, 50, 50 },
|
||||
{ 49, 46, 50, 50, 50 },
|
||||
{ 49, 46, 50, 50, 50 },
|
||||
{ 49, 46, 50, 50, 50 },
|
||||
{ 49, 46, 50, 50, 50 },
|
||||
{ 49, 46, 50, 50, 50 },
|
||||
{ 49, 46, 50, 50, 50 },
|
||||
{ 49, 46, 50, 50, 50 },
|
||||
{ 49, 46, 50, 50, 50 },
|
||||
{ 49, 46, 50, 50, 50 },
|
||||
{ 49, 46, 50, 50, 50 },
|
||||
{ 49, 46, 50, 50, 50 },
|
||||
{ 49, 46, 50, 50, 50 },
|
||||
{ 49, 46, 50, 50, 51 },
|
||||
{ 49, 46, 50, 50, 51 },
|
||||
{ 49, 46, 50, 50, 51 },
|
||||
{ 49, 46, 50, 50, 51 },
|
||||
{ 49, 46, 50, 50, 51 },
|
||||
{ 49, 46, 50, 50, 51 },
|
||||
{ 49, 46, 50, 50, 51 },
|
||||
{ 49, 46, 50, 50, 51 },
|
||||
{ 49, 46, 50, 50, 51 },
|
||||
{ 49, 46, 50, 50, 51 },
|
||||
{ 49, 46, 50, 50, 51 },
|
||||
{ 49, 46, 50, 50, 51 },
|
||||
{ 49, 46, 50, 50, 51 },
|
||||
{ 49, 46, 50, 50, 51 },
|
||||
{ 49, 46, 50, 50, 51 },
|
||||
{ 49, 46, 50, 50, 51 },
|
||||
{ 49, 46, 50, 50, 51 },
|
||||
{ 49, 46, 50, 50, 51 },
|
||||
{ 49, 46, 50, 50, 51 },
|
||||
{ 49, 48, 48, 44, 57, 49, 51, 46, 54, 55, 49 },
|
||||
{ 49, 57, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
|
||||
{ 50, 53, 49, 44, 56, 52, 54, 46, 51, 52, 55 },
|
||||
{ 50, 53, 51, 44, 50, 52, 51, 46, 56, 56, 51 },
|
||||
{ 51, 54, 53, 44, 48, 52, 53, 46, 56, 53, 51 },
|
||||
{ 51, 49, 52, 44, 55, 51, 52, 46, 57, 54, 49 },
|
||||
{ 53, 52, 49, 44, 49, 51, 51, 46, 57, 55, 53 },
|
||||
{ 56, 53, 56, 44, 51, 55, 50, 46, 49, 50, 51 },
|
||||
{ 49, 44, 48, 48, 49, 44, 48, 48, 48 },
|
||||
{ 49, 44, 51, 52, 55, 44, 53, 48, 53, 46, 55, 56, 50 },
|
||||
{ 51, 44, 51, 53, 56, 44, 56, 52, 52, 46, 49, 57, 55 },
|
||||
{ 57, 44, 57, 57, 55, 44, 57, 55, 57, 46, 52, 48, 57 },
|
||||
{ 57, 44, 57, 57, 51, 44, 55, 52, 51, 46, 49, 53, 57 },
|
||||
{ 57, 44, 57, 51, 56, 44, 54, 55, 49, 46, 57, 48, 57 },
|
||||
{ 51, 44, 51, 56, 53, 44, 51, 48, 50, 46, 53, 52, 55 },
|
||||
{ 51, 44, 52, 48, 52, 44, 54, 52, 50, 46, 54, 54, 49 },
|
||||
{ 51, 44, 52, 51, 49, 44, 50, 56, 48, 46, 48, 56, 55 },
|
||||
{ 51, 44, 52, 51, 56, 44, 55, 53, 54, 46, 52, 55, 53 },
|
||||
{ 51, 44, 52, 52, 54, 44, 48, 53, 51, 46, 55, 56, 55 },
|
||||
{ 51, 44, 52, 53, 55, 44, 57, 49, 55, 46, 53, 49, 51 },
|
||||
{ 51, 44, 52, 54, 53, 44, 51, 57, 51, 46, 57, 48, 49 },
|
||||
{ 51, 44, 52, 56, 52, 44, 55, 51, 52, 46, 48, 49, 53 },
|
||||
{ 51, 44, 52, 57, 50, 44, 48, 51, 49, 46, 51, 50, 55 },
|
||||
{ 51, 44, 53, 48, 51, 44, 56, 57, 53, 46, 48, 53, 51 },
|
||||
{ 51, 44, 53, 49, 49, 44, 51, 55, 49, 46, 52, 52, 49 },
|
||||
{ 51, 44, 53, 49, 56, 44, 54, 54, 56, 46, 55, 53, 51 },
|
||||
{ 51, 44, 53, 51, 48, 44, 53, 51, 50, 46, 52, 55, 57 },
|
||||
{ 51, 44, 53, 51, 56, 44, 48, 48, 56, 46, 56, 54, 55 },
|
||||
{ 51, 44, 53, 52, 53, 44, 51, 48, 54, 46, 49, 55, 57 },
|
||||
{ 51, 44, 53, 53, 55, 44, 49, 54, 57, 46, 57, 48, 53 },
|
||||
{ 51, 44, 53, 53, 55, 44, 51, 52, 56, 46, 57, 56, 49 },
|
||||
{ 51, 44, 53, 54, 52, 44, 54, 52, 54, 46, 50, 57, 51 },
|
||||
{ 51, 44, 53, 56, 51, 44, 57, 56, 54, 46, 52, 48, 55 },
|
||||
{ 51, 44, 53, 57, 49, 44, 50, 56, 51, 46, 55, 49, 57 },
|
||||
{ 51, 44, 54, 48, 51, 44, 49, 52, 55, 46, 52, 52, 53 },
|
||||
{ 51, 44, 54, 49, 48, 44, 54, 50, 51, 46, 56, 51, 51 },
|
||||
{ 51, 44, 54, 49, 55, 44, 57, 50, 49, 46, 49, 52, 53 },
|
||||
{ 51, 44, 54, 50, 57, 44, 55, 56, 52, 46, 56, 55, 49 },
|
||||
{ 51, 44, 54, 51, 55, 44, 50, 54, 49, 46, 50, 53, 57 },
|
||||
{ 51, 44, 54, 53, 54, 44, 52, 50, 50, 46, 50, 57, 55 },
|
||||
{ 51, 44, 54, 53, 54, 44, 54, 48, 49, 46, 51, 55, 51 },
|
||||
{ 51, 44, 54, 54, 51, 44, 56, 57, 56, 46, 54, 56, 53 },
|
||||
{ 51, 44, 54, 55, 53, 44, 55, 54, 50, 46, 52, 49, 49 },
|
||||
{ 51, 44, 54, 56, 51, 44, 50, 51, 56, 46, 55, 57, 57 },
|
||||
{ 51, 44, 54, 57, 48, 44, 53, 51, 54, 46, 49, 49, 49 },
|
||||
{ 51, 44, 55, 48, 50, 44, 51, 57, 57, 46, 56, 51, 55 },
|
||||
{ 51, 44, 55, 48, 57, 44, 56, 55, 54, 46, 50, 50, 53 },
|
||||
{ 51, 44, 55, 49, 55, 44, 49, 55, 51, 46, 53, 51, 55 },
|
||||
{ 51, 44, 55, 50, 57, 44, 48, 51, 55, 46, 50, 54, 51 },
|
||||
{ 51, 44, 55, 51, 54, 44, 53, 49, 51, 46, 54, 53, 49 },
|
||||
{ 51, 44, 55, 53, 53, 44, 56, 53, 51, 46, 55, 54, 53 },
|
||||
{ 51, 44, 55, 54, 51, 44, 49, 53, 49, 46, 48, 55, 55 },
|
||||
{ 51, 44, 55, 55, 53, 44, 48, 49, 52, 46, 56, 48, 51 },
|
||||
{ 51, 44, 55, 56, 50, 44, 52, 57, 49, 46, 49, 57, 49 },
|
||||
{ 51, 44, 55, 56, 57, 44, 55, 56, 56, 46, 53, 48, 51 },
|
||||
{ 51, 44, 56, 48, 49, 44, 54, 53, 50, 46, 50, 50, 57 },
|
||||
{ 51, 44, 56, 48, 57, 44, 49, 50, 56, 46, 54, 49, 55 },
|
||||
{ 51, 44, 56, 49, 54, 44, 52, 50, 53, 46, 57, 50, 57 },
|
||||
{ 51, 44, 56, 50, 56, 44, 50, 56, 57, 46, 54, 53, 53 },
|
||||
{ 51, 44, 56, 50, 56, 44, 52, 54, 56, 46, 55, 51, 49 },
|
||||
{ 51, 44, 56, 51, 53, 44, 55, 54, 54, 46, 48, 52, 51 },
|
||||
{ 51, 44, 56, 53, 53, 44, 49, 48, 54, 46, 49, 53, 55 },
|
||||
{ 51, 44, 56, 54, 50, 44, 52, 48, 51, 46, 52, 54, 57 },
|
||||
{ 51, 44, 56, 55, 52, 44, 50, 54, 55, 46, 49, 57, 53 },
|
||||
{ 51, 44, 56, 56, 49, 44, 55, 52, 51, 46, 53, 56, 51 },
|
||||
{ 51, 44, 56, 56, 57, 44, 48, 52, 48, 46, 56, 57, 53 },
|
||||
{ 51, 44, 57, 48, 48, 44, 57, 48, 52, 46, 54, 50, 49 },
|
||||
{ 51, 44, 57, 48, 56, 44, 51, 56, 49, 46, 48, 48, 57 },
|
||||
{ 51, 44, 57, 50, 55, 44, 53, 52, 50, 46, 48, 52, 55 },
|
||||
{ 51, 44, 57, 50, 55, 44, 55, 50, 49, 46, 49, 50, 51 },
|
||||
{ 51, 44, 57, 51, 53, 44, 48, 49, 56, 46, 52, 51, 53 },
|
||||
{ 51, 44, 57, 52, 54, 44, 56, 56, 50, 46, 49, 54, 49 },
|
||||
{ 51, 44, 57, 53, 52, 44, 51, 53, 56, 46, 53, 52, 57 },
|
||||
{ 51, 44, 57, 54, 49, 44, 54, 53, 53, 46, 56, 54, 49 },
|
||||
{ 51, 44, 57, 55, 51, 44, 53, 49, 57, 46, 53, 56, 55 },
|
||||
{ 51, 44, 57, 56, 48, 44, 57, 57, 53, 46, 57, 55, 53 },
|
||||
{ 51, 44, 57, 56, 56, 44, 50, 57, 51, 46, 50, 56, 55 },
|
||||
{ 52, 44, 48, 48, 48, 44, 49, 53, 55, 46, 48, 49, 51 },
|
||||
{ 52, 44, 48, 48, 55, 44, 54, 51, 51, 46, 52, 48, 49 },
|
||||
{ 52, 44, 48, 50, 54, 44, 57, 55, 51, 46, 53, 49, 53 },
|
||||
{ 52, 44, 48, 51, 52, 44, 50, 55, 48, 46, 56, 50, 55 },
|
||||
{ 52, 44, 48, 52, 54, 44, 49, 51, 52, 46, 53, 53, 51 },
|
||||
{ 52, 44, 48, 53, 51, 44, 54, 49, 48, 46, 57, 52, 49 },
|
||||
{ 52, 44, 48, 54, 48, 44, 57, 48, 56, 46, 50, 53, 51 },
|
||||
{ 52, 44, 48, 55, 50, 44, 55, 55, 49, 46, 57, 55, 57 },
|
||||
{ 52, 44, 48, 56, 48, 44, 50, 52, 56, 46, 51, 54, 55 },
|
||||
{ 52, 44, 48, 56, 55, 44, 53, 52, 53, 46, 54, 55, 57 },
|
||||
{ 52, 44, 48, 57, 57, 44, 52, 48, 57, 46, 52, 48, 53 },
|
||||
{ 52, 44, 48, 57, 57, 44, 53, 56, 56, 46, 52, 56, 49 },
|
||||
{ 52, 44, 49, 48, 54, 44, 56, 56, 53, 46, 55, 57, 51 },
|
||||
{ 52, 44, 49, 50, 54, 44, 50, 50, 53, 46, 57, 48, 55 },
|
||||
{ 52, 44, 49, 51, 51, 44, 53, 50, 51, 46, 50, 49, 57 },
|
||||
{ 52, 44, 49, 52, 53, 44, 51, 56, 54, 46, 57, 52, 53 },
|
||||
{ 52, 44, 49, 53, 50, 44, 56, 54, 51, 46, 51, 51, 51 },
|
||||
{ 52, 44, 49, 54, 48, 44, 49, 54, 48, 46, 54, 52, 53 },
|
||||
{ 52, 44, 49, 55, 50, 44, 48, 50, 52, 46, 51, 55, 49 },
|
||||
{ 52, 44, 49, 55, 57, 44, 53, 48, 48, 46, 55, 53, 57 },
|
||||
{ 52, 44, 49, 57, 56, 44, 54, 54, 49, 46, 55, 57, 55 },
|
||||
{ 52, 44, 50, 48, 51, 44, 52, 48, 55, 46, 50, 56, 55 },
|
||||
{ 52, 44, 50, 49, 48, 44, 55, 48, 52, 46, 53, 57, 57 },
|
||||
{ 52, 44, 50, 49, 51, 44, 52, 51, 53, 46, 52, 57, 55 },
|
||||
};
|
||||
|
||||
// The array of int[] unicode values storing the expected results
|
||||
// when calling Decimal.format(double) on the currency GoldenDoubleValues.
|
||||
static int[][] CurrencyGoldenFormattedValues = {
|
||||
{ 36, 48, 46, 48, 48 },
|
||||
{ 45, 36, 48, 46, 48, 48 },
|
||||
{ 36, 48, 46, 48, 48 },
|
||||
{ 36, 48, 46, 48, 48 },
|
||||
{ 45, 36, 50, 44, 49, 52, 55, 44, 52, 56, 51, 44, 54, 52, 54, 46, 50, 51 },
|
||||
{ 36, 50, 44, 49, 52, 55, 44, 52, 56, 51, 44, 54, 52, 54, 46, 50, 51 },
|
||||
{ 45, 36, 50, 44, 49, 52, 55, 44, 52, 56, 51, 44, 54, 52, 56, 46, 48, 48 },
|
||||
{ 36, 50, 44, 49, 52, 55, 44, 52, 56, 51, 44, 54, 52, 56, 46, 48, 48 },
|
||||
{ 45, 36, 49, 44, 57, 57, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57 },
|
||||
{ 36, 50, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 78, 97, 78 },
|
||||
{ 36, 8734 },
|
||||
{ 45, 36, 8734 },
|
||||
{ 36, 49, 55, 57, 44, 55, 54, 57, 44, 51, 49, 51, 44, 52, 56, 54, 44, 50, 51, 49, 44, 53, 55, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 45, 36, 57, 44, 56, 55, 54, 44, 53, 52, 51, 44, 50, 49, 48, 46, 57, 57 },
|
||||
{ 36, 57, 44, 56, 55, 54, 44, 53, 52, 51, 44, 50, 49, 48, 46, 57, 57 },
|
||||
{ 45, 36, 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 44, 48, 49, 50, 44, 51, 52, 53, 44, 54, 55, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 36, 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 44, 48, 49, 50, 44, 51, 52, 53, 44, 54, 55, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 36, 49, 46, 49, 50 },
|
||||
{ 36, 49, 50, 46, 49, 50 },
|
||||
{ 36, 49, 50, 51, 46, 49, 50 },
|
||||
{ 36, 49, 44, 50, 51, 52, 46, 49, 50 },
|
||||
{ 36, 49, 50, 44, 51, 52, 53, 46, 49, 50 },
|
||||
{ 36, 49, 50, 51, 44, 52, 53, 54, 46, 49, 50 },
|
||||
{ 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 46, 49, 50 },
|
||||
{ 36, 49, 50, 44, 51, 52, 53, 44, 54, 55, 56, 46, 49, 50 },
|
||||
{ 36, 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 46, 49, 50 },
|
||||
{ 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48, 46, 49, 50 },
|
||||
{ 45, 36, 49, 46, 49, 50 },
|
||||
{ 45, 36, 49, 50, 46, 49, 50 },
|
||||
{ 45, 36, 49, 50, 51, 46, 49, 50 },
|
||||
{ 45, 36, 49, 44, 50, 51, 52, 46, 49, 50 },
|
||||
{ 45, 36, 49, 50, 44, 51, 52, 53, 46, 49, 50 },
|
||||
{ 45, 36, 49, 50, 51, 44, 52, 53, 54, 46, 49, 50 },
|
||||
{ 45, 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 46, 49, 50 },
|
||||
{ 45, 36, 49, 50, 44, 51, 52, 53, 44, 54, 55, 56, 46, 49, 50 },
|
||||
{ 45, 36, 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 46, 49, 50 },
|
||||
{ 45, 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48, 46, 49, 50 },
|
||||
{ 36, 48, 46, 49, 48 },
|
||||
{ 36, 48, 46, 49, 50 },
|
||||
{ 36, 48, 46, 49, 50 },
|
||||
{ 36, 49, 48, 46, 49, 48 },
|
||||
{ 36, 49, 48, 46, 49, 50 },
|
||||
{ 36, 49, 48, 46, 49, 50 },
|
||||
{ 36, 49, 48, 48, 46, 49, 48 },
|
||||
{ 36, 49, 48, 48, 46, 49, 50 },
|
||||
{ 36, 49, 48, 48, 46, 49, 50 },
|
||||
{ 36, 49, 44, 48, 48, 48, 46, 49, 48 },
|
||||
{ 36, 49, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 36, 49, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 36, 49, 48, 44, 48, 48, 48, 46, 49, 48 },
|
||||
{ 36, 49, 48, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 36, 49, 48, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 36, 49, 48, 48, 44, 48, 48, 48, 46, 49, 48 },
|
||||
{ 36, 49, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 36, 49, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 48 },
|
||||
{ 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 36, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 48 },
|
||||
{ 36, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 36, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 36, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 48 },
|
||||
{ 36, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 36, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 48 },
|
||||
{ 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 45, 36, 48, 46, 49, 48 },
|
||||
{ 45, 36, 48, 46, 49, 50 },
|
||||
{ 45, 36, 48, 46, 49, 50 },
|
||||
{ 45, 36, 49, 48, 46, 49, 48 },
|
||||
{ 45, 36, 49, 48, 46, 49, 50 },
|
||||
{ 45, 36, 49, 48, 46, 49, 50 },
|
||||
{ 45, 36, 49, 48, 48, 46, 49, 48 },
|
||||
{ 45, 36, 49, 48, 48, 46, 49, 50 },
|
||||
{ 45, 36, 49, 48, 48, 46, 49, 50 },
|
||||
{ 45, 36, 49, 44, 48, 48, 48, 46, 49, 48 },
|
||||
{ 45, 36, 49, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 45, 36, 49, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 45, 36, 49, 48, 44, 48, 48, 48, 46, 49, 48 },
|
||||
{ 45, 36, 49, 48, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 45, 36, 49, 48, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 45, 36, 49, 48, 48, 44, 48, 48, 48, 46, 49, 48 },
|
||||
{ 45, 36, 49, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 45, 36, 49, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 45, 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 48 },
|
||||
{ 45, 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 45, 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 45, 36, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 48 },
|
||||
{ 45, 36, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 45, 36, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 45, 36, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 48 },
|
||||
{ 45, 36, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 45, 36, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 45, 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 48 },
|
||||
{ 45, 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 45, 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
|
||||
{ 36, 49, 46, 57, 57 },
|
||||
{ 36, 49, 50, 46, 57, 57 },
|
||||
{ 36, 49, 50, 51, 46, 57, 57 },
|
||||
{ 36, 49, 44, 50, 51, 52, 46, 57, 57 },
|
||||
{ 36, 49, 50, 44, 51, 52, 53, 46, 57, 57 },
|
||||
{ 36, 49, 50, 51, 44, 52, 53, 54, 46, 57, 57 },
|
||||
{ 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 46, 57, 57 },
|
||||
{ 36, 49, 50, 44, 51, 52, 53, 44, 54, 55, 56, 46, 57, 57 },
|
||||
{ 36, 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 46, 57, 57 },
|
||||
{ 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48, 46, 57, 57 },
|
||||
{ 36, 50, 46, 48, 48 },
|
||||
{ 36, 49, 51, 46, 48, 48 },
|
||||
{ 36, 49, 50, 52, 46, 48, 48 },
|
||||
{ 36, 49, 44, 50, 51, 53, 46, 48, 48 },
|
||||
{ 36, 49, 50, 44, 51, 52, 54, 46, 48, 48 },
|
||||
{ 36, 49, 50, 51, 44, 52, 53, 55, 46, 48, 48 },
|
||||
{ 36, 49, 44, 50, 51, 52, 44, 53, 54, 56, 46, 48, 48 },
|
||||
{ 36, 49, 50, 44, 51, 52, 53, 44, 54, 55, 57, 46, 48, 48 },
|
||||
{ 36, 49, 50, 51, 44, 52, 53, 54, 44, 55, 57, 48, 46, 48, 48 },
|
||||
{ 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 49, 46, 48, 48 },
|
||||
{ 45, 36, 49, 46, 57, 57 },
|
||||
{ 45, 36, 49, 50, 46, 57, 57 },
|
||||
{ 45, 36, 49, 50, 51, 46, 57, 57 },
|
||||
{ 45, 36, 49, 44, 50, 51, 52, 46, 57, 57 },
|
||||
{ 45, 36, 49, 50, 44, 51, 52, 53, 46, 57, 57 },
|
||||
{ 45, 36, 49, 50, 51, 44, 52, 53, 54, 46, 57, 57 },
|
||||
{ 45, 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 46, 57, 57 },
|
||||
{ 45, 36, 49, 50, 44, 51, 52, 53, 44, 54, 55, 56, 46, 57, 57 },
|
||||
{ 45, 36, 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 46, 57, 57 },
|
||||
{ 45, 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48, 46, 57, 57 },
|
||||
{ 45, 36, 50, 46, 48, 48 },
|
||||
{ 45, 36, 49, 51, 46, 48, 48 },
|
||||
{ 45, 36, 49, 50, 52, 46, 48, 48 },
|
||||
{ 45, 36, 49, 44, 50, 51, 53, 46, 48, 48 },
|
||||
{ 45, 36, 49, 50, 44, 51, 52, 54, 46, 48, 48 },
|
||||
{ 45, 36, 49, 50, 51, 44, 52, 53, 55, 46, 48, 48 },
|
||||
{ 45, 36, 49, 44, 50, 51, 52, 44, 53, 54, 56, 46, 48, 48 },
|
||||
{ 45, 36, 49, 50, 44, 51, 52, 53, 44, 54, 55, 57, 46, 48, 48 },
|
||||
{ 45, 36, 49, 50, 51, 44, 52, 53, 54, 44, 55, 57, 48, 46, 48, 48 },
|
||||
{ 45, 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 49, 46, 48, 48 },
|
||||
{ 36, 49, 49, 48, 46, 48, 48 },
|
||||
{ 36, 49, 44, 49, 48, 48, 46, 48, 48 },
|
||||
{ 36, 49, 49, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 36, 49, 49, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 36, 49, 44, 49, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 36, 49, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 36, 49, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 36, 49, 44, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 45, 36, 49, 49, 48, 46, 48, 48 },
|
||||
{ 45, 36, 49, 44, 49, 48, 48, 46, 48, 48 },
|
||||
{ 45, 36, 49, 49, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 45, 36, 49, 49, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 45, 36, 49, 44, 49, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 45, 36, 49, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 45, 36, 49, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 45, 36, 49, 44, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 36, 50, 46, 48, 48 },
|
||||
{ 36, 50, 48, 46, 48, 48 },
|
||||
{ 36, 50, 48, 48, 46, 48, 48 },
|
||||
{ 36, 50, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 36, 50, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 36, 50, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 36, 50, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 36, 50, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 36, 50, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 36, 50, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 45, 36, 50, 46, 48, 48 },
|
||||
{ 45, 36, 50, 48, 46, 48, 48 },
|
||||
{ 45, 36, 50, 48, 48, 46, 48, 48 },
|
||||
{ 45, 36, 50, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 45, 36, 50, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 45, 36, 50, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 45, 36, 50, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 45, 36, 50, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 45, 36, 50, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 45, 36, 50, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 36, 49, 48, 46, 48, 48 },
|
||||
{ 36, 49, 48, 48, 46, 48, 48 },
|
||||
{ 36, 49, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 36, 49, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 36, 49, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 36, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 36, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 36, 57, 46, 57, 57 },
|
||||
{ 36, 57, 57, 46, 57, 57 },
|
||||
{ 36, 57, 57, 57, 46, 57, 57 },
|
||||
{ 36, 57, 44, 57, 57, 57, 46, 57, 57 },
|
||||
{ 36, 57, 57, 44, 57, 57, 57, 46, 57, 57 },
|
||||
{ 36, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57 },
|
||||
{ 36, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57 },
|
||||
{ 36, 57, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57 },
|
||||
{ 36, 57, 57, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57 },
|
||||
{ 45, 36, 49, 48, 46, 48, 48 },
|
||||
{ 45, 36, 49, 48, 48, 46, 48, 48 },
|
||||
{ 45, 36, 49, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 45, 36, 49, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 45, 36, 49, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 45, 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 45, 36, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 45, 36, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 45, 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
|
||||
{ 45, 36, 57, 46, 57, 57 },
|
||||
{ 45, 36, 57, 57, 46, 57, 57 },
|
||||
{ 45, 36, 57, 57, 57, 46, 57, 57 },
|
||||
{ 45, 36, 57, 44, 57, 57, 57, 46, 57, 57 },
|
||||
{ 45, 36, 57, 57, 44, 57, 57, 57, 46, 57, 57 },
|
||||
{ 45, 36, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57 },
|
||||
{ 45, 36, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57 },
|
||||
{ 45, 36, 57, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57 },
|
||||
{ 45, 36, 57, 57, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57 },
|
||||
{ 36, 49, 46, 48, 48 },
|
||||
{ 36, 49, 50, 46, 48, 48 },
|
||||
{ 36, 49, 50, 51, 46, 48, 48 },
|
||||
{ 36, 49, 44, 50, 51, 52, 46, 48, 48 },
|
||||
{ 36, 49, 50, 44, 51, 52, 53, 46, 48, 48 },
|
||||
{ 36, 49, 50, 51, 44, 52, 53, 54, 46, 48, 48 },
|
||||
{ 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 46, 48, 48 },
|
||||
{ 36, 49, 50, 44, 51, 52, 53, 44, 54, 55, 56, 46, 48, 48 },
|
||||
{ 36, 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 46, 48, 48 },
|
||||
{ 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48, 46, 48, 48 },
|
||||
{ 45, 36, 49, 46, 48, 48 },
|
||||
{ 45, 36, 49, 50, 46, 48, 48 },
|
||||
{ 45, 36, 49, 50, 51, 46, 48, 48 },
|
||||
{ 45, 36, 49, 44, 50, 51, 52, 46, 48, 48 },
|
||||
{ 45, 36, 49, 50, 44, 51, 52, 53, 46, 48, 48 },
|
||||
{ 45, 36, 49, 50, 51, 44, 52, 53, 54, 46, 48, 48 },
|
||||
{ 45, 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 46, 48, 48 },
|
||||
{ 45, 36, 49, 50, 44, 51, 52, 53, 44, 54, 55, 56, 46, 48, 48 },
|
||||
{ 45, 36, 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 46, 48, 48 },
|
||||
{ 45, 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48, 46, 48, 48 },
|
||||
{ 45, 36, 50, 44, 53, 57, 57, 46, 52, 48 },
|
||||
{ 45, 36, 50, 44, 53, 57, 57, 46, 51, 52 },
|
||||
{ 45, 36, 50, 44, 53, 57, 57, 46, 51, 51 },
|
||||
{ 36, 49, 46, 48, 48 },
|
||||
{ 36, 49, 46, 48, 48 },
|
||||
{ 36, 49, 46, 48, 48 },
|
||||
{ 36, 49, 46, 48, 48 },
|
||||
{ 36, 49, 46, 48, 48 },
|
||||
{ 36, 49, 46, 48, 49 },
|
||||
{ 36, 49, 46, 48, 49 },
|
||||
{ 36, 49, 46, 48, 49 },
|
||||
{ 36, 49, 46, 48, 49 },
|
||||
{ 36, 49, 46, 48, 49 },
|
||||
{ 36, 49, 46, 50, 50 },
|
||||
{ 36, 49, 46, 50, 50 },
|
||||
{ 36, 49, 46, 50, 50 },
|
||||
{ 36, 49, 46, 50, 50 },
|
||||
{ 36, 49, 46, 50, 50 },
|
||||
{ 36, 49, 46, 50, 50 },
|
||||
{ 36, 49, 46, 50, 50 },
|
||||
{ 36, 49, 46, 50, 50 },
|
||||
{ 36, 49, 46, 50, 50 },
|
||||
{ 36, 49, 46, 50, 50 },
|
||||
{ 36, 49, 46, 50, 50 },
|
||||
{ 36, 49, 46, 50, 50 },
|
||||
{ 36, 49, 46, 50, 50 },
|
||||
{ 36, 49, 46, 50, 50 },
|
||||
{ 36, 49, 46, 50, 50 },
|
||||
{ 36, 49, 46, 50, 50 },
|
||||
{ 36, 49, 46, 50, 50 },
|
||||
{ 36, 49, 46, 50, 50 },
|
||||
{ 36, 49, 46, 50, 50 },
|
||||
{ 36, 49, 46, 50, 50 },
|
||||
{ 36, 49, 46, 50, 51 },
|
||||
{ 36, 49, 46, 50, 51 },
|
||||
{ 36, 49, 46, 50, 51 },
|
||||
{ 36, 49, 46, 50, 51 },
|
||||
{ 36, 49, 46, 50, 51 },
|
||||
{ 36, 49, 46, 50, 51 },
|
||||
{ 36, 49, 46, 50, 51 },
|
||||
{ 36, 49, 46, 50, 51 },
|
||||
{ 36, 49, 46, 50, 51 },
|
||||
{ 36, 49, 46, 50, 51 },
|
||||
{ 36, 49, 46, 50, 51 },
|
||||
{ 36, 49, 46, 50, 51 },
|
||||
{ 36, 49, 46, 50, 51 },
|
||||
{ 36, 49, 46, 50, 51 },
|
||||
{ 36, 49, 46, 50, 51 },
|
||||
{ 36, 49, 46, 50, 51 },
|
||||
{ 36, 49, 46, 50, 51 },
|
||||
{ 36, 49, 46, 50, 51 },
|
||||
{ 36, 49, 46, 50, 51 },
|
||||
{ 36, 49, 46, 50, 51 },
|
||||
{ 36, 49, 44, 48, 48, 57, 44, 49, 51, 54, 46, 55, 49 },
|
||||
{ 36, 50, 44, 53, 49, 56, 44, 52, 54, 51, 46, 52, 54 },
|
||||
{ 36, 50, 44, 53, 51, 50, 44, 52, 51, 56, 46, 56, 51 },
|
||||
{ 36, 51, 44, 54, 53, 48, 44, 52, 53, 56, 46, 53, 51 },
|
||||
{ 36, 51, 44, 49, 52, 55, 44, 51, 52, 57, 46, 54, 50 },
|
||||
{ 36, 53, 44, 52, 49, 49, 44, 51, 51, 57, 46, 55, 53 },
|
||||
{ 36, 56, 44, 53, 56, 51, 44, 55, 50, 49, 46, 50, 50 },
|
||||
{ 36, 49, 51, 44, 52, 55, 53, 44, 48, 53, 55, 46, 56, 50 },
|
||||
{ 36, 51, 51, 44, 53, 56, 56, 44, 52, 52, 49, 46, 57, 56 },
|
||||
{ 36, 57, 57, 44, 57, 55, 57, 44, 55, 57, 52, 46, 48, 56 },
|
||||
{ 36, 57, 57, 44, 57, 51, 55, 44, 52, 51, 49, 46, 53, 56 },
|
||||
{ 36, 57, 57, 44, 51, 56, 54, 44, 55, 49, 57, 46, 48, 56 },
|
||||
{ 36, 51, 51, 44, 56, 53, 51, 44, 48, 50, 53, 46, 52, 55 },
|
||||
{ 36, 51, 52, 44, 48, 52, 54, 44, 52, 50, 54, 46, 54, 48 },
|
||||
{ 36, 51, 52, 44, 51, 49, 50, 44, 56, 48, 48, 46, 56, 55 },
|
||||
{ 36, 51, 52, 44, 51, 56, 55, 44, 53, 54, 52, 46, 55, 53 },
|
||||
{ 36, 51, 52, 44, 52, 54, 48, 44, 53, 51, 55, 46, 56, 55 },
|
||||
{ 36, 51, 52, 44, 53, 55, 57, 44, 49, 55, 53, 46, 49, 50 },
|
||||
{ 36, 51, 52, 44, 54, 53, 51, 44, 57, 51, 57, 46, 48, 50 },
|
||||
{ 36, 51, 52, 44, 56, 52, 55, 44, 51, 52, 48, 46, 49, 53 },
|
||||
{ 36, 51, 52, 44, 57, 50, 48, 44, 51, 49, 51, 46, 50, 55 },
|
||||
{ 36, 51, 53, 44, 48, 51, 56, 44, 57, 53, 48, 46, 53, 50 },
|
||||
{ 36, 51, 53, 44, 49, 49, 51, 44, 55, 49, 52, 46, 52, 49 },
|
||||
{ 36, 51, 53, 44, 49, 56, 54, 44, 54, 56, 55, 46, 53, 51 },
|
||||
{ 36, 51, 53, 44, 51, 48, 53, 44, 51, 50, 52, 46, 55, 56 },
|
||||
{ 36, 51, 53, 44, 51, 56, 48, 44, 48, 56, 56, 46, 54, 55 },
|
||||
{ 36, 51, 53, 44, 52, 53, 51, 44, 48, 54, 49, 46, 55, 57 },
|
||||
{ 36, 51, 53, 44, 53, 55, 49, 44, 54, 57, 57, 46, 48, 53 },
|
||||
{ 36, 51, 53, 44, 53, 55, 51, 44, 52, 56, 57, 46, 56, 49 },
|
||||
{ 36, 51, 53, 44, 54, 52, 54, 44, 52, 54, 50, 46, 57, 51 },
|
||||
{ 36, 51, 53, 44, 56, 51, 57, 44, 56, 54, 52, 46, 48, 55 },
|
||||
{ 36, 51, 53, 44, 57, 49, 50, 44, 56, 51, 55, 46, 50, 48 },
|
||||
{ 36, 51, 54, 44, 48, 51, 49, 44, 52, 55, 52, 46, 52, 53 },
|
||||
{ 36, 51, 54, 44, 49, 48, 54, 44, 50, 51, 56, 46, 51, 51 },
|
||||
{ 36, 51, 54, 44, 49, 55, 57, 44, 50, 49, 49, 46, 52, 53 },
|
||||
{ 36, 51, 54, 44, 50, 57, 55, 44, 56, 52, 56, 46, 55, 48 },
|
||||
{ 36, 51, 54, 44, 51, 55, 50, 44, 54, 49, 50, 46, 53, 57 },
|
||||
{ 36, 51, 54, 44, 53, 54, 52, 44, 50, 50, 50, 46, 57, 55 },
|
||||
{ 36, 51, 54, 44, 53, 54, 54, 44, 48, 49, 51, 46, 55, 51 },
|
||||
{ 36, 51, 54, 44, 54, 51, 56, 44, 57, 56, 54, 46, 56, 53 },
|
||||
{ 36, 51, 54, 44, 55, 53, 55, 44, 54, 50, 52, 46, 49, 48 },
|
||||
{ 36, 51, 54, 44, 56, 51, 50, 44, 51, 56, 55, 46, 57, 57 },
|
||||
{ 36, 51, 54, 44, 57, 48, 53, 44, 51, 54, 49, 46, 49, 49 },
|
||||
{ 36, 51, 55, 44, 48, 50, 51, 44, 57, 57, 56, 46, 51, 55 },
|
||||
{ 36, 51, 55, 44, 48, 57, 56, 44, 55, 54, 50, 46, 50, 53 },
|
||||
{ 36, 51, 55, 44, 49, 55, 49, 44, 55, 51, 53, 46, 51, 55 },
|
||||
{ 36, 51, 55, 44, 50, 57, 48, 44, 51, 55, 50, 46, 54, 50 },
|
||||
{ 36, 51, 55, 44, 51, 54, 53, 44, 49, 51, 54, 46, 53, 50 },
|
||||
{ 36, 51, 55, 44, 53, 53, 56, 44, 53, 51, 55, 46, 54, 53 },
|
||||
{ 36, 51, 55, 44, 54, 51, 49, 44, 53, 49, 48, 46, 55, 55 },
|
||||
{ 36, 51, 55, 44, 55, 53, 48, 44, 49, 52, 56, 46, 48, 50 },
|
||||
{ 36, 51, 55, 44, 56, 50, 52, 44, 57, 49, 49, 46, 57, 49 },
|
||||
{ 36, 51, 55, 44, 56, 57, 55, 44, 56, 56, 53, 46, 48, 51 },
|
||||
{ 36, 51, 56, 44, 48, 49, 54, 44, 53, 50, 50, 46, 50, 56 },
|
||||
{ 36, 51, 56, 44, 48, 57, 49, 44, 50, 56, 54, 46, 49, 55 },
|
||||
{ 36, 51, 56, 44, 49, 54, 52, 44, 50, 53, 57, 46, 50, 57 },
|
||||
{ 36, 51, 56, 44, 50, 56, 50, 44, 56, 57, 54, 46, 53, 53 },
|
||||
{ 36, 51, 56, 44, 50, 56, 52, 44, 54, 56, 55, 46, 51, 49 },
|
||||
{ 36, 51, 56, 44, 51, 53, 55, 44, 54, 54, 48, 46, 52, 51 },
|
||||
{ 36, 51, 56, 44, 53, 53, 49, 44, 48, 54, 49, 46, 53, 55 },
|
||||
{ 36, 51, 56, 44, 54, 50, 52, 44, 48, 51, 52, 46, 55, 48 },
|
||||
{ 36, 51, 56, 44, 55, 52, 50, 44, 54, 55, 49, 46, 57, 53 },
|
||||
{ 36, 51, 56, 44, 56, 49, 55, 44, 52, 51, 53, 46, 56, 51 },
|
||||
{ 36, 51, 56, 44, 56, 57, 48, 44, 52, 48, 56, 46, 57, 53 },
|
||||
{ 36, 51, 57, 44, 48, 48, 57, 44, 48, 52, 54, 46, 50, 48 },
|
||||
{ 36, 51, 57, 44, 48, 56, 51, 44, 56, 49, 48, 46, 48, 57 },
|
||||
{ 36, 51, 57, 44, 50, 55, 53, 44, 52, 50, 48, 46, 52, 55 },
|
||||
{ 36, 51, 57, 44, 50, 55, 55, 44, 50, 49, 49, 46, 50, 51 },
|
||||
{ 36, 51, 57, 44, 51, 53, 48, 44, 49, 56, 52, 46, 51, 53 },
|
||||
{ 36, 51, 57, 44, 52, 54, 56, 44, 56, 50, 49, 46, 54, 48 },
|
||||
{ 36, 51, 57, 44, 53, 52, 51, 44, 53, 56, 53, 46, 52, 57 },
|
||||
{ 36, 51, 57, 44, 54, 49, 54, 44, 53, 53, 56, 46, 54, 49 },
|
||||
{ 36, 51, 57, 44, 55, 51, 53, 44, 49, 57, 53, 46, 56, 55 },
|
||||
{ 36, 51, 57, 44, 56, 48, 57, 44, 57, 53, 57, 46, 55, 53 },
|
||||
{ 36, 51, 57, 44, 56, 56, 50, 44, 57, 51, 50, 46, 56, 55 },
|
||||
{ 36, 52, 48, 44, 48, 48, 49, 44, 53, 55, 48, 46, 49, 50 },
|
||||
{ 36, 52, 48, 44, 48, 55, 54, 44, 51, 51, 52, 46, 48, 50 },
|
||||
{ 36, 52, 48, 44, 50, 54, 57, 44, 55, 51, 53, 46, 49, 53 },
|
||||
{ 36, 52, 48, 44, 51, 52, 50, 44, 55, 48, 56, 46, 50, 55 },
|
||||
{ 36, 52, 48, 44, 52, 54, 49, 44, 51, 52, 53, 46, 53, 50 },
|
||||
{ 36, 52, 48, 44, 53, 51, 54, 44, 49, 48, 57, 46, 52, 49 },
|
||||
{ 36, 52, 48, 44, 54, 48, 57, 44, 48, 56, 50, 46, 53, 51 },
|
||||
{ 36, 52, 48, 44, 55, 50, 55, 44, 55, 49, 57, 46, 55, 56 },
|
||||
{ 36, 52, 48, 44, 56, 48, 50, 44, 52, 56, 51, 46, 54, 55 },
|
||||
{ 36, 52, 48, 44, 56, 55, 53, 44, 52, 53, 54, 46, 55, 57 },
|
||||
{ 36, 52, 48, 44, 57, 57, 52, 44, 48, 57, 52, 46, 48, 53 },
|
||||
{ 36, 52, 48, 44, 57, 57, 53, 44, 56, 56, 52, 46, 56, 49 },
|
||||
{ 36, 52, 49, 44, 48, 54, 56, 44, 56, 53, 55, 46, 57, 51 },
|
||||
{ 36, 52, 49, 44, 50, 54, 50, 44, 50, 53, 57, 46, 48, 55 },
|
||||
{ 36, 52, 49, 44, 51, 51, 53, 44, 50, 51, 50, 46, 50, 48 },
|
||||
{ 36, 52, 49, 44, 52, 53, 51, 44, 56, 54, 57, 46, 52, 53 },
|
||||
{ 36, 52, 49, 44, 53, 50, 56, 44, 54, 51, 51, 46, 51, 51 },
|
||||
{ 36, 52, 49, 44, 54, 48, 49, 44, 54, 48, 54, 46, 52, 53 },
|
||||
{ 36, 52, 49, 44, 55, 50, 48, 44, 50, 52, 51, 46, 55, 48 },
|
||||
{ 36, 52, 49, 44, 55, 57, 53, 44, 48, 48, 55, 46, 53, 57 },
|
||||
{ 36, 52, 49, 44, 57, 56, 54, 44, 54, 49, 55, 46, 57, 55 },
|
||||
{ 36, 52, 50, 44, 48, 51, 52, 44, 48, 55, 50, 46, 56, 55 },
|
||||
{ 36, 52, 50, 44, 49, 48, 55, 44, 48, 52, 53, 46, 57, 56 },
|
||||
{ 36, 52, 50, 44, 49, 51, 52, 44, 51, 53, 52, 46, 57, 56 },
|
||||
};
|
||||
|
||||
}
|
||||
193
test/jdk/java/text/Format/DecimalFormat/LargeExponentsTest.java
Normal file
193
test/jdk/java/text/Format/DecimalFormat/LargeExponentsTest.java
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8331485
|
||||
* @summary Ensure correctness when parsing large (+/-) exponent values that
|
||||
* exceed Integer.MAX_VALUE and Long.MAX_VALUE.
|
||||
* @run junit/othervm --add-opens java.base/java.text=ALL-UNNAMED LargeExponentsTest
|
||||
*/
|
||||
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.ParsePosition;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
// We prevent odd results when parsing large exponent values by ensuring
|
||||
// that we properly handle overflow in the implementation of DigitList
|
||||
public class LargeExponentsTest {
|
||||
|
||||
// Exponent symbol is 'E'
|
||||
private static final NumberFormat FMT = NumberFormat.getInstance(Locale.US);
|
||||
|
||||
// Check that the parsed value and parse position index are both equal to the expected values.
|
||||
// We are mainly checking that an exponent > Integer.MAX_VALUE no longer
|
||||
// parses to 0 and that an exponent > Long.MAX_VALUE no longer parses to the mantissa.
|
||||
@ParameterizedTest
|
||||
@MethodSource({"largeExponentValues", "smallExponentValues", "bugReportValues", "edgeCases"})
|
||||
public void overflowTest(String parseString, Double expectedValue) throws ParseException {
|
||||
checkParse(parseString, expectedValue);
|
||||
checkParseWithPP(parseString, expectedValue);
|
||||
}
|
||||
|
||||
// A separate white-box test to avoid the memory consumption of testing cases
|
||||
// when the String is near Integer.MAX_LENGTH
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
public void largeDecimalAtExponentTest(int expected, int decimalAt, long expVal)
|
||||
throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
|
||||
DecimalFormat df = new DecimalFormat();
|
||||
Method m = df.getClass().getDeclaredMethod(
|
||||
"shiftDecimalAt", int.class, long.class);
|
||||
m.setAccessible(true);
|
||||
assertEquals(expected, m.invoke(df, decimalAt, expVal));
|
||||
}
|
||||
|
||||
// Cases where we can test behavior when the String is near Integer.MAX_LENGTH
|
||||
private static Stream<Arguments> largeDecimalAtExponentTest() {
|
||||
return Stream.of(
|
||||
// Equivalent to testing Arguments.of("0."+"0".repeat(Integer.MAX_VALUE-20)+"1"+"E2147483650", 1.0E22)
|
||||
// This is an absurdly long decimal string with length close to Integer.MAX_VALUE
|
||||
// where the decimal position correctly negates the exponent value, even if it exceeds Integer.MAX_VALUE
|
||||
Arguments.of(23, -(Integer.MAX_VALUE-20), 3L+Integer.MAX_VALUE),
|
||||
Arguments.of(-23, Integer.MAX_VALUE-20, -(3L+Integer.MAX_VALUE)),
|
||||
Arguments.of(Integer.MIN_VALUE, -(Integer.MAX_VALUE-20), -(3L+Integer.MAX_VALUE)),
|
||||
Arguments.of(Integer.MAX_VALUE, Integer.MAX_VALUE-20, 3L+Integer.MAX_VALUE),
|
||||
Arguments.of(Integer.MAX_VALUE, -(Integer.MAX_VALUE-20), Long.MAX_VALUE),
|
||||
Arguments.of(Integer.MIN_VALUE, Integer.MAX_VALUE-20, Long.MIN_VALUE)
|
||||
);
|
||||
}
|
||||
|
||||
// Checks the parse(String, ParsePosition) method
|
||||
public void checkParse(String parseString, Double expectedValue) {
|
||||
ParsePosition pp = new ParsePosition(0);
|
||||
Number actualValue = FMT.parse(parseString, pp);
|
||||
assertEquals(expectedValue, (double)actualValue);
|
||||
assertEquals(parseString.length(), pp.getIndex());
|
||||
}
|
||||
|
||||
// Checks the parse(String) method
|
||||
public void checkParseWithPP(String parseString, Double expectedValue)
|
||||
throws ParseException {
|
||||
Number actualValue = FMT.parse(parseString);
|
||||
assertEquals(expectedValue, (double)actualValue);
|
||||
}
|
||||
|
||||
// Generate large enough exponents that should all be parsed as infinity
|
||||
// when positive. This includes exponents that exceed Long.MAX_VALUE
|
||||
private static List<Arguments> largeExponentValues() {
|
||||
return createExponentValues(false);
|
||||
}
|
||||
|
||||
// Same as previous provider but for negative exponent values, so expecting
|
||||
// a parsed value of 0.
|
||||
private static List<Arguments> smallExponentValues() {
|
||||
return createExponentValues(true);
|
||||
}
|
||||
|
||||
// Programmatically generate some large parse values that are expected
|
||||
// to be parsed as infinity or 0
|
||||
private static List<Arguments> createExponentValues(boolean negative) {
|
||||
List<Arguments> args = new ArrayList<>();
|
||||
// Start with a base value that should be parsed as infinity
|
||||
String baseValue = "12234.123E1100";
|
||||
// Continuously add to the String until we trigger the overflow condition
|
||||
for (int i = 0; i < 100; i++) {
|
||||
StringBuilder bldr = new StringBuilder();
|
||||
// Add to exponent
|
||||
bldr.append(baseValue).append("1".repeat(i));
|
||||
// Add to mantissa
|
||||
bldr.insert(0, "1".repeat(i));
|
||||
args.add(Arguments.of(
|
||||
// Prepend "-" to exponent if negative
|
||||
negative ? bldr.insert(bldr.indexOf("E")+1, "-").toString() : bldr.toString(),
|
||||
// Expect 0 if negative, else infinity
|
||||
negative ? 0.0 : Double.POSITIVE_INFINITY));
|
||||
}
|
||||
return args;
|
||||
}
|
||||
|
||||
// The provided values are all from the JBS issue
|
||||
// These contain exponents that exceed Integer.MAX_VALUE, but not Long.MAX_VALUE
|
||||
private static Stream<Arguments> bugReportValues() {
|
||||
return Stream.of(
|
||||
Arguments.of("0.123E1", 1.23),
|
||||
Arguments.of("0.123E309", 1.23E308),
|
||||
Arguments.of("0.123E310", Double.POSITIVE_INFINITY),
|
||||
Arguments.of("0.123E2147483647", Double.POSITIVE_INFINITY),
|
||||
Arguments.of("0.123E2147483648", Double.POSITIVE_INFINITY),
|
||||
Arguments.of("0.0123E2147483648", Double.POSITIVE_INFINITY),
|
||||
Arguments.of("0.0123E2147483649", Double.POSITIVE_INFINITY),
|
||||
Arguments.of("1.23E2147483646", Double.POSITIVE_INFINITY),
|
||||
Arguments.of("1.23E2147483647", Double.POSITIVE_INFINITY),
|
||||
Arguments.of("0.123E4294967296", Double.POSITIVE_INFINITY),
|
||||
Arguments.of("0.123E-322", 9.9E-324),
|
||||
Arguments.of("0.123E-323", 0.0),
|
||||
Arguments.of("0.123E-2147483647", 0.0),
|
||||
Arguments.of("0.123E-2147483648", 0.0),
|
||||
Arguments.of("0.123E-2147483649", 0.0)
|
||||
);
|
||||
}
|
||||
|
||||
// Some other edge case values to ensure parse correctness
|
||||
private static Stream<Arguments> edgeCases() {
|
||||
return Stream.of(
|
||||
// Exponent itself does not cause underflow, but decimalAt adjustment
|
||||
// based off mantissa should. decimalAt(-1) + exponent(Integer.MIN_VALUE) = underflow
|
||||
Arguments.of("0.0123E-2147483648", 0.0),
|
||||
// 0 exponent
|
||||
Arguments.of("1.23E0", 1.23),
|
||||
// Leading zeroes
|
||||
Arguments.of("1.23E0000123", 1.23E123),
|
||||
// Leading zeroes - Past Long.MAX_VALUE length
|
||||
Arguments.of("1.23E00000000000000000000000000000000000000000123", 1.23E123),
|
||||
// Trailing zeroes
|
||||
Arguments.of("1.23E100", 1.23E100),
|
||||
// Long.MAX_VALUE length
|
||||
Arguments.of("1.23E1234567891234567800", Double.POSITIVE_INFINITY),
|
||||
// Long.MAX_VALUE with trailing zeroes
|
||||
Arguments.of("1.23E9223372036854775807000", Double.POSITIVE_INFINITY),
|
||||
// Long.MIN_VALUE
|
||||
Arguments.of("1.23E-9223372036854775808", 0.0),
|
||||
// Exponent value smaller than Long.MIN_VALUE
|
||||
Arguments.of("1.23E-9223372036854775809", 0.0),
|
||||
// Exponent value equal to Long.MAX_VALUE
|
||||
Arguments.of("1.23E9223372036854775807", Double.POSITIVE_INFINITY),
|
||||
// Exponent value larger than Long.MAX_VALUE
|
||||
Arguments.of("1.23E9223372036854775808", Double.POSITIVE_INFINITY)
|
||||
);
|
||||
}
|
||||
}
|
||||
103
test/jdk/java/text/Format/DecimalFormat/MantissaDigits.java
Normal file
103
test/jdk/java/text/Format/DecimalFormat/MantissaDigits.java
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8159023
|
||||
* @summary Confirm behavior of mantissa for scientific notation in Decimal Format
|
||||
* @run junit MantissaDigits
|
||||
*/
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
import java.util.Locale;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class MantissaDigits {
|
||||
private static final double[] NUMBERS = {
|
||||
1.1, 12.1, 123.1, 1234.1, 12345.1, 123456.1,
|
||||
-1.1, -12.1, -123.1, -1234.1, -12345.1, -123456.1,
|
||||
1, 12, 123, 1234, 12345, 123456, 1234567,
|
||||
-1, -12, -123, -1234, -12345, -123456, -1234567,
|
||||
1.1234, 1.1111, 1.412, 222.333, -771.2222
|
||||
};
|
||||
private static final DecimalFormatSymbols DFS = new DecimalFormatSymbols(Locale.US);
|
||||
private static final String ERRMSG = "%s formatted with %s gives %s, and " +
|
||||
"significant digit count was %s, but the formula provided %s%n";
|
||||
// Hard coded as 1, since all test patterns only have 1 exponent digit
|
||||
private static final int EXPONENTDIGITS = 1;
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("patterns")
|
||||
public void testMantissaDefinition(String pattern, int minDigits, int maxDigits) {
|
||||
DecimalFormat df = new DecimalFormat(pattern, DFS);
|
||||
for (double number : NUMBERS) {
|
||||
// Count the significant digits in the pre-formatted number
|
||||
int originalNumDigits = (int) String.valueOf(number).chars()
|
||||
.filter(Character::isDigit).count();
|
||||
|
||||
if (wholeNumber(number)) {
|
||||
// Trailing 0 should not be counted
|
||||
originalNumDigits--;
|
||||
}
|
||||
|
||||
// Format the number, then grab the significant
|
||||
// digits inside the mantissa
|
||||
String formattedNum = df.format(number);
|
||||
int mantissaDigits = (int) formattedNum.chars()
|
||||
.filter(Character::isDigit).count() - EXPONENTDIGITS;
|
||||
|
||||
// Test the new definition of the Mantissa
|
||||
Integer calculatedDigits = Math
|
||||
.min(Math.max(minDigits, originalNumDigits), maxDigits);
|
||||
assertEquals(mantissaDigits, calculatedDigits, String.format(ERRMSG,
|
||||
number, pattern, formattedNum, mantissaDigits, calculatedDigits));
|
||||
}
|
||||
}
|
||||
|
||||
private static Boolean wholeNumber(double number) {
|
||||
return (int) number == number;
|
||||
}
|
||||
|
||||
private static Stream<Arguments> patterns() {
|
||||
return Stream.of(
|
||||
Arguments.of("#0.0##E0", 2, 5),
|
||||
Arguments.of("#00.00##E0", 4, 7),
|
||||
Arguments.of("#0.000##E0", 4, 7),
|
||||
Arguments.of("#00.000##E0", 5, 8),
|
||||
Arguments.of("#000.0##E0", 4, 7),
|
||||
Arguments.of("#000.00##E0", 5, 8),
|
||||
Arguments.of("#000.000##E0", 6, 9),
|
||||
Arguments.of("000.000E0", 6, 6),
|
||||
Arguments.of("#.##E0", 0, 3),
|
||||
Arguments.of("######.######E0", 0, 12),
|
||||
Arguments.of("####00.00######E0", 4, 14)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
#
|
||||
# Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
# Hex dump of a serialized NumberFormat for NumberRegression.
|
||||
|
||||
aced0005737200176a6176612e746578742e446563696d616c466f726d61740b
|
||||
ff0362d872303a02000b5a001b646563696d616c536570617261746f72416c77
|
||||
61797353686f776e42000c67726f7570696e6753697a654200116d696e457870
|
||||
6f6e656e7444696769747349000a6d756c7469706c6965724900157365726961
|
||||
6c56657273696f6e4f6e53747265616d5a00167573654578706f6e656e746961
|
||||
6c4e6f746174696f6e4c000e6e656761746976655072656669787400124c6a61
|
||||
76612f6c616e672f537472696e673b4c000e6e65676174697665537566666978
|
||||
71007e00014c000e706f73697469766550726566697871007e00014c000e706f
|
||||
73697469766553756666697871007e00014c000773796d626f6c737400204c6a
|
||||
6176612f746578742f446563696d616c466f726d617453796d626f6c733b7872
|
||||
00166a6176612e746578742e4e756d626572466f726d6174dff6b3bf137d07e8
|
||||
03000b5a000c67726f7570696e67557365644200116d61784672616374696f6e
|
||||
4469676974734200106d6178496e74656765724469676974734900156d617869
|
||||
6d756d4672616374696f6e4469676974734900146d6178696d756d496e746567
|
||||
65724469676974734200116d696e4672616374696f6e4469676974734200106d
|
||||
696e496e74656765724469676974734900156d696e696d756d4672616374696f
|
||||
6e4469676974734900146d696e696d756d496e74656765724469676974735a00
|
||||
107061727365496e74656765724f6e6c7949001573657269616c56657273696f
|
||||
6e4f6e53747265616d787200106a6176612e746578742e466f726d6174fbd8bc
|
||||
12e90f18430200007870017f7f00000123000001217f7f000001240000012200
|
||||
00000001780003000000000100000001007400012d7400007400007400007372
|
||||
001e6a6176612e746578742e446563696d616c466f726d617453796d626f6c73
|
||||
501d17990868939c02000f430010646563696d616c536570617261746f724300
|
||||
05646967697443000b6578706f6e656e7469616c43001167726f7570696e6753
|
||||
6570617261746f724300096d696e75735369676e4300116d6f6e657461727953
|
||||
6570617261746f724300107061747465726e536570617261746f724300077065
|
||||
724d696c6c43000770657263656e7449001573657269616c56657273696f6e4f
|
||||
6e53747265616d4300097a65726f44696769744c00034e614e71007e00014c00
|
||||
0e63757272656e637953796d626f6c71007e00014c0008696e66696e69747971
|
||||
007e00014c0012696e746c43757272656e637953796d626f6c71007e00017870
|
||||
002e00230045002c002d002e003b20300025000000010030740003efbfbd7400
|
||||
0124740003e2889e740003555344
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
#
|
||||
# Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
# Hex dump of a serialized NumberFormat for NumberRegression.
|
||||
|
||||
aced0005737200176a6176612e746578742e446563696d616c466f726d61740b
|
||||
ff0362d872303a02000b5a001b646563696d616c536570617261746f72416c77
|
||||
61797353686f776e42000c67726f7570696e6753697a654200116d696e457870
|
||||
6f6e656e7444696769747349000a6d756c7469706c6965724900157365726961
|
||||
6c56657273696f6e4f6e53747265616d5a00167573654578706f6e656e746961
|
||||
6c4e6f746174696f6e4c000e6e656761746976655072656669787400124c6a61
|
||||
76612f6c616e672f537472696e673b4c000e6e65676174697665537566666978
|
||||
71007e00014c000e706f73697469766550726566697871007e00014c000e706f
|
||||
73697469766553756666697871007e00014c000773796d626f6c737400204c6a
|
||||
6176612f746578742f446563696d616c466f726d617453796d626f6c733b7872
|
||||
00166a6176612e746578742e4e756d626572466f726d6174dff6b3bf137d07e8
|
||||
03000b5a000c67726f7570696e67557365644200116d61784672616374696f6e
|
||||
4469676974734200106d6178496e74656765724469676974734900156d617869
|
||||
6d756d4672616374696f6e4469676974734900146d6178696d756d496e746567
|
||||
65724469676974734200116d696e4672616374696f6e4469676974734200106d
|
||||
696e496e74656765724469676974734900156d696e696d756d4672616374696f
|
||||
6e4469676974734900146d696e696d756d496e74656765724469676974735a00
|
||||
107061727365496e74656765724f6e6c7949001573657269616c56657273696f
|
||||
6e4f6e53747265616d787200106a6176612e746578742e466f726d6174fbd8bc
|
||||
12e90f18430200007870017f7f00000314000003127f7f000003130000031100
|
||||
00000001780003000000000100000001007400012d7400007400007400007372
|
||||
001e6a6176612e746578742e446563696d616c466f726d617453796d626f6c73
|
||||
501d17990868939c02000f430010646563696d616c536570617261746f724300
|
||||
05646967697443000b6578706f6e656e7469616c43001167726f7570696e6753
|
||||
6570617261746f724300096d696e75735369676e4300116d6f6e657461727953
|
||||
6570617261746f724300107061747465726e536570617261746f724300077065
|
||||
724d696c6c43000770657263656e7449001573657269616c56657273696f6e4f
|
||||
6e53747265616d4300097a65726f44696769744c00034e614e71007e00014c00
|
||||
0e63757272656e637953796d626f6c71007e00014c0008696e66696e69747971
|
||||
007e00014c0012696e746c43757272656e637953796d626f6c71007e00017870
|
||||
002e00230045002c002d002e003b20300025000000010030740003efbfbd7400
|
||||
0124740003e2889e740003555344
|
||||
|
|
@ -0,0 +1,796 @@
|
|||
/*
|
||||
* Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @bug 7050528
|
||||
* @summary Test java.text.DecimalFormat fast-path for format(double...)
|
||||
* @author Olivier Lagneau
|
||||
* @build GoldenDoubleValues GoldenFormattedValues
|
||||
* @run main RoundingAndPropertyTest
|
||||
*
|
||||
*/
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Note :
|
||||
* Since fast-path algorithm does not modify any feature of DecimalFormat,
|
||||
* some tests or values in this program may have to be adapted/added/removed
|
||||
* when any change has been done in the fast-path source code, because the
|
||||
* conditions for exercising fast-path may change.
|
||||
*
|
||||
* This is specially true if the set of constraints to fall in the fast-path
|
||||
* case is relaxed in any manner.
|
||||
*
|
||||
* Usage :
|
||||
* - Run main without any argument to test against a set of golden values and
|
||||
* associated results hard-coded in the source code. That will do the tests
|
||||
* described below
|
||||
* See below comment section named "Description".
|
||||
*
|
||||
* or
|
||||
*
|
||||
* - Run main with string argument "-gengold" to output source code of
|
||||
* GoldenFormattedValues.java class file with the jdk version used while
|
||||
* generating the code.
|
||||
* See below comment section named : "Modifying Golden Values".
|
||||
*
|
||||
* In case of error while running the test, a Runtime exception is generated
|
||||
* providing the numbers of errors detected (format of golden values checks and
|
||||
* property changes checks), and the program exit.
|
||||
*
|
||||
* Description :
|
||||
*
|
||||
* This test first checks that localization of digits is done correctly when
|
||||
* calling DecimalFormat.format() on the array of values DecimalLocalizationValues
|
||||
* found in GoldenDoubleValues, using the locale FullLocalizationTestLocale
|
||||
* (from GoldenDoubleValues) that implies localization of digits. it checks the
|
||||
* the results against expected returned string. In case of formatting error,
|
||||
* it provides a message informing which value was wrongly formatted.
|
||||
*
|
||||
* Then it checks the results of calling NumberFormat.format(double) on a set
|
||||
* of predefined golden values and checks results against expected returned
|
||||
* string. It does this both for the decimal case, with an instance returned
|
||||
* NumberFormat.getInstance() call and for the currency case, with an instance
|
||||
* returned by NumberFormat.getCurrencyInstance(). Almost all the tested double
|
||||
* values satisfy the constraints assumed by the fast-path algorithm for
|
||||
* format(double ...). Some are voluntarily outside the scope of fast-path to
|
||||
* check that the algorithm correctly eliminate them. In case of formatting
|
||||
* error a message provides information on the golden value raising the error
|
||||
* (value, exact decimal value (using BidDecimal), expected result, formatted result).
|
||||
*
|
||||
* Last the test checks the status and behavior of a DecimalFormat instance
|
||||
* when changing properties that make this instance satisfy/invalidate its
|
||||
* fast-path status, depending on the predefined set of fast-path constraints.
|
||||
*
|
||||
* The golden results are predefined arrays of int[] containing the unicode
|
||||
* ints of the chars in the expected formatted string, when using locale
|
||||
* provided in GoldenDoubleValues class. The results are those obtained by
|
||||
* using a reference jdk version (for example one that does not contains the
|
||||
* DecimalFormat fast-path algorithm, like jdk80-b25).
|
||||
*
|
||||
* The double values from which we get golden results are stored inside two
|
||||
* arrays of double values:
|
||||
* - DecimalGoldenValues for testing NumberFormat.getInstance().
|
||||
* - CurrencyGoldenValues for testing NumberFormat.getCurrencyInstance().
|
||||
* These arrays are located in GoldenDoubleValues.java source file.
|
||||
*
|
||||
* For each double value in the arrays above, there is an associated golden
|
||||
* result. These results are stored in arrays of int[]:
|
||||
* - DecimalGoldenFormattedValues for expected decimal golden results.
|
||||
* - CurrencyGoldenFormattedValues for expected currency golden results.
|
||||
* - DecimalDigitsLocalizedFormattedValues for expected localized digit results.
|
||||
*
|
||||
* We store the results in int[] arrays containing the expected unicode values
|
||||
* because the compiler that will compile the containing java file may use a
|
||||
* different locale than the one registered in GoldenDoubleValues.java. These
|
||||
* arrays are located in a separate GoldenFormattedValues.java source file
|
||||
* that is generated by RoundingAndPropertyTest using "-gengold" parameter.
|
||||
* See below "Modifying Golden Values".
|
||||
*
|
||||
* The golden value arrays can be expanded, modified ... to test additional
|
||||
* or different double values. In that case, the source file of class
|
||||
* GoldenFormattedValues must be regenerated to replace the existing one..
|
||||
*
|
||||
* Modifying Golden Values :
|
||||
*
|
||||
* In order to ease further modification of the list of double values checked
|
||||
* and associated golden results, the test includes the method
|
||||
* generatesGoldenFormattedValuesClass() that writes on standard output stream
|
||||
* the source code for GoldenFormattedValues class that includes the expected
|
||||
* results arrays.
|
||||
*
|
||||
* Here are the steps to follow for updating/modifying golden values and results:
|
||||
* 1- Edit GoldenDoubleValues.java to add/remove/modify golden or localization
|
||||
* values.
|
||||
* 2- Run main with "-gengold" string argument with a target jdk.
|
||||
* (at the creation of this test file, the target jdk used was jdk1.8.0-ea).
|
||||
* 2- Copy this java code that has been writen on standard output and replace
|
||||
* GoldenFormattedValues.java contents by the generated output.
|
||||
* 3- Check that this updated code compiles.
|
||||
* [4]- If needed replaces existing GoldenDoubleValues and GoldenFormattedValues
|
||||
* files in jdk/test section, respectively by the one modified at step 1 and
|
||||
* generated at step 2.
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
import java.util.*;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
import java.math.RoundingMode;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
|
||||
public class RoundingAndPropertyTest {
|
||||
|
||||
|
||||
// Prints on standard output stream the unicode values of chars as a
|
||||
// comma-separated list of int values
|
||||
private static void printUnicodeValuesArray(char[] chars) {
|
||||
for (int i = 0; i < chars.length; i++) {
|
||||
System.out.print((int) chars[i]);
|
||||
if (i != (chars.length - 1))
|
||||
System.out.print(", ");
|
||||
}
|
||||
}
|
||||
|
||||
// Converts given array of unicode values as an array of chars.
|
||||
// Returns this converted array.
|
||||
private static char[] getCharsFromUnicodeArray(int[] unicodeValues) {
|
||||
char[] chars = new char[unicodeValues.length];
|
||||
|
||||
for (int i = 0; i < unicodeValues.length; i++) {
|
||||
chars[i] = (char) unicodeValues[i];
|
||||
}
|
||||
return chars;
|
||||
}
|
||||
|
||||
/* Prints on standard output stream the java code of resulting
|
||||
* GoldenFormattedValues class for the golden values found in
|
||||
* class GoldenDoubleValues.
|
||||
*/
|
||||
private static void generatesGoldenFormattedValuesClass() {
|
||||
|
||||
String fourWhiteSpaces = " ";
|
||||
String eightWhiteSpaces = " ";
|
||||
|
||||
// Prints header without Copyright header.
|
||||
System.out.println("/* This is a machine generated file - Please DO NOT EDIT !");
|
||||
System.out.println(" * Change RoundingAndPropertyTest instead,");
|
||||
System.out.println(" * and run with \"-gengold\" argument to regenerate (without copyright header).");
|
||||
System.out.println(" */");
|
||||
System.out.println();
|
||||
|
||||
System.out.println("/* This file contains the set of result Strings expected from calling inside");
|
||||
System.out.println(" * RoundingAndPropertyTest the method NumberFormat.format() upon the set of");
|
||||
System.out.println(" * double values provided in GoldenDoubleValues.java. It contains three arrays,");
|
||||
System.out.println(" * each containing arrays of unicode values representing the expected string");
|
||||
System.out.println(" * result when calling format() on the corresponding (i.e. same index) double");
|
||||
System.out.println(" * value found in GoldenDoubleValues arrays :");
|
||||
System.out.println(" * - DecimalDigitsLocalizedFormattedValues corresponds to DecimalLocalizationValues,");
|
||||
System.out.println(" * when using FullLocalizationTestLocale to format.");
|
||||
System.out.println(" * - DecimalGoldenFormattedValues corresponds to DecimalGoldenValues, when used");
|
||||
System.out.println(" * in the decimal pattern case together with TestLocale.");
|
||||
System.out.println(" * - CurrencyGoldenFormattedValues corresponds to CurrencyGoldenValues. when used");
|
||||
System.out.println(" * in the currency pattern case together with TestLocale.");
|
||||
System.out.println(" * Please see documentation in RoundingAndPropertyTest.java for more details.");
|
||||
System.out.println(" *");
|
||||
System.out.println(" * This file generated by running RoundingAndPropertyTest with \"-gengold\" argument.");
|
||||
System.out.println(" */");
|
||||
System.out.println();
|
||||
|
||||
// Prints beginning of class GoldenFormattedValues.
|
||||
System.out.println("class GoldenFormattedValues {");
|
||||
System.out.println();
|
||||
System.out.println(
|
||||
fourWhiteSpaces +
|
||||
"// The formatted values below were generated from golden values");
|
||||
System.out.print(
|
||||
fourWhiteSpaces +
|
||||
"// listed in GoldenDoubleValues.java,");
|
||||
System.out.println(" using the following jvm version :");
|
||||
System.out.println(
|
||||
fourWhiteSpaces + "// " +
|
||||
System.getProperty("java.vendor") +
|
||||
" " +
|
||||
System.getProperty("java.vm.name") +
|
||||
" " +
|
||||
System.getProperty("java.version"));
|
||||
System.out.println(
|
||||
fourWhiteSpaces +
|
||||
"// locale for golden double values : " + GoldenDoubleValues.TestLocale);
|
||||
System.out.println(
|
||||
fourWhiteSpaces +
|
||||
"// locale for testing digit localization : " + GoldenDoubleValues.FullLocalizationTestLocale);
|
||||
System.out.println();
|
||||
|
||||
// Prints the expected results when digit localization happens
|
||||
System.out.println(
|
||||
fourWhiteSpaces +
|
||||
"// The array of int[] unicode values storing the expected results");
|
||||
System.out.print(
|
||||
fourWhiteSpaces +
|
||||
"// when experiencing full localization of digits");
|
||||
System.out.println(" on DecimalLocalizationValues.");
|
||||
System.out.println(
|
||||
fourWhiteSpaces +
|
||||
"static int[][] DecimalDigitsLocalizedFormattedValues = {");
|
||||
NumberFormat df =
|
||||
NumberFormat.getInstance(GoldenDoubleValues.FullLocalizationTestLocale);
|
||||
for (int i = 0;
|
||||
i < GoldenDoubleValues.DecimalLocalizationValues.length;
|
||||
i++) {
|
||||
double d = GoldenDoubleValues.DecimalLocalizationValues[i];
|
||||
String formatted = df.format(d);
|
||||
char[] decFmtChars = formatted.toCharArray();
|
||||
|
||||
System.out.print(eightWhiteSpaces + "{ ");
|
||||
printUnicodeValuesArray(decFmtChars);
|
||||
System.out.println(" },");
|
||||
}
|
||||
System.out.println(fourWhiteSpaces + "};");
|
||||
System.out.println();
|
||||
|
||||
// Prints the golden expected results for the decimal pattern case
|
||||
System.out.println(
|
||||
fourWhiteSpaces +
|
||||
"// The array of int[] unicode values storing the expected results");
|
||||
System.out.print(
|
||||
fourWhiteSpaces +
|
||||
"// when calling Decimal.format(double)");
|
||||
System.out.println(" on the decimal GoldenDoubleValues.");
|
||||
System.out.println(
|
||||
fourWhiteSpaces +
|
||||
"static int[][] DecimalGoldenFormattedValues = {");
|
||||
df = NumberFormat.getInstance(GoldenDoubleValues.TestLocale);
|
||||
for (int i = 0;
|
||||
i < GoldenDoubleValues.DecimalGoldenValues.length;
|
||||
i++) {
|
||||
double d = GoldenDoubleValues.DecimalGoldenValues[i];
|
||||
String formatted = df.format(d);
|
||||
char[] decFmtChars = formatted.toCharArray();
|
||||
|
||||
System.out.print(eightWhiteSpaces + "{ ");
|
||||
printUnicodeValuesArray(decFmtChars);
|
||||
System.out.println(" },");
|
||||
}
|
||||
System.out.println(fourWhiteSpaces + "};");
|
||||
System.out.println();
|
||||
|
||||
// Prints the golden expected results for the currency pattern case
|
||||
System.out.println(
|
||||
fourWhiteSpaces +
|
||||
"// The array of int[] unicode values storing the expected results");
|
||||
System.out.print(
|
||||
fourWhiteSpaces +
|
||||
"// when calling Decimal.format(double)");
|
||||
System.out.println(" on the currency GoldenDoubleValues.");
|
||||
System.out.println(
|
||||
fourWhiteSpaces +
|
||||
"static int[][] CurrencyGoldenFormattedValues = {");
|
||||
NumberFormat cf =
|
||||
NumberFormat.getCurrencyInstance(GoldenDoubleValues.TestLocale);
|
||||
for (int i = 0;
|
||||
i < GoldenDoubleValues.CurrencyGoldenValues.length;
|
||||
i++) {
|
||||
double d = GoldenDoubleValues.CurrencyGoldenValues[i];
|
||||
String formatted = cf.format(d);
|
||||
char[] decFmtChars = formatted.toCharArray();
|
||||
|
||||
System.out.print(eightWhiteSpaces + "{ ");
|
||||
printUnicodeValuesArray(decFmtChars);
|
||||
System.out.println(" },");
|
||||
}
|
||||
System.out.println(fourWhiteSpaces + "};");
|
||||
System.out.println();
|
||||
|
||||
// Prints end of GoldenFormattedValues class.
|
||||
System.out.println("}");
|
||||
}
|
||||
|
||||
private static int testLocalizationValues() {
|
||||
|
||||
DecimalFormat df = (DecimalFormat)
|
||||
NumberFormat.getInstance(GoldenDoubleValues.FullLocalizationTestLocale);
|
||||
|
||||
double[] localizationValues = GoldenDoubleValues.DecimalLocalizationValues;
|
||||
int size = localizationValues.length;
|
||||
int successCounter = 0;
|
||||
int failureCounter = 0;
|
||||
for (int i = 0; i < size; i++) {
|
||||
|
||||
double d = localizationValues[i];
|
||||
String formatted = df.format(d);
|
||||
|
||||
char[] expectedUnicodeArray =
|
||||
getCharsFromUnicodeArray(
|
||||
GoldenFormattedValues.DecimalDigitsLocalizedFormattedValues[i]);
|
||||
String expected = new String(expectedUnicodeArray);
|
||||
|
||||
if (!formatted.equals(expected)) {
|
||||
failureCounter++;
|
||||
System.out.println(
|
||||
"--- Localization error for value d = " + d +
|
||||
". Exact value = " + new BigDecimal(d).toString() +
|
||||
". Expected result = " + expected +
|
||||
". Output result = " + formatted);
|
||||
} else successCounter++;
|
||||
}
|
||||
System.out.println("Checked positively " + successCounter +
|
||||
" golden decimal values out of " + size +
|
||||
" tests. There were " + failureCounter +
|
||||
" format failure");
|
||||
|
||||
return failureCounter;
|
||||
}
|
||||
|
||||
private static int testGoldenValues(java.text.DecimalFormat df,
|
||||
java.text.DecimalFormat cf) {
|
||||
|
||||
double[] goldenDecimalValues = GoldenDoubleValues.DecimalGoldenValues;
|
||||
int decimalSize = goldenDecimalValues.length;
|
||||
int decimalSuccessCounter = 0;
|
||||
int decimalFailureCounter = 0;
|
||||
for (int i = 0; i < decimalSize; i++) {
|
||||
|
||||
double d = goldenDecimalValues[i];
|
||||
String formatted = df.format(d);
|
||||
|
||||
char[] expectedUnicodeArray =
|
||||
getCharsFromUnicodeArray(
|
||||
GoldenFormattedValues.DecimalGoldenFormattedValues[i]);
|
||||
String expected = new String(expectedUnicodeArray);
|
||||
|
||||
if (!formatted.equals(expected)) {
|
||||
decimalFailureCounter++;
|
||||
System.out.println(
|
||||
"--- Error for golden value d = " + d +
|
||||
". Exact value = " + new BigDecimal(d).toString() +
|
||||
". Expected result = " + expected +
|
||||
". Output result = " + formatted);
|
||||
} else decimalSuccessCounter++;
|
||||
}
|
||||
System.out.println("Checked positively " + decimalSuccessCounter +
|
||||
" golden decimal values out of " + decimalSize +
|
||||
" tests. There were " + decimalFailureCounter +
|
||||
" format failure");
|
||||
|
||||
double[] goldenCurrencyValues = GoldenDoubleValues.CurrencyGoldenValues;
|
||||
int currencySize = goldenCurrencyValues.length;
|
||||
int currencySuccessCounter = 0;
|
||||
int currencyFailureCounter = 0;
|
||||
for (int i = 0; i < currencySize; i++) {
|
||||
double d = goldenCurrencyValues[i];
|
||||
String formatted = cf.format(d);
|
||||
|
||||
char[] expectedUnicodeArray =
|
||||
getCharsFromUnicodeArray(
|
||||
GoldenFormattedValues.CurrencyGoldenFormattedValues[i]);
|
||||
String expected = new String(expectedUnicodeArray);
|
||||
|
||||
if (!formatted.equals(expected)) {
|
||||
currencyFailureCounter++;
|
||||
System.out.println(
|
||||
"--- Error for golden value d = " + d +
|
||||
". Exact value = " + new BigDecimal(d).toString() +
|
||||
". Expected result = " + expected +
|
||||
". Output result = " + formatted);
|
||||
} else currencySuccessCounter++;
|
||||
}
|
||||
System.out.println("Checked positively " + currencySuccessCounter +
|
||||
" golden currency values out of " + currencySize +
|
||||
" tests. There were " + currencyFailureCounter +
|
||||
" format failure");
|
||||
|
||||
return (decimalFailureCounter + currencyFailureCounter);
|
||||
}
|
||||
|
||||
// Checks that the two passed s1 and s2 string are equal, and prints
|
||||
// out message in case of error.
|
||||
private static boolean resultsEqual(String propertyName,
|
||||
String s1,
|
||||
String s2) {
|
||||
|
||||
boolean equality = s1.equals(s2);
|
||||
if (!equality)
|
||||
System.out.println(
|
||||
"\n*** Error while reverting to default " +
|
||||
propertyName + " property.\n" +
|
||||
" initial output = " + s1 +
|
||||
". reverted output = " + s2 + ".");
|
||||
else System.out.println(" Test passed.");
|
||||
|
||||
return equality;
|
||||
|
||||
}
|
||||
|
||||
/* This methods checks the behaviour of the management of properties
|
||||
* of a DecimalFormat instance that satisfies fast-path constraints.
|
||||
*
|
||||
* It does this by comparing the results of the format(double) output
|
||||
* obtained from initial fast-path state with the output provided by
|
||||
* the same instance that has been pushed and exercised outside
|
||||
* fast-path rules and finally "reverted" to its initial fast-path state.
|
||||
*
|
||||
* The schema of actions is this :
|
||||
* - Call format(double) on a known DecimalFormat fast-path instance,
|
||||
* and store this result.
|
||||
* - Record the current state of a given property.
|
||||
* - Change the property to invalidate the fast-path state.
|
||||
* - Call again format(double) on the instance.
|
||||
* - Revert state of property to validate again fast-path context.
|
||||
* - Call format(double) again.
|
||||
* - Check that first and last call to format(double) provide same result
|
||||
* - Record failure if any.
|
||||
* - Do the same for another property with the same instance.
|
||||
* So all the property changes are chained one after the other on only the
|
||||
* same instance.
|
||||
*
|
||||
* Some properties that currently do not influence the fast-path state
|
||||
* are also tested. This is not useful with current fast-path source
|
||||
* but is here for testing the whole set of properties. This is the case
|
||||
* for prefixes and suffixes, and parseBigDecimal properties.
|
||||
*/
|
||||
private static int testSettersAndFastPath(DecimalFormat df,
|
||||
boolean isCurrency) {
|
||||
|
||||
final double d1 = GoldenDoubleValues.PROPERTY_CHECK_POSITIVE_VALUE;
|
||||
final double d2 = GoldenDoubleValues.PROPERTY_CHECK_NEGATIVE_VALUE;
|
||||
|
||||
int errors = 0;
|
||||
boolean testSucceeded = false;
|
||||
String firstFormatResult;
|
||||
String secondFormatResult;
|
||||
String propertyName;
|
||||
|
||||
// ---- positivePrefix property test ----
|
||||
testSucceeded = false;
|
||||
propertyName = "positivePrefix";
|
||||
System.out.print("Checking " + propertyName + " property.");
|
||||
String initialPrefix = df.getPositivePrefix();
|
||||
firstFormatResult = df.format(d1);
|
||||
df.setPositivePrefix("positivePrefix:");
|
||||
df.format(d1);
|
||||
df.setPositivePrefix(initialPrefix);
|
||||
secondFormatResult = df.format(d1);
|
||||
testSucceeded =
|
||||
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
|
||||
if (!testSucceeded)
|
||||
errors++;
|
||||
|
||||
// ---- positiveSuffix property test ----
|
||||
testSucceeded = false;
|
||||
propertyName = "positiveSuffix";
|
||||
System.out.print("Checking " + propertyName + " property.");
|
||||
String initialSuffix = df.getPositiveSuffix();
|
||||
firstFormatResult = df.format(d1);
|
||||
df.setPositiveSuffix("positiveSuffix:");
|
||||
df.format(d1);
|
||||
df.setPositiveSuffix(initialSuffix);
|
||||
secondFormatResult = df.format(d1);
|
||||
testSucceeded =
|
||||
resultsEqual(propertyName,firstFormatResult, secondFormatResult);
|
||||
if (!testSucceeded)
|
||||
errors++;
|
||||
|
||||
// ---- negativePrefix property test ----
|
||||
testSucceeded = false;
|
||||
propertyName = "negativePrefix";
|
||||
System.out.print("Checking " + propertyName + " property.");
|
||||
initialPrefix = df.getNegativePrefix();
|
||||
firstFormatResult = df.format(d1);
|
||||
df.setNegativePrefix("negativePrefix:");
|
||||
df.format(d1);
|
||||
df.setNegativePrefix(initialPrefix);
|
||||
secondFormatResult = df.format(d1);
|
||||
testSucceeded =
|
||||
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
|
||||
if (!testSucceeded)
|
||||
errors++;
|
||||
|
||||
// ---- negativeSuffix property test ----
|
||||
testSucceeded = false;
|
||||
propertyName = "negativeSuffix";
|
||||
System.out.print("Checking " + propertyName + " property.");
|
||||
initialSuffix = df.getNegativeSuffix();
|
||||
firstFormatResult = df.format(d1);
|
||||
df.setNegativeSuffix("negativeSuffix:");
|
||||
df.format(d1);
|
||||
df.setNegativeSuffix(initialSuffix);
|
||||
secondFormatResult = df.format(d1);
|
||||
testSucceeded =
|
||||
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
|
||||
if (!testSucceeded)
|
||||
errors++;
|
||||
|
||||
// ---- multiplier property test ----
|
||||
testSucceeded = false;
|
||||
propertyName = "multiplier";
|
||||
System.out.print("Checking " + propertyName + " property.");
|
||||
int initialMultiplier = df.getMultiplier();
|
||||
firstFormatResult = df.format(d1);
|
||||
df.setMultiplier(10);
|
||||
df.format(d1);
|
||||
df.setMultiplier(initialMultiplier);
|
||||
secondFormatResult = df.format(d1);
|
||||
testSucceeded =
|
||||
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
|
||||
if (!testSucceeded)
|
||||
errors++;
|
||||
|
||||
// ---- groupingUsed property test ----
|
||||
testSucceeded = false;
|
||||
propertyName = "groupingUsed";
|
||||
System.out.print("Checking " + propertyName + " property.");
|
||||
boolean initialGroupingUsed = df.isGroupingUsed();
|
||||
firstFormatResult = df.format(d1);
|
||||
df.setGroupingUsed(!initialGroupingUsed);
|
||||
df.format(d1);
|
||||
df.setGroupingUsed(initialGroupingUsed);
|
||||
secondFormatResult = df.format(d1);
|
||||
testSucceeded =
|
||||
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
|
||||
if (!testSucceeded)
|
||||
errors++;
|
||||
|
||||
// ---- groupingSize property test ----
|
||||
testSucceeded = false;
|
||||
propertyName = "groupingSize";
|
||||
System.out.print("Checking " + propertyName + " property.");
|
||||
int initialGroupingSize = df.getGroupingSize();
|
||||
firstFormatResult = df.format(d1);
|
||||
df.setGroupingSize(initialGroupingSize + 1);
|
||||
df.format(d1);
|
||||
df.setGroupingSize(initialGroupingSize);
|
||||
secondFormatResult = df.format(d1);
|
||||
testSucceeded =
|
||||
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
|
||||
if (!testSucceeded)
|
||||
errors++;
|
||||
|
||||
// ---- decimalSeparatorAlwaysShown property test ----
|
||||
testSucceeded = false;
|
||||
propertyName = "decimalSeparatorAlwaysShown";
|
||||
System.out.print("Checking " + propertyName + " property.");
|
||||
boolean initialDSShown = df.isDecimalSeparatorAlwaysShown();
|
||||
firstFormatResult = df.format(d1);
|
||||
df.setDecimalSeparatorAlwaysShown(!initialDSShown);
|
||||
df.format(d1);
|
||||
df.setDecimalSeparatorAlwaysShown(initialDSShown);
|
||||
secondFormatResult = df.format(d1);
|
||||
testSucceeded =
|
||||
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
|
||||
if (!testSucceeded)
|
||||
errors++;
|
||||
|
||||
// ---- parseBigDecimal property test ----
|
||||
testSucceeded = false;
|
||||
propertyName = "parseBigDecimal";
|
||||
System.out.print("Checking " + propertyName + " property.");
|
||||
boolean initialParseBigdecimal = df.isParseBigDecimal();
|
||||
firstFormatResult = df.format(d1);
|
||||
df.setParseBigDecimal(!initialParseBigdecimal);
|
||||
df.format(d1);
|
||||
df.setParseBigDecimal(initialParseBigdecimal);
|
||||
secondFormatResult = df.format(d1);
|
||||
testSucceeded =
|
||||
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
|
||||
if (!testSucceeded)
|
||||
errors++;
|
||||
|
||||
// ---- maximumIntegerDigits property test ----
|
||||
testSucceeded = false;
|
||||
propertyName = "maximumIntegerDigits";
|
||||
System.out.print("Checking " + propertyName + " property.");
|
||||
int initialMaxIDs = df.getMaximumIntegerDigits();
|
||||
firstFormatResult = df.format(d1);
|
||||
df.setMaximumIntegerDigits(8);
|
||||
df.format(d1);
|
||||
df.setMaximumIntegerDigits(initialMaxIDs);
|
||||
secondFormatResult = df.format(d1);
|
||||
testSucceeded =
|
||||
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
|
||||
if (!testSucceeded)
|
||||
errors++;
|
||||
|
||||
// ---- minimumIntegerDigits property test ----
|
||||
testSucceeded = false;
|
||||
propertyName = "minimumIntegerDigits";
|
||||
System.out.print("Checking " + propertyName + " property.");
|
||||
int initialMinIDs = df.getMinimumIntegerDigits();
|
||||
firstFormatResult = df.format(d1);
|
||||
df.setMinimumIntegerDigits(2);
|
||||
df.format(d1);
|
||||
df.setMinimumIntegerDigits(initialMinIDs);
|
||||
secondFormatResult = df.format(d1);
|
||||
testSucceeded =
|
||||
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
|
||||
if (!testSucceeded)
|
||||
errors++;
|
||||
|
||||
// ---- maximumFractionDigits property test ----
|
||||
testSucceeded = false;
|
||||
propertyName = "maximumFractionDigits";
|
||||
System.out.print("Checking " + propertyName + " property.");
|
||||
firstFormatResult = df.format(d1);
|
||||
df.setMaximumFractionDigits(8);
|
||||
df.format(d1);
|
||||
if (isCurrency) {
|
||||
df.setMinimumFractionDigits(2);
|
||||
df.setMaximumFractionDigits(2);
|
||||
} else {
|
||||
df.setMinimumFractionDigits(0);
|
||||
df.setMaximumFractionDigits(3);
|
||||
}
|
||||
secondFormatResult = df.format(d1);
|
||||
testSucceeded =
|
||||
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
|
||||
if (!testSucceeded)
|
||||
errors++;
|
||||
|
||||
// ---- minimumFractionDigits property test ----
|
||||
testSucceeded = false;
|
||||
propertyName = "minimumFractionDigits";
|
||||
System.out.print("Checking " + propertyName + " property.");
|
||||
firstFormatResult = df.format(d1);
|
||||
df.setMinimumFractionDigits(1);
|
||||
df.format(d1);
|
||||
if (isCurrency) {
|
||||
df.setMinimumFractionDigits(2);
|
||||
df.setMaximumFractionDigits(2);
|
||||
} else {
|
||||
df.setMinimumFractionDigits(0);
|
||||
df.setMaximumFractionDigits(3);
|
||||
}
|
||||
secondFormatResult = df.format(d1);
|
||||
testSucceeded =
|
||||
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
|
||||
if (!testSucceeded)
|
||||
errors++;
|
||||
|
||||
// ---- currency property test ----
|
||||
testSucceeded = false;
|
||||
propertyName = "currency";
|
||||
System.out.print("Checking " + propertyName + " property.");
|
||||
Currency initialCurrency = df.getCurrency();
|
||||
Currency japanCur = java.util.Currency.getInstance(Locale.JAPAN);
|
||||
firstFormatResult = df.format(d1);
|
||||
df.setCurrency(japanCur);
|
||||
df.format(d1);
|
||||
df.setCurrency(initialCurrency);
|
||||
secondFormatResult = df.format(d1);
|
||||
testSucceeded =
|
||||
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
|
||||
if (!testSucceeded)
|
||||
errors++;
|
||||
|
||||
// ---- roundingMode property test ----
|
||||
testSucceeded = false;
|
||||
propertyName = "roundingMode";
|
||||
System.out.print("Checking " + propertyName + " property.");
|
||||
RoundingMode initialRMode = df.getRoundingMode();
|
||||
firstFormatResult = df.format(d1);
|
||||
df.setRoundingMode(RoundingMode.HALF_UP);
|
||||
df.format(d1);
|
||||
df.setRoundingMode(RoundingMode.HALF_EVEN);
|
||||
secondFormatResult = df.format(d1);
|
||||
testSucceeded =
|
||||
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
|
||||
if (!testSucceeded)
|
||||
errors++;
|
||||
|
||||
// ---- decimalFormatSymbols property test ----
|
||||
testSucceeded = false;
|
||||
propertyName = "decimalFormatSymbols";
|
||||
System.out.print("Checking " + propertyName + " property.");
|
||||
DecimalFormatSymbols initialDecimalFormatSymbols = df.getDecimalFormatSymbols();
|
||||
firstFormatResult = df.format(d1);
|
||||
Locale bizarreLocale = Locale.FRANCE;
|
||||
DecimalFormatSymbols unusualSymbols = new DecimalFormatSymbols(bizarreLocale);
|
||||
unusualSymbols.setDecimalSeparator('@');
|
||||
unusualSymbols.setGroupingSeparator('|');
|
||||
df.setDecimalFormatSymbols(unusualSymbols);
|
||||
df.format(d1);
|
||||
df.setDecimalFormatSymbols(initialDecimalFormatSymbols);
|
||||
secondFormatResult = df.format(d1);
|
||||
testSucceeded =
|
||||
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
|
||||
if (!testSucceeded)
|
||||
errors++;
|
||||
|
||||
testSucceeded = false;
|
||||
System.out.print("Checking " + propertyName + " property.");
|
||||
initialDecimalFormatSymbols = df.getDecimalFormatSymbols();
|
||||
firstFormatResult = df.format(d1);
|
||||
Locale japanLocale = Locale.JAPAN;
|
||||
unusualSymbols = new DecimalFormatSymbols(japanLocale);
|
||||
unusualSymbols.setDecimalSeparator('9');
|
||||
unusualSymbols.setGroupingSeparator('0');
|
||||
df.setDecimalFormatSymbols(unusualSymbols);
|
||||
df.format(d1);
|
||||
df.setDecimalFormatSymbols(initialDecimalFormatSymbols);
|
||||
secondFormatResult = df.format(d1);
|
||||
testSucceeded =
|
||||
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
|
||||
if (!testSucceeded)
|
||||
errors++;
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
// Main for RoundingAndPropertyTest. We test first the golden values,
|
||||
// and then the property setters and getters.
|
||||
public static void main(String[] args) {
|
||||
|
||||
if ((args.length >= 1) &&
|
||||
(args[0].equals("-gengold")))
|
||||
generatesGoldenFormattedValuesClass();
|
||||
else {
|
||||
System.out.println("\nChecking correctness of formatting with digit localization.");
|
||||
System.out.println("=============================================================");
|
||||
int localizationErrors = testLocalizationValues();
|
||||
if (localizationErrors != 0)
|
||||
System.out.println("*** Failure in localization tests : " +
|
||||
localizationErrors + " errors detected ");
|
||||
else System.out.println(" Tests for full localization of digits all passed.");
|
||||
|
||||
DecimalFormat df = (DecimalFormat)
|
||||
NumberFormat.getInstance(GoldenDoubleValues.TestLocale);
|
||||
DecimalFormat cf = (DecimalFormat)
|
||||
NumberFormat.getCurrencyInstance(GoldenDoubleValues.TestLocale);
|
||||
|
||||
System.out.println("\nChecking correctness of formating for golden values.");
|
||||
System.out.println("=============================================================");
|
||||
int goldenValuesErrors = testGoldenValues(df,cf);
|
||||
if (goldenValuesErrors != 0)
|
||||
System.out.println("*** Failure in goldenValues tests : " +
|
||||
goldenValuesErrors + " errors detected ");
|
||||
else System.out.println(" Tests for golden values all passed.");
|
||||
|
||||
System.out.println("\nChecking behavior of property changes for decimal case.");
|
||||
System.out.println("=============================================================");
|
||||
int decimalTestsErrors = testSettersAndFastPath(df, false);
|
||||
if (decimalTestsErrors != 0)
|
||||
System.out.println("*** Failure in decimal property changes tests : " +
|
||||
decimalTestsErrors + " errors detected ");
|
||||
else System.out.println(" Tests for decimal property changes all passed.");
|
||||
|
||||
System.out.println("\nChecking behavior of property changes for currency case.");
|
||||
System.out.println("=============================================================");
|
||||
int currencyTestsErrors = testSettersAndFastPath(cf, true);
|
||||
if (currencyTestsErrors != 0)
|
||||
System.out.println("*** Failure in currency property changes tests : " +
|
||||
currencyTestsErrors + " errors detected ");
|
||||
else System.out.println(" Tests for currency property chamges all passed.");
|
||||
|
||||
if ((localizationErrors > 0) ||
|
||||
(goldenValuesErrors > 0) ||
|
||||
(decimalTestsErrors > 0) ||
|
||||
(currencyTestsErrors > 0))
|
||||
throw new RuntimeException(
|
||||
"Failed with " +
|
||||
(localizationErrors + goldenValuesErrors +
|
||||
decimalTestsErrors + currencyTestsErrors) +
|
||||
" error(s).");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8369050
|
||||
* @summary Check rounding of DecimalFormat on tie cases when the maximum
|
||||
* fraction digits allowed is one less than the position of the first
|
||||
* significant digit in the double.
|
||||
* @run junit RoundingTiesNearZeroTest
|
||||
*/
|
||||
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import java.math.RoundingMode;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Locale;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class RoundingTiesNearZeroTest {
|
||||
|
||||
// Safe to re-use since we are not testing any fast-path cases
|
||||
// so state is irrelevant
|
||||
private static final NumberFormat format = NumberFormat.getInstance(Locale.US);
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("ties")
|
||||
void roundingTieTest(RoundingMode rm, int maxDigits, double db, String expected) {
|
||||
format.setRoundingMode(rm);
|
||||
format.setMaximumFractionDigits(maxDigits);
|
||||
assertEquals(expected, format.format(db), "Rounding failed under " + rm);
|
||||
}
|
||||
|
||||
static Stream<Arguments> ties() {
|
||||
return Stream.of(
|
||||
// 1) String is exact as binary
|
||||
// 0.5 -> 0.5
|
||||
Arguments.of(RoundingMode.HALF_EVEN, 0, 0.5, "0"),
|
||||
Arguments.of(RoundingMode.HALF_UP, 0, 0.5, "1"),
|
||||
Arguments.of(RoundingMode.HALF_DOWN, 0, 0.5, "0"),
|
||||
// 2) String is rounded up from binary
|
||||
// 0.0000005 -> 4.999999999999999773740559129431293428069693618454039096832275390625E-7
|
||||
Arguments.of(RoundingMode.HALF_EVEN, 6, 0.0000005, "0"),
|
||||
Arguments.of(RoundingMode.HALF_UP, 6, 0.0000005, "0"),
|
||||
Arguments.of(RoundingMode.HALF_DOWN, 6, 0.0000005, "0"),
|
||||
// 3) String is not rounded up from binary
|
||||
// Non-exponential notation
|
||||
// 0.05 -> 0.05000000000000000277555756156289135105907917022705078125
|
||||
Arguments.of(RoundingMode.HALF_EVEN, 1, 0.05, "0.1"),
|
||||
Arguments.of(RoundingMode.HALF_UP, 1, 0.05, "0.1"),
|
||||
Arguments.of(RoundingMode.HALF_DOWN, 1, 0.05, "0.1"),
|
||||
// Exponential notation
|
||||
// 0.00005 -> 0.0000500000000000000023960868011929647991564706899225711822509765625
|
||||
Arguments.of(RoundingMode.HALF_EVEN, 4, 0.00005, "0.0001"),
|
||||
Arguments.of(RoundingMode.HALF_UP, 4, 0.00005, "0.0001"),
|
||||
Arguments.of(RoundingMode.HALF_DOWN, 4, 0.00005, "0.0001")
|
||||
);
|
||||
}
|
||||
}
|
||||
365
test/jdk/java/text/Format/DecimalFormat/SerializationTest.java
Normal file
365
test/jdk/java/text/Format/DecimalFormat/SerializationTest.java
Normal file
|
|
@ -0,0 +1,365 @@
|
|||
/*
|
||||
* Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* @test
|
||||
* @bug 4069754 4067878 4101150 4185761 8327640
|
||||
* @library /java/text/testlib
|
||||
* @build HexDumpReader
|
||||
* @summary Check de-serialization correctness for DecimalFormat. That is, ensure the
|
||||
* behavior for each stream version is correct during de-serialization.
|
||||
* @run junit/othervm --add-opens java.base/java.text=ALL-UNNAMED SerializationTest
|
||||
*/
|
||||
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InvalidObjectException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Field;
|
||||
import java.math.RoundingMode;
|
||||
import java.text.DateFormat;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.Random;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class SerializationTest {
|
||||
|
||||
@Nested // Test that rely on hex dump files that were written from older JDK versions
|
||||
class HexDumpTests {
|
||||
|
||||
@Test // See 4101150 and CDF which is the serialized hex dump
|
||||
void JDK1_1_4Test() {
|
||||
// Reconstruct a 1.1.4 serializable class which has a DF holder
|
||||
var cdf = (CheckDecimalFormat) assertDoesNotThrow(
|
||||
() -> deSer("DecimalFormat.114.txt"));
|
||||
assertDoesNotThrow(cdf::Update); // Checks format call succeeds
|
||||
}
|
||||
|
||||
@Test // See 4185761
|
||||
void minMaxDigitsTest() {
|
||||
// Reconstructing a DFS stream from an older JDK version
|
||||
// The min digits are smaller than the max digits and should fail
|
||||
// minint maxint minfrac maxfrac
|
||||
// 0x122 0x121 0x124 0x123
|
||||
assertEquals("Digit count range invalid",
|
||||
assertThrows(InvalidObjectException.class,
|
||||
() -> deSer("NumberFormat4185761a.ser.txt")).getMessage());
|
||||
}
|
||||
|
||||
@Test // See 4185761
|
||||
void digitLimitTest() {
|
||||
// Reconstructing a DFS stream from an older JDK version
|
||||
// The digit values exceed the class invariant limits
|
||||
// minint maxint minfrac maxfrac
|
||||
// 0x311 0x312 0x313 0x314
|
||||
assertEquals("Digit count out of range",
|
||||
assertThrows(InvalidObjectException.class,
|
||||
() -> deSer("NumberFormat4185761b.ser.txt")).getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
class VersionTests {
|
||||
|
||||
// Version 0 did not have exponential fields and defaulted the value to false
|
||||
@Test
|
||||
void version0Test() {
|
||||
var crafted = new DFBuilder()
|
||||
.setVer(0)
|
||||
.set("useExponentialNotation", true)
|
||||
.build();
|
||||
var bytes = ser(crafted);
|
||||
var df = assertDoesNotThrow(() -> deSer(bytes));
|
||||
// Ensure we do not observe exponential notation form
|
||||
assertFalse(df.format(0).contains("E"));
|
||||
}
|
||||
|
||||
// Version 1 did not support the affix pattern Strings. Ensure when they
|
||||
// are read in from the stream they are not defaulted and remain null.
|
||||
@Test
|
||||
void version1Test() {
|
||||
var crafted = new DFBuilder()
|
||||
.setVer(1)
|
||||
.set("posPrefixPattern", null)
|
||||
.set("posSuffixPattern", null)
|
||||
.set("negPrefixPattern", null)
|
||||
.set("negSuffixPattern", null)
|
||||
.build();
|
||||
var bytes = ser(crafted);
|
||||
var df = assertDoesNotThrow(() -> deSer(bytes));
|
||||
assertNull(readField(df, "posPrefixPattern"));
|
||||
assertNull(readField(df, "posSuffixPattern"));
|
||||
assertNull(readField(df, "negPrefixPattern"));
|
||||
assertNull(readField(df, "negSuffixPattern"));
|
||||
}
|
||||
|
||||
// Version 2 did not support the min/max int and frac digits.
|
||||
// Ensure the proper defaults are set.
|
||||
@Test
|
||||
void version2Test() {
|
||||
var crafted = new DFBuilder()
|
||||
.setVer(2)
|
||||
.set("maximumIntegerDigits", -1)
|
||||
.set("maximumFractionDigits", -1)
|
||||
.set("minimumIntegerDigits", -1)
|
||||
.set("minimumFractionDigits", -1)
|
||||
.build();
|
||||
var bytes = ser(crafted);
|
||||
var df = assertDoesNotThrow(() -> deSer(bytes));
|
||||
assertEquals(1, df.getMinimumIntegerDigits());
|
||||
assertEquals(3, df.getMaximumFractionDigits());
|
||||
assertEquals(309, df.getMaximumIntegerDigits());
|
||||
assertEquals(0, df.getMinimumFractionDigits());
|
||||
}
|
||||
|
||||
// Version 3 did not support rounding mode. Should default to HALF_EVEN
|
||||
@Test
|
||||
void version3Test() {
|
||||
var crafted = new DFBuilder()
|
||||
.setVer(3)
|
||||
.set("roundingMode", RoundingMode.UNNECESSARY)
|
||||
.build();
|
||||
var bytes = ser(crafted);
|
||||
var df = assertDoesNotThrow(() -> deSer(bytes));
|
||||
assertEquals(RoundingMode.HALF_EVEN, df.getRoundingMode());
|
||||
}
|
||||
}
|
||||
|
||||
// Some invariant checking in DF relies on checking NF fields.
|
||||
// Either via NF.readObject() or through super calls in DF.readObject
|
||||
@Nested // For all these nested tests, see 4185761
|
||||
class NumberFormatTests {
|
||||
|
||||
// Ensure the max integer value invariant is not exceeded
|
||||
@Test
|
||||
void integerTest() {
|
||||
var crafted = new DFBuilder()
|
||||
.setSuper("maximumIntegerDigits", 786)
|
||||
.setSuper("minimumIntegerDigits", 785)
|
||||
.build();
|
||||
var bytes = ser(crafted);
|
||||
assertEquals("Digit count out of range",
|
||||
assertThrows(InvalidObjectException.class, () -> deSer(bytes)).getMessage());
|
||||
}
|
||||
|
||||
// Ensure the max fraction value invariant is not exceeded
|
||||
@Test
|
||||
void fractionTest() {
|
||||
var crafted = new DFBuilder()
|
||||
.setSuper("maximumFractionDigits", 788)
|
||||
.setSuper("minimumFractionDigits", 787)
|
||||
.build();
|
||||
var bytes = ser(crafted);
|
||||
assertEquals("Digit count out of range",
|
||||
assertThrows(InvalidObjectException.class, () -> deSer(bytes)).getMessage());
|
||||
}
|
||||
|
||||
// Ensure the minimum integer digits cannot be greater than the max
|
||||
@Test
|
||||
void maxMinIntegerTest() {
|
||||
var crafted = new DFBuilder()
|
||||
.setSuper("maximumIntegerDigits", 5)
|
||||
.setSuper("minimumIntegerDigits", 6)
|
||||
.build();
|
||||
var bytes = ser(crafted);
|
||||
assertEquals("Digit count range invalid",
|
||||
assertThrows(InvalidObjectException.class, () -> deSer(bytes)).getMessage());
|
||||
}
|
||||
|
||||
// Ensure the minimum fraction digits cannot be greater than the max
|
||||
@Test
|
||||
void maxMinFractionTest() {
|
||||
var crafted = new DFBuilder()
|
||||
.setSuper("maximumFractionDigits", 5)
|
||||
.setSuper("minimumFractionDigits", 6)
|
||||
.build();
|
||||
var bytes = ser(crafted);
|
||||
assertEquals("Digit count range invalid",
|
||||
assertThrows(InvalidObjectException.class, () -> deSer(bytes)).getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure the serial version is updated to the current after de-serialization.
|
||||
@Test
|
||||
void versionTest() {
|
||||
var bytes = ser(new DFBuilder().setVer(-25).build());
|
||||
var df = assertDoesNotThrow(() -> deSer(bytes));
|
||||
assertEquals(4, readField(df, "serialVersionOnStream"));
|
||||
}
|
||||
|
||||
// Ensure strictness value is read properly when it is set.
|
||||
@Test
|
||||
void strictnessTest() {
|
||||
var crafted = new DecimalFormat();
|
||||
crafted.setStrict(true);
|
||||
var bytes = ser(crafted);
|
||||
var df = assertDoesNotThrow(() -> deSer(bytes));
|
||||
assertTrue(df.isStrict());
|
||||
}
|
||||
|
||||
// Ensure invalid grouping sizes are corrected to the default invariant.
|
||||
@Test
|
||||
void groupingSizeTest() {
|
||||
var crafted = new DFBuilder()
|
||||
.set("groupingSize", (byte) -5)
|
||||
.build();
|
||||
var bytes = ser(crafted);
|
||||
var df = assertDoesNotThrow(() -> deSer(bytes));
|
||||
assertEquals(3, df.getGroupingSize());
|
||||
}
|
||||
|
||||
// Ensure a de-serialized dFmt does not throw NPE from missing digitList
|
||||
// later when formatting. i.e. re-construct the transient digitList field
|
||||
@Test // See 4069754, 4067878
|
||||
void digitListTest() {
|
||||
var crafted = new DecimalFormat();
|
||||
var bytes = ser(crafted);
|
||||
var df = assertDoesNotThrow(() -> deSer(bytes));
|
||||
assertDoesNotThrow(() -> df.format(1));
|
||||
assertNotNull(readField(df, "digitList"));
|
||||
}
|
||||
|
||||
// Similar to the previous test, but the original regression test
|
||||
// which was a failure in DateFormat due to DecimalFormat NPE
|
||||
@Test // See 4069754 and 4067878
|
||||
void digitListDateFormatTest() {
|
||||
var fmt = new FooFormat();
|
||||
fmt.now();
|
||||
var bytes = ser(fmt);
|
||||
var ff = (FooFormat) assertDoesNotThrow(() -> deSer0(bytes));
|
||||
assertDoesNotThrow(ff::now);
|
||||
}
|
||||
|
||||
static class FooFormat implements Serializable {
|
||||
DateFormat dateFormat = DateFormat.getDateInstance();
|
||||
|
||||
public String now() {
|
||||
GregorianCalendar calendar = new GregorianCalendar();
|
||||
Date t = calendar.getTime();
|
||||
return dateFormat.format(t);
|
||||
}
|
||||
}
|
||||
|
||||
// Utilities ----
|
||||
|
||||
// Utility to serialize
|
||||
private static byte[] ser(Object obj) {
|
||||
return assertDoesNotThrow(() -> {
|
||||
try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(byteArrayOutputStream)) {
|
||||
oos.writeObject(obj);
|
||||
return byteArrayOutputStream.toByteArray();
|
||||
}
|
||||
}, "Unexpected error during serialization");
|
||||
}
|
||||
|
||||
// Utility to deserialize
|
||||
private static Object deSer0(byte[] bytes) throws IOException, ClassNotFoundException {
|
||||
try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
|
||||
ObjectInputStream ois = new ObjectInputStream(byteArrayInputStream)) {
|
||||
return ois.readObject();
|
||||
}
|
||||
}
|
||||
|
||||
// Convenience cast to DF
|
||||
private static DecimalFormat deSer(byte[] bytes) throws IOException, ClassNotFoundException {
|
||||
return (DecimalFormat) deSer0(bytes);
|
||||
}
|
||||
|
||||
// Utility to deserialize from file in hex format
|
||||
private static Object deSer(String file) throws IOException, ClassNotFoundException {
|
||||
try (InputStream stream = HexDumpReader.getStreamFromHexDump(file);
|
||||
ObjectInputStream ois = new ObjectInputStream(stream)) {
|
||||
return ois.readObject();
|
||||
}
|
||||
}
|
||||
|
||||
// Utility to read a private field
|
||||
private static Object readField(DecimalFormat df, String name) {
|
||||
return assertDoesNotThrow(() -> {
|
||||
var field = DecimalFormat.class.getDeclaredField(name);
|
||||
field.setAccessible(true);
|
||||
return field.get(df);
|
||||
}, "Unexpected error during field reading");
|
||||
}
|
||||
|
||||
// Utility class to build instances of DF via reflection
|
||||
private static class DFBuilder {
|
||||
|
||||
private final DecimalFormat df;
|
||||
|
||||
private DFBuilder() {
|
||||
df = new DecimalFormat();
|
||||
}
|
||||
|
||||
private DFBuilder setVer(Object value) {
|
||||
return set("serialVersionOnStream", value);
|
||||
}
|
||||
|
||||
private DFBuilder setSuper(String field, Object value) {
|
||||
return set(df.getClass().getSuperclass(), field, value);
|
||||
}
|
||||
|
||||
private DFBuilder set(String field, Object value) {
|
||||
return set(df.getClass(), field, value);
|
||||
}
|
||||
|
||||
private DFBuilder set(Class<?> clzz, String field, Object value) {
|
||||
return assertDoesNotThrow(() -> {
|
||||
Field f = clzz.getDeclaredField(field);
|
||||
f.setAccessible(true);
|
||||
f.set(df, value);
|
||||
return this;
|
||||
}, "Unexpected error during reflection setting");
|
||||
}
|
||||
|
||||
private DecimalFormat build() {
|
||||
return df;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Not nested, so that it can be recognized and cast correctly for the 1.1.4 test
|
||||
class CheckDecimalFormat implements Serializable {
|
||||
DecimalFormat _decFormat = (DecimalFormat) NumberFormat.getInstance();
|
||||
public String Update() {
|
||||
Random r = new Random();
|
||||
return _decFormat.format(r.nextDouble());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8212749
|
||||
* @summary test whether input value check for
|
||||
* DecimalFormat.setGroupingSize(int) works correctly.
|
||||
* @run junit/othervm SetGroupingSizeTest
|
||||
*/
|
||||
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
public class SetGroupingSizeTest {
|
||||
|
||||
static Object[][] validGroupingSizes() {
|
||||
return new Object[][] {
|
||||
{ 0 },
|
||||
{ Byte.MAX_VALUE },
|
||||
};
|
||||
}
|
||||
|
||||
static Object[][] invalidGroupingSizes() {
|
||||
return new Object[][] {
|
||||
{ Byte.MIN_VALUE - 1 },
|
||||
{ Byte.MIN_VALUE },
|
||||
{ -1 },
|
||||
{ Byte.MAX_VALUE + 1 },
|
||||
{ Integer.MIN_VALUE },
|
||||
{ Integer.MAX_VALUE },
|
||||
};
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("validGroupingSizes")
|
||||
void test_validGroupingSize(int newVal) {
|
||||
DecimalFormat df = new DecimalFormat();
|
||||
df.setGroupingSize(newVal);
|
||||
assertEquals(newVal, df.getGroupingSize());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("invalidGroupingSizes")
|
||||
void test_invalidGroupingSize(int newVal) {
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
DecimalFormat df = new DecimalFormat();
|
||||
df.setGroupingSize(newVal);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8341445
|
||||
* @summary DFS setters should throw NPE. This ensures that NPE is not thrown
|
||||
* by equals().
|
||||
* @run junit SettersShouldThrowNPETest
|
||||
*/
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
import java.util.Arrays;
|
||||
import java.util.Currency;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
public class SettersShouldThrowNPETest {
|
||||
|
||||
// The public setter methods that should throw NPE
|
||||
private static final List<Method> NPE_SETTERS =
|
||||
Arrays.stream(DecimalFormatSymbols.class.getDeclaredMethods())
|
||||
.filter(m -> Modifier.isPublic(m.getModifiers())
|
||||
&& m.getName().startsWith("set")
|
||||
&& Stream.of(m.getParameterTypes()).noneMatch(Class::isPrimitive))
|
||||
.toList();
|
||||
|
||||
// Non-primitive setters should throw NPE
|
||||
@ParameterizedTest
|
||||
@MethodSource("setters")
|
||||
public void settersThrowNPETest(Method m) {
|
||||
var dfs = new DecimalFormatSymbols();
|
||||
InvocationTargetException e =
|
||||
assertThrows(InvocationTargetException.class, () -> m.invoke(dfs, (Object) null));
|
||||
if (!(e.getCause() instanceof NullPointerException)) {
|
||||
throw new RuntimeException(e.getCause() + " was thrown instead of NPE by : " + m);
|
||||
}
|
||||
}
|
||||
|
||||
// Currency fields are lazy and can be null
|
||||
// Ensure when exposed to users, they are never null
|
||||
@ParameterizedTest
|
||||
@MethodSource("locales")
|
||||
public void lazyCurrencyFieldsTest(Locale locale) {
|
||||
var dfs = new DecimalFormatSymbols(locale);
|
||||
assertDoesNotThrow(() -> dfs.equals(new DecimalFormatSymbols()));
|
||||
assertNotNull(dfs.getCurrency());
|
||||
assertNotNull(dfs.getInternationalCurrencySymbol());
|
||||
assertNotNull(dfs.getCurrencySymbol());
|
||||
}
|
||||
|
||||
// Prior to 8341445, if the international currency symbol was invalid,
|
||||
// the currency attribute was set to null. However, we should not have null
|
||||
// currency fields post initializeCurrency() call. Ensure invalid code
|
||||
// does not update the other fields.
|
||||
@Test
|
||||
public void setInternationalCurrencySymbolFallbackTest() {
|
||||
var code = "fooBarBazQux";
|
||||
// initialize() should provide null for all currency related fields
|
||||
var dfs = new DecimalFormatSymbols(Locale.ROOT);
|
||||
// Load the fallbacks via initCurrency() since the loc is Locale.ROOT
|
||||
dfs.setInternationalCurrencySymbol(code); // set invalid code
|
||||
// Ensure our values are the expected fallbacks, minus the updated intl code
|
||||
assertEquals(Currency.getInstance("XXX"), dfs.getCurrency());
|
||||
assertEquals("\u00A4", dfs.getCurrencySymbol());
|
||||
assertEquals("fooBarBazQux", dfs.getInternationalCurrencySymbol());
|
||||
}
|
||||
|
||||
private static List<Method> setters() {
|
||||
return NPE_SETTERS;
|
||||
}
|
||||
|
||||
private static List<Locale> locales() {
|
||||
return List.of(Locale.ROOT, Locale.US, Locale.forLanguageTag("XXX"));
|
||||
}
|
||||
}
|
||||
439
test/jdk/java/text/Format/DecimalFormat/TieRoundingTest.java
Normal file
439
test/jdk/java/text/Format/DecimalFormat/TieRoundingTest.java
Normal file
|
|
@ -0,0 +1,439 @@
|
|||
/*
|
||||
* Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
*
|
||||
* @bug 7131459 8039915
|
||||
* @summary test various situations of NumberFormat rounding when close to tie
|
||||
* @author Olivier Lagneau
|
||||
* @run main TieRoundingTest
|
||||
*
|
||||
*/
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.DecimalFormat;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.Locale;
|
||||
|
||||
public class TieRoundingTest {
|
||||
|
||||
static int testCounter = 0;
|
||||
static int errorCounter = 0;
|
||||
static boolean allPassed = true;
|
||||
|
||||
static void formatOutputTestDouble(NumberFormat nf,
|
||||
double doubleToTest,
|
||||
String tiePosition,
|
||||
String inputDigits,
|
||||
String expectedOutput) {
|
||||
|
||||
int mfd = nf.getMaximumFractionDigits();
|
||||
RoundingMode rm = nf.getRoundingMode();
|
||||
String result = nf.format(doubleToTest);
|
||||
|
||||
if (!result.equals(expectedOutput)) {
|
||||
System.out.println();
|
||||
System.out.println("========================================");
|
||||
System.out.println("***Failure : error formatting value from string : " +
|
||||
inputDigits);
|
||||
System.out.println("NumberFormat pattern is : " +
|
||||
((DecimalFormat ) nf).toPattern());
|
||||
System.out.println("Maximum number of fractional digits : " + mfd);
|
||||
System.out.println("Fractional rounding digit : " + (mfd + 1));
|
||||
System.out.println("Position of value relative to tie : " + tiePosition);
|
||||
System.out.println("Rounding Mode : " + rm);
|
||||
System.out.println("BigDecimal output : " +
|
||||
new BigDecimal(doubleToTest).toString());
|
||||
System.out.println("FloatingDecimal output : " + doubleToTest);
|
||||
System.out.println(
|
||||
"Error. Formatted result different from expected." +
|
||||
"\nExpected output is : \"" + expectedOutput + "\"" +
|
||||
"\nFormated output is : \"" + result + "\"");
|
||||
System.out.println("========================================");
|
||||
System.out.println();
|
||||
|
||||
errorCounter++;
|
||||
allPassed = false;
|
||||
} else {
|
||||
testCounter++;
|
||||
System.out.println("\nSuccess for double value : " + doubleToTest + " :");
|
||||
System.out.println(" Input digits :" + inputDigits +
|
||||
", BigDecimal value : " +
|
||||
new BigDecimal(doubleToTest).toString());
|
||||
System.out.print(" Rounding mode: " + rm);
|
||||
System.out.print(", fract digits : " + mfd);
|
||||
System.out.print(", position : " + tiePosition + " tie");
|
||||
System.out.print(", result : " + result);
|
||||
System.out.println(", expected : " + expectedOutput);
|
||||
}
|
||||
}
|
||||
|
||||
static void formatOutputTestLong(NumberFormat nf,
|
||||
long longToTest,
|
||||
String tiePosition,
|
||||
String inputDigits,
|
||||
String expectedOutput) {
|
||||
|
||||
int mfd = nf.getMaximumFractionDigits();
|
||||
RoundingMode rm = nf.getRoundingMode();
|
||||
String result = nf.format(longToTest);
|
||||
|
||||
if (!result.equals(expectedOutput)) {
|
||||
System.out.println();
|
||||
System.out.println("========================================");
|
||||
System.out.println("***Failure : error formatting value from string : " +
|
||||
inputDigits);
|
||||
System.out.println("NumberFormat pattern is : " +
|
||||
((DecimalFormat ) nf).toPattern());
|
||||
System.out.println("Maximum number of fractional digits : " + mfd);
|
||||
System.out.println("Fractional rounding digit : " + (mfd + 1));
|
||||
System.out.println("Position of value relative to tie : " + tiePosition);
|
||||
System.out.println("Rounding Mode : " + rm);
|
||||
System.out.println(
|
||||
"Error. Formatted result different from expected." +
|
||||
"\nExpected output is : \"" + expectedOutput + "\"" +
|
||||
"\nFormated output is : \"" + result + "\"");
|
||||
System.out.println("========================================");
|
||||
System.out.println();
|
||||
|
||||
errorCounter++;
|
||||
allPassed = false;
|
||||
} else {
|
||||
testCounter++;
|
||||
System.out.print("Success. Long input :" + inputDigits);
|
||||
System.out.print(", rounding : " + rm);
|
||||
System.out.print(", fract digits : " + mfd);
|
||||
System.out.print(", tie position : " + tiePosition);
|
||||
System.out.println(", expected : " + expectedOutput);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void formatOutputTestObject(NumberFormat nf,
|
||||
Object someNumber,
|
||||
String tiePosition,
|
||||
String inputDigits,
|
||||
String expectedOutput) {
|
||||
|
||||
int mfd = nf.getMaximumFractionDigits();
|
||||
RoundingMode rm = nf.getRoundingMode();
|
||||
String result = nf.format(someNumber);
|
||||
|
||||
if (!result.equals(expectedOutput)) {
|
||||
System.out.println();
|
||||
System.out.println("========================================");
|
||||
System.out.println("***Failure : error formatting value from string : " +
|
||||
inputDigits);
|
||||
System.out.println("NumberFormat pattern is : " +
|
||||
((DecimalFormat ) nf).toPattern());
|
||||
System.out.println("Maximum number of fractional digits : " + mfd);
|
||||
System.out.println("Fractional rounding digit : " + (mfd + 1));
|
||||
System.out.println("Position of value relative to tie : " + tiePosition);
|
||||
System.out.println("Rounding Mode : " + rm);
|
||||
System.out.println("Number self output representation: " + someNumber);
|
||||
System.out.println(
|
||||
"Error. Formatted result different from expected." +
|
||||
"\nExpected output is : \"" + expectedOutput + "\"" +
|
||||
"\nFormated output is : \"" + result + "\"");
|
||||
System.out.println("========================================");
|
||||
System.out.println();
|
||||
|
||||
errorCounter++;
|
||||
allPassed = false;
|
||||
} else {
|
||||
testCounter++;
|
||||
System.out.print("Success. Number input :" + inputDigits);
|
||||
System.out.print(", rounding : " + rm);
|
||||
System.out.print(", fract digits : " + mfd);
|
||||
System.out.print(", tie position : " + tiePosition);
|
||||
System.out.println(", expected : " + expectedOutput);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
// The 3 HALF_* rounding modes are impacted by bugs 7131459, 8039915.
|
||||
// So we do not test the other rounding modes.
|
||||
RoundingMode[] roundingModes = {
|
||||
RoundingMode.HALF_DOWN,
|
||||
RoundingMode.HALF_EVEN,
|
||||
RoundingMode.HALF_UP
|
||||
};
|
||||
|
||||
// Precise the relative position of input value against its closest tie.
|
||||
// The double values tested below for 3 and 5 fractional digits must follow
|
||||
// this scheme (position toward tie).
|
||||
String[] tieRelativePositions = {
|
||||
"below", "exact", "above",
|
||||
"below", "exact", "above",
|
||||
"below", "exact", "above",
|
||||
"below", "above", "above",
|
||||
"below", "below", "above",
|
||||
"below", "exact", "above"
|
||||
};
|
||||
|
||||
// =============== Testing double (and thus float) value cases =========
|
||||
|
||||
System.out.println("\n===== testing 3 digits rounding position =====");
|
||||
double[] values3FractDigits = {
|
||||
// unimpacting values close to tie, with less than 3 input fract digits
|
||||
1.115d, 1.125d, 1.135d,
|
||||
// HALF_* impacting close to tie values covering all 6 tie cases
|
||||
0.3115d, 0.3125d, 0.3135d,
|
||||
0.6865d, 0.6875d, 0.6885d,
|
||||
// specific HALF_UP close to tie values
|
||||
0.3124d, 0.3126d, 0.3128d,
|
||||
// specific HALF_DOWN close to tie values
|
||||
0.6864d, 0.6865d, 0.6868d,
|
||||
// unimpacting values close to tie, with more than 3 input fract digits
|
||||
1.46885d, 2.46875d, 1.46865d
|
||||
};
|
||||
|
||||
String[] inputs3FractDigits = {
|
||||
"1.115d", "1.125d", "1.135d",
|
||||
"0.3115d", "0.3125d", "0.3135d",
|
||||
"0.6865d", "0.6875d", "0.6885d",
|
||||
"0.3124d", "0.3126d", "0.3128d",
|
||||
"0.6864d", "0.6865d", "0.6868d",
|
||||
"1.46885d", "2.46875d", "1.46865d"
|
||||
};
|
||||
|
||||
String[][] expected3FractDigits = {
|
||||
{"1.115", "1.125", "1.135",
|
||||
"0.311", "0.312", "0.314",
|
||||
"0.686", "0.687", "0.689",
|
||||
"0.312", "0.313", "0.313",
|
||||
"0.686", "0.686", "0.687",
|
||||
"1.469", "2.469", "1.469"
|
||||
},
|
||||
{"1.115", "1.125", "1.135",
|
||||
"0.311", "0.312", "0.314",
|
||||
"0.686", "0.688", "0.689",
|
||||
"0.312", "0.313", "0.313",
|
||||
"0.686", "0.686", "0.687",
|
||||
"1.469", "2.469", "1.469"
|
||||
},
|
||||
{"1.115", "1.125", "1.135",
|
||||
"0.311", "0.313", "0.314",
|
||||
"0.686", "0.688", "0.689",
|
||||
"0.312", "0.313", "0.313",
|
||||
"0.686", "0.686", "0.687",
|
||||
"1.469", "2.469", "1.469"
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
for (int r = 0; r < roundingModes.length; r++) {
|
||||
NumberFormat dfDefault = NumberFormat.getInstance(Locale.US);
|
||||
RoundingMode rmode = roundingModes[r];
|
||||
dfDefault.setRoundingMode(rmode);
|
||||
System.out.println("\n----- Now checking " + rmode +
|
||||
" rounding mode -----");
|
||||
|
||||
for (int i = 0; i < values3FractDigits.length; i++) {
|
||||
double d = values3FractDigits[i];
|
||||
String tiePosition = tieRelativePositions[i];
|
||||
String input = inputs3FractDigits[i];
|
||||
String expected = expected3FractDigits[r][i];
|
||||
|
||||
formatOutputTestDouble(dfDefault, d, tiePosition, input, expected);
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("\n===== testing 5 digits rounding position =====");
|
||||
double[] values5FractDigits = {
|
||||
// unimpacting values close to tie, with less than 5 input fract digits
|
||||
1.3135d, 1.3125d, 1.3115d,
|
||||
// HALF_* impacting values close to tie, covering all 6 cases
|
||||
1.328115d, 1.328125d, 1.328135d,
|
||||
1.796865d, 1.796875d, 1.796885d,
|
||||
// specific HALF_UP close to tie values
|
||||
1.328124d, 1.798876d, 1.796889d,
|
||||
// specific HALF_DOWN close to tie values
|
||||
1.328114d, 1.796865d, 1.328138d,
|
||||
// unimpacting values close to tie, with more than 5 input fract digits
|
||||
1.3281149999999d, 1.75390625d, 1.7968750000001d
|
||||
};
|
||||
|
||||
String[] inputs5FractDigits = {
|
||||
"1.3135d", "1.3125d", "1.3115d",
|
||||
"1.328115d", "1.328125d", "1.328135d",
|
||||
"1.796865d", "1.796875d", "1.796885d",
|
||||
"1.328124d", "1.798876d", "1.796889d",
|
||||
"1.328114d", "1.796865d", "1.328138d",
|
||||
"1.3281149999999d", "1.75390625d", "1.7968750000001d"
|
||||
};
|
||||
|
||||
String[][] expected5FractDigits = {
|
||||
{"1.3135", "1.3125", "1.3115",
|
||||
"1.32811", "1.32812", "1.32814",
|
||||
"1.79686", "1.79687", "1.79689",
|
||||
"1.32812", "1.79888", "1.79689",
|
||||
"1.32811", "1.79686", "1.32814",
|
||||
"1.32811", "1.75391", "1.79688"
|
||||
},
|
||||
{"1.3135", "1.3125", "1.3115",
|
||||
"1.32811", "1.32812", "1.32814",
|
||||
"1.79686", "1.79688", "1.79689",
|
||||
"1.32812", "1.79888", "1.79689",
|
||||
"1.32811", "1.79686", "1.32814",
|
||||
"1.32811", "1.75391", "1.79688"
|
||||
},
|
||||
{"1.3135", "1.3125", "1.3115",
|
||||
"1.32811", "1.32813", "1.32814",
|
||||
"1.79686", "1.79688", "1.79689",
|
||||
"1.32812", "1.79888", "1.79689",
|
||||
"1.32811", "1.79686", "1.32814",
|
||||
"1.32811", "1.75391", "1.79688"
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
for (int r = 0; r < roundingModes.length; r++) {
|
||||
DecimalFormat df5 = (DecimalFormat) NumberFormat.getInstance(Locale.US);
|
||||
RoundingMode rmode = roundingModes[r];
|
||||
df5.setRoundingMode(rmode);
|
||||
System.out.println("\n----- Now checking " + rmode +
|
||||
" rounding mode -----");
|
||||
df5.applyPattern("#,###.#####");
|
||||
|
||||
for (int i = 0; i < values5FractDigits.length; i++) {
|
||||
double d = values5FractDigits[i];
|
||||
String tiePosition = tieRelativePositions[i];
|
||||
String input = inputs5FractDigits[i];
|
||||
String expected = expected5FractDigits[r][i];
|
||||
|
||||
formatOutputTestDouble(df5, d, tiePosition, input, expected);
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== Testing long value cases ====================
|
||||
|
||||
System.out.println("\n===== testing long values =====");
|
||||
long l = 123456789012345L;
|
||||
DecimalFormat dfLong = (DecimalFormat) NumberFormat.getInstance(Locale.US);
|
||||
String tiePosition = "exact";
|
||||
String input = "123456789012345L";
|
||||
String expected = "123,456,789,012,345";
|
||||
String result = dfLong.format(l);
|
||||
formatOutputTestLong(dfLong, l, tiePosition, input, expected);
|
||||
|
||||
dfLong.applyPattern("0.###E0");
|
||||
expected = "1.235E14";
|
||||
formatOutputTestLong(dfLong, l, tiePosition, input, expected);
|
||||
|
||||
l = 123450000000000L;
|
||||
input = "123450000000000L";
|
||||
expected = "1.234E14";
|
||||
formatOutputTestLong(dfLong, l, tiePosition, input, expected);
|
||||
|
||||
l = 987750000000000L;
|
||||
input = "987750000000000L";
|
||||
expected = "9.878E14";
|
||||
formatOutputTestLong(dfLong, l, tiePosition, input, expected);
|
||||
|
||||
dfLong.applyPattern("#,###.0E0");
|
||||
l = 987755000000000L;
|
||||
input = "987755000000000L";
|
||||
expected = "987.76E12";
|
||||
|
||||
formatOutputTestLong(dfLong, l, tiePosition, input, expected);
|
||||
|
||||
|
||||
// ================= Testing BigInteger value cases =================
|
||||
|
||||
System.out.println("\n===== testing BigInteger values =====");
|
||||
String stringValue = "12345678901234567890123456789012345";
|
||||
BigInteger bi = new BigInteger(stringValue);
|
||||
DecimalFormat dfBig = (DecimalFormat) NumberFormat.getInstance(Locale.US);
|
||||
tiePosition = "exact";
|
||||
input = stringValue;
|
||||
expected = "12,345,678,901,234,567,890,123,456,789,012,345";
|
||||
formatOutputTestObject(dfBig, bi, tiePosition, input, expected);
|
||||
|
||||
dfBig.applyPattern("0.###E0");
|
||||
expected = "1.235E34";
|
||||
formatOutputTestObject(dfBig, bi, tiePosition, input, expected);
|
||||
|
||||
stringValue = "12345000000000000000000000000000000";
|
||||
input = stringValue;
|
||||
bi = new BigInteger(stringValue);
|
||||
expected = "1.234E34";
|
||||
formatOutputTestObject(dfBig, bi, tiePosition, input, expected);
|
||||
|
||||
stringValue = "12345000000000000000000000000000001";
|
||||
input = stringValue;
|
||||
bi = new BigInteger(stringValue);
|
||||
expected = "1.235E34";
|
||||
formatOutputTestObject(dfBig, bi, tiePosition, input, expected);
|
||||
|
||||
stringValue = "98755000000000000000000000000000000";
|
||||
input = stringValue;
|
||||
bi = new BigInteger(stringValue);
|
||||
expected = "9.876E34";
|
||||
formatOutputTestObject(dfBig, bi, tiePosition, input, expected);
|
||||
|
||||
dfLong.applyPattern("#,###.0E0");
|
||||
stringValue = "98775500000000000000000000000000000";
|
||||
input = stringValue;
|
||||
expected = "987.76E34";
|
||||
|
||||
// =============== Testing BigDecimal value cases ================
|
||||
|
||||
System.out.println("\n===== testing BigDecimal values =====");
|
||||
dfBig = (DecimalFormat) NumberFormat.getInstance(Locale.US);
|
||||
|
||||
stringValue = "0.68850000000000000088817841970012523233890533447265625";
|
||||
BigDecimal bd = new BigDecimal(stringValue);
|
||||
tiePosition = "exact";
|
||||
input = stringValue;
|
||||
expected = "0.689";
|
||||
formatOutputTestObject(dfBig, bd, tiePosition, input, expected);
|
||||
|
||||
stringValue = "0.31149999999999999911182158029987476766109466552734375";
|
||||
bd = new BigDecimal(stringValue);
|
||||
dfBig.applyPattern("#,##0.####");
|
||||
tiePosition = "exact";
|
||||
input = stringValue;
|
||||
expected = "0.3115";
|
||||
formatOutputTestObject(dfBig, bd, tiePosition, input, expected);
|
||||
|
||||
// ==================== Printing results and exiting ===================
|
||||
|
||||
System.out.println();
|
||||
System.out.println("==> " + testCounter + " tests passed successfully");
|
||||
System.out.println("==> " + errorCounter + " tests failed");
|
||||
|
||||
System.out.println();
|
||||
if (allPassed) {
|
||||
System.out.println(
|
||||
"Success in formating all the values with the given parameters");
|
||||
} else {
|
||||
String s = "Test failed with " + errorCounter + " formating error(s).";
|
||||
System.out.println(s);
|
||||
throw new RuntimeException(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8282929 8326908
|
||||
* @summary Verify DecimalFormat::toLocalizedPattern correctness.
|
||||
* @run junit ToLocalizedPatternTest
|
||||
*/
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
import java.util.Locale;
|
||||
|
||||
public class ToLocalizedPatternTest {
|
||||
private static final char MONETARY_GROUPING = 'g';
|
||||
private static final char MONETARY_DECIMAL = 'd';
|
||||
|
||||
// Verifies that the toLocalizedPattern() method correctly returns
|
||||
// monetary symbols for a currency formatter.
|
||||
@Test
|
||||
public void monetarySymbolsTest() {
|
||||
var dfs = new DecimalFormatSymbols(Locale.US);
|
||||
|
||||
// Customize the decimal format symbols
|
||||
dfs.setMonetaryGroupingSeparator(MONETARY_GROUPING);
|
||||
dfs.setMonetaryDecimalSeparator(MONETARY_DECIMAL);
|
||||
|
||||
// create a currency formatter
|
||||
var cf = (DecimalFormat)DecimalFormat.getCurrencyInstance(Locale.US);
|
||||
cf.setDecimalFormatSymbols(dfs);
|
||||
|
||||
// check
|
||||
assertEquals(cf.toLocalizedPattern(),
|
||||
cf.toPattern()
|
||||
.replace(',', MONETARY_GROUPING)
|
||||
.replace('.', MONETARY_DECIMAL));
|
||||
}
|
||||
|
||||
// Verify some common symbols are enforced with the DFS
|
||||
@Test
|
||||
public void useDFSWhenLocalizedTest() {
|
||||
DecimalFormatSymbols dfs = new DecimalFormatSymbols();
|
||||
dfs.setGroupingSeparator('a');
|
||||
dfs.setDecimalSeparator('b');
|
||||
dfs.setDigit('c');
|
||||
dfs.setZeroDigit('d');
|
||||
// Create a DecimalFormat that utilizes the above symbols
|
||||
DecimalFormat dFmt = new DecimalFormat("###,##0.###", dfs);
|
||||
assertEquals("caccdbccc", dFmt.toLocalizedPattern());
|
||||
}
|
||||
}
|
||||
130
test/jdk/java/text/Format/DecimalFormat/ToPatternTest.java
Normal file
130
test/jdk/java/text/Format/DecimalFormat/ToPatternTest.java
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8326908
|
||||
* @summary Verify DecimalFormat::toPattern correctness.
|
||||
* @run junit ToPatternTest
|
||||
*/
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class ToPatternTest {
|
||||
|
||||
// DecimalFormat constant
|
||||
private static final int DOUBLE_FRACTION_DIGITS = 340;
|
||||
|
||||
// Ensure that toPattern() provides the correct amount of minimum
|
||||
// and maximum digits for integer/fraction.
|
||||
@ParameterizedTest
|
||||
@MethodSource("minMaxDigits")
|
||||
public void basicTest(int maxInt, int minInt, int maxFrac, int minFrac) {
|
||||
DecimalFormat dFmt = new DecimalFormat();
|
||||
|
||||
dFmt.setMaximumIntegerDigits(maxInt);
|
||||
dFmt.setMinimumIntegerDigits(minInt);
|
||||
dFmt.setMaximumFractionDigits(maxFrac);
|
||||
dFmt.setMinimumFractionDigits(minFrac);
|
||||
|
||||
// Non-localized separator always uses '.'
|
||||
String[] patterns = dFmt.toPattern().split("\\.");
|
||||
assertEquals(2, patterns.length,
|
||||
dFmt.toPattern() + " should be split into an integer/fraction portion");
|
||||
String integerPattern = patterns[0];
|
||||
String fractionPattern = patterns[1];
|
||||
|
||||
// Count # and 0 explicitly (since there are grouping symbols)
|
||||
assertEquals(integerPattern.chars().filter(ch -> ch == '0').count() +
|
||||
integerPattern.chars().filter(ch -> ch == '#').count(),
|
||||
Math.max(dFmt.getGroupingSize(), dFmt.getMinimumIntegerDigits()) + 1);
|
||||
assertEquals(integerPattern.chars().filter(ch -> ch == '0').count(), dFmt.getMinimumIntegerDigits());
|
||||
assertEquals(fractionPattern.length(), dFmt.getMaximumFractionDigits());
|
||||
assertEquals(fractionPattern.chars().filter(ch -> ch == '0').count(), dFmt.getMinimumFractionDigits());
|
||||
}
|
||||
|
||||
// General and edge cases for the min and max Integer/Fraction digits
|
||||
private static Stream<Arguments> minMaxDigits() {
|
||||
return Stream.of(
|
||||
Arguments.of(10, 5, 10, 5),
|
||||
Arguments.of(0, 0, 1, 1),
|
||||
Arguments.of(1, 1, 1, 1),
|
||||
Arguments.of(5, 5, 5, 5),
|
||||
Arguments.of(5, 10, 5, 10),
|
||||
Arguments.of(333, 27, 409, 3)
|
||||
);
|
||||
}
|
||||
|
||||
// Ensure that a NegativePattern is explicitly produced when required.
|
||||
@Test
|
||||
public void negativeSubPatternTest() {
|
||||
DecimalFormat dFmt = new DecimalFormat();
|
||||
dFmt.setPositivePrefix("foo");
|
||||
dFmt.setPositiveSuffix("bar");
|
||||
dFmt.setNegativePrefix("baz");
|
||||
dFmt.setNegativeSuffix("qux");
|
||||
|
||||
String[] patterns = dFmt.toPattern().split(";");
|
||||
assertEquals(2, patterns.length,
|
||||
"There should be a positivePattern and negativePattern");
|
||||
String positivePattern = patterns[0];
|
||||
String negativePattern = patterns[1];
|
||||
|
||||
assertTrue(positivePattern.startsWith(dFmt.getPositivePrefix()));
|
||||
assertTrue(positivePattern.endsWith(dFmt.getPositiveSuffix()));
|
||||
assertTrue(negativePattern.startsWith(dFmt.getNegativePrefix()));
|
||||
assertTrue(negativePattern.endsWith(dFmt.getNegativeSuffix()));
|
||||
}
|
||||
|
||||
// 8326908: Verify that an empty pattern DecimalFormat does not throw an
|
||||
// OutOfMemoryError when toPattern() is invoked. Behavioral change of
|
||||
// MAXIMUM_INTEGER_DIGITS replaced with DOUBLE_FRACTION_DIGITS for empty
|
||||
// pattern initialization.
|
||||
@Test
|
||||
public void emptyStringPatternTest() {
|
||||
DecimalFormat empty = new DecimalFormat("");
|
||||
// Verify new maximum fraction digits value
|
||||
assertEquals(DOUBLE_FRACTION_DIGITS, empty.getMaximumFractionDigits());
|
||||
// Verify no OOME for empty pattern
|
||||
assertDoesNotThrow(empty::toPattern);
|
||||
// Check toString for coverage, as it invokes toPattern
|
||||
assertDoesNotThrow(empty::toString);
|
||||
}
|
||||
|
||||
// Verify that only the last grouping interval is used for the grouping size.
|
||||
@Test
|
||||
public void groupingSizeTest() {
|
||||
assertEquals(22,
|
||||
new DecimalFormat( "###,####,"+"#".repeat(22)).getGroupingSize());
|
||||
}
|
||||
}
|
||||
56
test/jdk/java/text/Format/DecimalFormat/ToStringTest.java
Normal file
56
test/jdk/java/text/Format/DecimalFormat/ToStringTest.java
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8321545
|
||||
* @summary Ensure value returned by overridden toString method is as expected
|
||||
* @run junit ToStringTest
|
||||
*/
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class ToStringTest {
|
||||
|
||||
// Check a normal expected value. There is no null locale test as
|
||||
// DecimalFormatSymbols will throw an exception when created with a null locale.
|
||||
@Test
|
||||
public void expectedValueTest() {
|
||||
String expectedStr =
|
||||
"DecimalFormat [locale: \"English (Canada)\", pattern: \"foo#00.00bar\"]\n";
|
||||
var d = new DecimalFormat("foo#00.00bar", new DecimalFormatSymbols(Locale.CANADA));
|
||||
assertEquals(expectedStr, d.toString());
|
||||
|
||||
String expectedStr2 =
|
||||
"DecimalFormat [locale: \"English (Canada)\", pattern: \"#,##0.###\"]\n";
|
||||
var d2 = NumberFormat.getInstance(Locale.CANADA);
|
||||
assertEquals(expectedStr2, d2.toString());
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue