/* * Copyright (c) 1997, 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 * @summary round trip test NumberFormat * @key randomness * @run junit NumberRoundTrip */ import java.text.DecimalFormat; import java.text.NumberFormat; import java.text.ParseException; import java.util.Locale; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.fail; /** * This class tests the round-trip behavior of NumberFormat, DecimalFormat, and DigitList. * Round-trip behavior is tested by taking a numeric value and formatting it, then * parsing the resulting string, and comparing this result with the original value. * Two tests are applied: String preservation, and numeric preservation. String * preservation is exact; numeric preservation is not. However, numeric preservation * should extend to the few least-significant bits. * //bug472 */ public class NumberRoundTrip { static final boolean STRING_COMPARE = true; static final boolean EXACT_NUMERIC_COMPARE = false; static final double MAX_ERROR = 1e-14; static double max_numeric_error = 0; static double min_numeric_error = 1; String localeName, formatName; @Test public void TestNumberFormatRoundTrip() { System.out.println("Default Locale"); localeName = "Default Locale"; formatName = "getInstance"; doTest(NumberFormat.getInstance()); formatName = "getNumberInstance"; doTest(NumberFormat.getNumberInstance()); formatName = "getCurrencyInstance"; doTest(NumberFormat.getCurrencyInstance()); formatName = "getPercentInstance"; doTest(NumberFormat.getPercentInstance()); Locale[] loc = NumberFormat.getAvailableLocales(); for (int i=0; i " + escape(s)); n = fmt.parse(s); System.out.println(" " + escape(s) + " P> " + n); s2 = fmt.format(n); System.out.println(" " + n + " F> " + escape(s2)); if (STRING_COMPARE) { if (!s.equals(s2)) { if (fmt instanceof DecimalFormat) { System.out.println("Text mismatch: expected: " + s + ", got: " + s2 + " --- Try BigDecimal parsing."); ((DecimalFormat)fmt).setParseBigDecimal(true); n = fmt.parse(s); System.out.println(" " + escape(s) + " P> " + n); s2 = fmt.format(n); System.out.println(" " + n + " F> " + escape(s2)); ((DecimalFormat)fmt).setParseBigDecimal(false); if (!s.equals(s2)) { err = "STRING ERROR(DecimalFormat): "; } } else { err = "STRING ERROR(NumberFormat): "; } } } if (EXACT_NUMERIC_COMPARE) { if (value.doubleValue() != n.doubleValue()) { err += "NUMERIC ERROR: "; } } else { // Compute proportional error double error = proportionalError(value, n); if (error > MAX_ERROR) { err += "NUMERIC ERROR " + error + ": "; } if (error > max_numeric_error) max_numeric_error = error; if (error < min_numeric_error) min_numeric_error = error; } String message = value + typeOf(value) + " F> " + escape(s) + " P> " + n + typeOf(n) + " F> " + escape(s2); if (err.length() > 0) { fail("*** " + err + " with " + formatName + " in " + localeName + " " + message); } else { System.out.println(message); } } catch (ParseException e) { fail("*** " + e.toString() + " with " + formatName + " in " + localeName); } } static String typeOf(Number n) { if (n instanceof Long) return " Long"; if (n instanceof Double) return " Double"; return " Number"; } static String escape(String s) { StringBuffer buf = new StringBuffer(); for (int i=0; i> 12)); buf.append(Integer.toHexString((c & 0x0F00) >> 8)); buf.append(Integer.toHexString((c & 0x00F0) >> 4)); buf.append(Integer.toHexString(c & 0x000F)); } } return buf.toString(); } }