Path: blob/master/test/jdk/java/text/Format/NumberFormat/NumberRoundTrip.java
41152 views
/*1* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @summary round trip test NumberFormat26* @library /java/text/testlib27* @key randomness28*/2930import java.text.*;31import java.util.*;3233/**34* This class tests the round-trip behavior of NumberFormat, DecimalFormat, and DigitList.35* Round-trip behavior is tested by taking a numeric value and formatting it, then36* parsing the resulting string, and comparing this result with the original value.37* Two tests are applied: String preservation, and numeric preservation. String38* preservation is exact; numeric preservation is not. However, numeric preservation39* should extend to the few least-significant bits.40* //bug47241*/42public class NumberRoundTrip extends IntlTest {43static final boolean STRING_COMPARE = true;44static final boolean EXACT_NUMERIC_COMPARE = false;45static final double MAX_ERROR = 1e-14;46static boolean DEBUG = false;47static double max_numeric_error = 0;48static double min_numeric_error = 1;4950String localeName, formatName;5152public static void main(String[] args) throws Exception {53if (args.length > 0 && args[0].equals("-debug")) {54DEBUG = true;55String[] newargs = new String[args.length - 1];56System.arraycopy(args, 1, newargs, 0, newargs.length);57args = newargs;58}59new NumberRoundTrip().run(args);60}6162public void TestNumberFormatRoundTrip() {63logln("Default Locale");64localeName = "Default Locale";65formatName = "getInstance";66doTest(NumberFormat.getInstance());67formatName = "getNumberInstance";68doTest(NumberFormat.getNumberInstance());69formatName = "getCurrencyInstance";70doTest(NumberFormat.getCurrencyInstance());71formatName = "getPercentInstance";72doTest(NumberFormat.getPercentInstance());7374Locale[] loc = NumberFormat.getAvailableLocales();75for (int i=0; i<loc.length; ++i) {76logln(loc[i].getDisplayName());77localeName = loc[i].toString();78formatName = "getInstance";79doTest(NumberFormat.getInstance(loc[i]));80formatName = "getNumberInstance";81doTest(NumberFormat.getNumberInstance(loc[i]));82formatName = "getCurrencyInstance";83doTest(NumberFormat.getCurrencyInstance(loc[i]));84formatName = "getPercentInstance";85doTest(NumberFormat.getPercentInstance(loc[i]));86}8788logln("Numeric error " +89min_numeric_error + " to " +90max_numeric_error);91}9293public void doTest(NumberFormat fmt) {94doTest(fmt, Double.NaN);95doTest(fmt, Double.POSITIVE_INFINITY);96doTest(fmt, Double.NEGATIVE_INFINITY);9798doTest(fmt, 500);99doTest(fmt, 0);100doTest(fmt, 5555555555555555L);101doTest(fmt, 55555555555555555L);102doTest(fmt, 9223372036854775807L);103doTest(fmt, 9223372036854775808.0);104doTest(fmt, -9223372036854775808L);105doTest(fmt, -9223372036854775809.0);106107for (int i=0; i<2; ++i) {108doTest(fmt, randomDouble(1));109doTest(fmt, randomDouble(10000));110doTest(fmt, Math.floor(randomDouble(10000)));111doTest(fmt, randomDouble(1e50));112doTest(fmt, randomDouble(1e-50));113doTest(fmt, randomDouble(1e100));114// The use of double d such that isInfinite(100d) causes the115// numeric test to fail with percent formats (bug 4266589).116// Largest double s.t. 100d < Inf: d=1.7976931348623156E306117doTest(fmt, randomDouble(1e306));118doTest(fmt, randomDouble(1e-323));119doTest(fmt, randomDouble(1e-100));120}121}122123/**124* Return a random value from -range..+range.125*/126public double randomDouble(double range) {127double a = Math.random();128return (2.0 * range * a) - range;129}130131public void doTest(NumberFormat fmt, double value) {132doTest(fmt, Double.valueOf(value));133}134135public void doTest(NumberFormat fmt, long value) {136doTest(fmt, Long.valueOf(value));137}138139static double proportionalError(Number a, Number b) {140double aa = a.doubleValue(), bb = b.doubleValue();141double error = aa - bb;142if (aa != 0 && bb != 0) error /= aa;143return Math.abs(error);144}145146public void doTest(NumberFormat fmt, Number value) {147fmt.setMaximumFractionDigits(Integer.MAX_VALUE);148String s = fmt.format(value), s2 = null;149Number n = null;150String err = "";151try {152if (DEBUG) logln(" " + value + " F> " + escape(s));153n = fmt.parse(s);154if (DEBUG) logln(" " + escape(s) + " P> " + n);155s2 = fmt.format(n);156if (DEBUG) logln(" " + n + " F> " + escape(s2));157158if (STRING_COMPARE) {159if (!s.equals(s2)) {160if (fmt instanceof DecimalFormat) {161logln("Text mismatch: expected: " + s + ", got: " + s2 + " --- Try BigDecimal parsing.");162((DecimalFormat)fmt).setParseBigDecimal(true);163n = fmt.parse(s);164if (DEBUG) logln(" " + escape(s) + " P> " + n);165s2 = fmt.format(n);166if (DEBUG) logln(" " + n + " F> " + escape(s2));167((DecimalFormat)fmt).setParseBigDecimal(false);168169if (!s.equals(s2)) {170err = "STRING ERROR(DecimalFormat): ";171}172} else {173err = "STRING ERROR(NumberFormat): ";174}175}176}177178if (EXACT_NUMERIC_COMPARE) {179if (value.doubleValue() != n.doubleValue()) {180err += "NUMERIC ERROR: ";181}182} else {183// Compute proportional error184double error = proportionalError(value, n);185186if (error > MAX_ERROR) {187err += "NUMERIC ERROR " + error + ": ";188}189190if (error > max_numeric_error) max_numeric_error = error;191if (error < min_numeric_error) min_numeric_error = error;192}193194String message = value + typeOf(value) + " F> " +195escape(s) + " P> " +196n + typeOf(n) + " F> " +197escape(s2);198if (err.length() > 0) {199errln("*** " + err + " with " +200formatName + " in " + localeName +201" " + message);202} else {203logln(message);204}205} catch (ParseException e) {206errln("*** " + e.toString() + " with " +207formatName + " in " + localeName);208}209}210211static String typeOf(Number n) {212if (n instanceof Long) return " Long";213if (n instanceof Double) return " Double";214return " Number";215}216217static String escape(String s) {218StringBuffer buf = new StringBuffer();219for (int i=0; i<s.length(); ++i) {220char c = s.charAt(i);221if (c < (char)0xFF) {222buf.append(c);223} else {224buf.append("\\U");225buf.append(Integer.toHexString((c & 0xF000) >> 12));226buf.append(Integer.toHexString((c & 0x0F00) >> 8));227buf.append(Integer.toHexString((c & 0x00F0) >> 4));228buf.append(Integer.toHexString(c & 0x000F));229}230}231return buf.toString();232}233}234235236