--- /dev/null 2016-05-17 12:01:17.473251102 +0900 +++ new/test/java/text/Format/NumberFormat/NumberRegression.java 2016-05-23 13:58:02.103788922 +0900 @@ -0,0 +1,1824 @@ +/* + * Copyright (c) 1997, 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 4052223 4059870 4061302 4062486 4066646 4068693 4070798 4071005 4071014 + * 4071492 4071859 4074454 4074620 4075713 4083018 4086575 4087244 4087245 + * 4087251 4087535 4088161 4088503 4090489 4090504 4092480 4092561 4095713 + * 4098741 4099404 4101481 4106658 4106662 4106664 4108738 4110936 4122840 + * 4125885 4134034 4134300 4140009 4141750 4145457 4147295 4147706 4162198 + * 4162852 4167494 4170798 4176114 4179818 4185761 4212072 4212073 4216742 + * 4217661 4243011 4243108 4330377 4233840 4241880 4833877 8008577 + * @summary Regression tests for NumberFormat and associated classes + * @library /java/text/testlib + * @modules java.base/sun.util.resources + * @compile -XDignore.symbol.file NumberRegression.java + * @run main/othervm -Djava.locale.providers=COMPAT,SPI NumberRegression + */ + +/* +(C) Copyright Taligent, Inc. 1996 - All Rights Reserved +(C) Copyright IBM Corp. 1996 - All Rights Reserved + + The original version of this source code and documentation is copyrighted and +owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These materials are +provided under terms of a License Agreement between Taligent and Sun. This +technology is protected by multiple US and International patents. This notice and +attribution to Taligent may not be removed. + Taligent is a registered trademark of Taligent, Inc. +*/ + +import java.text.*; +import java.util.*; +import java.math.BigDecimal; +import java.io.*; +import java.math.BigInteger; +import sun.util.resources.LocaleData; + +public class NumberRegression extends IntlTest { + + public static void main(String[] args) throws Exception { + new NumberRegression().run(args); + } + + /** + * NumberFormat.equals comparing with null should always return false. + */ + public void Test4075713(){ + + try { + MyNumberFormatTest tmp = new MyNumberFormatTest(); + if (!tmp.equals(null)) + logln("NumberFormat.equals passed"); + } catch (NullPointerException e) { + errln("(new MyNumberFormatTest()).equals(null) throws unexpected exception"); + } + } + + /** + * NumberFormat.equals comparing two obj equal even the setGroupingUsed + * flag is different. + */ + public void Test4074620() { + + MyNumberFormatTest nf1 = new MyNumberFormatTest(); + MyNumberFormatTest nf2 = new MyNumberFormatTest(); + + nf1.setGroupingUsed(false); + nf2.setGroupingUsed(true); + + if (nf1.equals(nf2)) errln("Test for bug 4074620 failed"); + else logln("Test for bug 4074620 passed."); + return; + } + + + /** + * DecimalFormat.format() incorrectly uses maxFractionDigits setting. + */ + + public void Test4088161 (){ + DecimalFormat df = new DecimalFormat(); + double d = 100; + df.setMinimumFractionDigits(0); + df.setMaximumFractionDigits(16); + StringBuffer sBuf1 = new StringBuffer(""); + FieldPosition fp1 = new FieldPosition(0); + logln("d = " + d); + logln("maxFractionDigits = " + df.getMaximumFractionDigits()); + logln(" format(d) = '" + df.format(d, sBuf1, fp1) + "'"); + df.setMaximumFractionDigits(17); + StringBuffer sBuf2 = new StringBuffer(""); + FieldPosition fp2 = new FieldPosition(0); + logln("maxFractionDigits = " + df.getMaximumFractionDigits()); + df.format(d, sBuf2, fp2); + String expected = Locale.getDefault().equals(new Locale("hi", "IN")) ? + "\u0967\u0966\u0966" : "100"; + if (!sBuf2.toString().equals(expected)) + errln(" format(d) = '" + sBuf2 + "'"); + } + /** + * DecimalFormatSymbols should be cloned in the ctor DecimalFormat. + * DecimalFormat(String, DecimalFormatSymbols). + */ + public void Test4087245 (){ + DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(); + DecimalFormat df = new DecimalFormat("#,##0.0", symbols); + long n = 123; + StringBuffer buf1 = new StringBuffer(); + StringBuffer buf2 = new StringBuffer(); + logln("format(" + n + ") = " + + df.format(n, buf1, new FieldPosition(0))); + symbols.setDecimalSeparator('p'); // change value of field + logln("format(" + n + ") = " + + df.format(n, buf2, new FieldPosition(0))); + if (!buf1.toString().equals(buf2.toString())) + errln("Test for bug 4087245 failed"); + } + /** + * DecimalFormat.format() incorrectly formats 0.0 + */ + public void Test4087535 () + { + DecimalFormat df = new DecimalFormat(); + df.setMinimumIntegerDigits(0); + + double n = 0; + String buffer = new String(); + buffer = df.format(n); + if (buffer.length() == 0) + errln(n + ": '" + buffer + "'"); + n = 0.1; + buffer = df.format(n); + if (buffer.length() == 0) + errln(n + ": '" + buffer + "'"); + } + + /** + * DecimalFormat.format fails when groupingSize is set to 0. + */ + public void Test4088503 (){ + DecimalFormat df = new DecimalFormat(); + df.setGroupingSize(0); + StringBuffer sBuf = new StringBuffer(""); + FieldPosition fp = new FieldPosition(0); + try { + logln(df.format(123, sBuf, fp).toString()); + } catch (Exception foo) { + errln("Test for bug 4088503 failed."); + } + + } + /** + * NumberFormat.getCurrencyInstance is wrong. + */ + public void Test4066646 () { + float returnfloat = 0.0f; + assignFloatValue(2.04f); + assignFloatValue(2.03f); + assignFloatValue(2.02f); + assignFloatValue(0.0f); + } + + public float assignFloatValue(float returnfloat) + { + logln(" VALUE " + returnfloat); + NumberFormat nfcommon = NumberFormat.getCurrencyInstance(Locale.US); + nfcommon.setGroupingUsed(false); + + String stringValue = nfcommon.format(returnfloat).substring(1); + if (Float.valueOf(stringValue).floatValue() != returnfloat) + errln(" DISPLAYVALUE " + stringValue); + return returnfloat; + } // End Of assignFloatValue() + + /** + * DecimalFormat throws exception when parsing "0" + */ + public void Test4059870() { + DecimalFormat format = new DecimalFormat("00"); + try { + logln(format.parse("0").toString()); + } catch (Exception e) { errln("Test for bug 4059870 failed : " + e); } + } + /** + * DecimalFormatSymbol.equals should always return false when + * comparing with null. + */ + + public void Test4083018 (){ + DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(); + try { + if (!dfs.equals(null)) + logln("Test Passed!"); + } catch (Exception foo) { + errln("Test for bug 4083018 failed => Message : " + foo.getMessage()); + } + } + /** + * DecimalFormat does not round up correctly. + */ + public void Test4071492 (){ + Locale savedLocale = Locale.getDefault(); + Locale.setDefault(Locale.US); + double x = 0.00159999; + NumberFormat nf = NumberFormat.getInstance(); + nf.setMaximumFractionDigits(4); + String out = nf.format(x); + logln("0.00159999 formats with 4 fractional digits to " + out); + String expected = "0.0016"; + if (!out.equals(expected)) + errln("FAIL: Expected " + expected); + Locale.setDefault(savedLocale); + } + + /** + * A space as a group separator for localized pattern causes + * wrong format. WorkAround : use non-breaking space. + */ + public void Test4086575() { + + NumberFormat nf = NumberFormat.getInstance(Locale.FRANCE); + logln("nf toPattern1: " + ((DecimalFormat)nf).toPattern()); + logln("nf toLocPattern1: " + ((DecimalFormat)nf).toLocalizedPattern()); + + // No group separator + logln("...applyLocalizedPattern ###,00;(###,00) "); + ((DecimalFormat)nf).applyLocalizedPattern("###,00;(###,00)"); + logln("nf toPattern2: " + ((DecimalFormat)nf).toPattern()); + logln("nf toLocPattern2: " + ((DecimalFormat)nf).toLocalizedPattern()); + + logln("nf: " + nf.format(1234)); // 1234,00 + logln("nf: " + nf.format(-1234)); // (1234,00) + + // Space as group separator + + logln("...applyLocalizedPattern # ###,00;(# ###,00) "); + ((DecimalFormat)nf).applyLocalizedPattern("#\u00a0###,00;(#\u00a0###,00)"); + logln("nf toPattern2: " + ((DecimalFormat)nf).toPattern()); + logln("nf toLocPattern2: " + ((DecimalFormat)nf).toLocalizedPattern()); + String buffer = nf.format(1234); + if (!buffer.equals("1\u00a0234,00")) + errln("nf : " + buffer); // Expect 1 234,00 + buffer = nf.format(-1234); + if (!buffer.equals("(1\u00a0234,00)")) + errln("nf : " + buffer); // Expect (1 234,00) + + // Erroneously prints: + // 1234,00 , + // (1234,00 ,) + + } + /** + * DecimalFormat.parse returns wrong value + */ + public void Test4068693() + { + Locale savedLocale = Locale.getDefault(); + Locale.setDefault(Locale.US); + logln("----- Test Application -----"); + ParsePosition pos; + DecimalFormat df = new DecimalFormat(); + Double d = (Double)df.parse("123.55456", pos=new ParsePosition(0)); + if (!d.toString().equals("123.55456")) { + errln("Result -> " + d.doubleValue()); + } + Locale.setDefault(savedLocale); + } + + /* bugs 4069754, 4067878 + * null pointer thrown when accessing a deserialized DecimalFormat + * object. + */ + public void Test4069754() + { + try { + myformat it = new myformat(); + logln(it.Now()); + FileOutputStream ostream = new FileOutputStream("t.tmp"); + ObjectOutputStream p = new ObjectOutputStream(ostream); + p.writeObject(it); + ostream.close(); + logln("Saved ok."); + + FileInputStream istream = new FileInputStream("t.tmp"); + ObjectInputStream p2 = new ObjectInputStream(istream); + myformat it2 = (myformat)p2.readObject(); + logln(it2.Now()); + istream.close(); + logln("Loaded ok."); + } catch (Exception foo) { + errln("Test for bug 4069754 or 4057878 failed => Exception: " + foo.getMessage()); + } + } + + /** + * DecimalFormat.applyPattern(String) allows illegal patterns + */ + public void Test4087251 (){ + DecimalFormat df = new DecimalFormat(); + try { + df.applyPattern("#.#.#"); + logln("toPattern() returns \"" + df.toPattern() + "\""); + errln("applyPattern(\"#.#.#\") doesn't throw IllegalArgumentException"); + } catch (IllegalArgumentException e) { + logln("Caught Illegal Argument Error !"); + } + // Second test; added 5/11/98 when reported to fail on 1.2b3 + try { + df.applyPattern("#0.0#0#0"); + logln("toPattern() returns \"" + df.toPattern() + "\""); + errln("applyPattern(\"#0.0#0#0\") doesn't throw IllegalArgumentException"); + } catch (IllegalArgumentException e) { + logln("Ok - IllegalArgumentException for #0.0#0#0"); + } + } + + /** + * DecimalFormat.format() loses precision + */ + public void Test4090489 (){ + Locale savedLocale = Locale.getDefault(); + Locale.setDefault(Locale.US); + DecimalFormat df = new DecimalFormat(); + df.setMinimumFractionDigits(10); + df.setGroupingUsed(false); + double d = 1.000000000000001E7; + BigDecimal bd = new BigDecimal(d); + StringBuffer sb = new StringBuffer(""); + FieldPosition fp = new FieldPosition(0); + logln("d = " + d); + logln("BigDecimal.toString(): " + bd.toString()); + df.format(d, sb, fp); + if (!sb.toString().equals("10000000.0000000100")) { + errln("DecimalFormat.format(): " + sb.toString()); + } + Locale.setDefault(savedLocale); + } + + /** + * DecimalFormat.format() loses precision + */ + public void Test4090504 () + { + double d = 1; + logln("d = " + d); + DecimalFormat df = new DecimalFormat(); + StringBuffer sb; + FieldPosition fp; + try { + for (int i = 17; i <= 20; i++) { + df.setMaximumFractionDigits(i); + sb = new StringBuffer(""); + fp = new FieldPosition(0); + logln(" getMaximumFractionDigits() = " + i); + logln(" formated: " + df.format(d, sb, fp)); + } + } catch (Exception foo) { + errln("Bug 4090504 regression test failed. Message : " + foo.getMessage()); + } + } + /** + * DecimalFormat.parse(String str, ParsePosition pp) loses precision + */ + public void Test4095713 () + { + Locale savedLocale = Locale.getDefault(); + Locale.setDefault(Locale.US); + DecimalFormat df = new DecimalFormat(); + String str = "0.1234"; + Double d1 = new Double(str); + Double d2 = (Double) df.parse(str, new ParsePosition(0)); + logln(d1.toString()); + if (d2.doubleValue() != d1.doubleValue()) + errln("Bug 4095713 test failed, new double value : " + d2.doubleValue()); + Locale.setDefault(savedLocale); + } + + /** + * DecimalFormat.parse() fails when multiplier is not set to 1 + */ + public void Test4092561 () + { + Locale savedLocale = Locale.getDefault(); + Locale.setDefault(Locale.US); + DecimalFormat df = new DecimalFormat(); + + String str = Long.toString(Long.MIN_VALUE); + logln("Long.MIN_VALUE : " + df.parse(str, new ParsePosition(0)).toString()); + df.setMultiplier(100); + Number num = df.parse(str, new ParsePosition(0)); + if (num.doubleValue() != -9.223372036854776E16) { + errln("Bug 4092561 test failed when multiplier is not set to 1. Expected: -9.223372036854776E16, got: " + num.doubleValue()); + } + + df.setMultiplier(-100); + num = df.parse(str, new ParsePosition(0)); + if (num.doubleValue() != 9.223372036854776E16) { + errln("Bug 4092561 test failed when multiplier is not set to 1. Expected: 9.223372036854776E16, got: " + num.doubleValue()); + } + + str = Long.toString(Long.MAX_VALUE); + logln("Long.MAX_VALUE : " + df.parse(str, new ParsePosition(0)).toString()); + + df.setMultiplier(100); + num = df.parse(str, new ParsePosition(0)); + if (num.doubleValue() != 9.223372036854776E16) { + errln("Bug 4092561 test failed when multiplier is not set to 1. Expected: 9.223372036854776E16, got: " + num.doubleValue()); + } + + df.setMultiplier(-100); + num = df.parse(str, new ParsePosition(0)); + if (num.doubleValue() != -9.223372036854776E16) { + errln("Bug 4092561 test failed when multiplier is not set to 1. Expected: -9.223372036854776E16, got: " + num.doubleValue()); + } + + Locale.setDefault(savedLocale); + } + + /** + * DecimalFormat: Negative format ignored. + */ + public void Test4092480 () + { + DecimalFormat dfFoo = new DecimalFormat("000"); + + try { + dfFoo.applyPattern("0000;-000"); + if (!dfFoo.toPattern().equals("#0000")) + errln("dfFoo.toPattern : " + dfFoo.toPattern()); + logln(dfFoo.format(42)); + logln(dfFoo.format(-42)); + dfFoo.applyPattern("000;-000"); + if (!dfFoo.toPattern().equals("#000")) + errln("dfFoo.toPattern : " + dfFoo.toPattern()); + logln(dfFoo.format(42)); + logln(dfFoo.format(-42)); + + dfFoo.applyPattern("000;-0000"); + if (!dfFoo.toPattern().equals("#000")) + errln("dfFoo.toPattern : " + dfFoo.toPattern()); + logln(dfFoo.format(42)); + logln(dfFoo.format(-42)); + + dfFoo.applyPattern("0000;-000"); + if (!dfFoo.toPattern().equals("#0000")) + errln("dfFoo.toPattern : " + dfFoo.toPattern()); + logln(dfFoo.format(42)); + logln(dfFoo.format(-42)); + } catch (Exception foo) { + errln("Message " + foo.getMessage()); + } + } + /** + * NumberFormat.getCurrencyInstance() produces format that uses + * decimal separator instead of monetary decimal separator. + * + * Rewrote this test not to depend on the actual pattern. Pattern should + * never contain the monetary separator! Decimal separator in pattern is + * interpreted as monetary separator if currency symbol is seen! + */ + public void Test4087244 () { + Locale de = new Locale("pt", "PT"); + DecimalFormat df = (DecimalFormat) NumberFormat.getCurrencyInstance(de); + DecimalFormatSymbols sym = df.getDecimalFormatSymbols(); + sym.setMonetaryDecimalSeparator('$'); + df.setDecimalFormatSymbols(sym); + char decSep = sym.getDecimalSeparator(); + char monSep = sym.getMonetaryDecimalSeparator(); + char zero = sym.getZeroDigit(); + if (decSep == monSep) { + errln("ERROR in test: want decimal sep != monetary sep"); + } else { + df.setMinimumIntegerDigits(1); + df.setMinimumFractionDigits(2); + String str = df.format(1.23); + String monStr = "1" + monSep + "23"; + String decStr = "1" + decSep + "23"; + if (str.indexOf(monStr) >= 0 && str.indexOf(decStr) < 0) { + logln("OK: 1.23 -> \"" + str + "\" contains \"" + + monStr + "\" and not \"" + decStr + '"'); + } else { + errln("FAIL: 1.23 -> \"" + str + "\", should contain \"" + + monStr + + "\" and not \"" + decStr + '"'); + } + } + } + /** + * Number format data rounding errors for locale FR + */ + public void Test4070798 () { + NumberFormat formatter; + String tempString; + /* User error : + String expectedDefault = "-5\u00a0789,987"; + String expectedCurrency = "5\u00a0789,98 F"; + String expectedPercent = "-578\u00a0998%"; + */ + String expectedDefault = "-5\u00a0789,988"; + String expectedCurrency = "5\u00a0789,99 \u20AC"; + // changed for bug 6547501 + String expectedPercent = "-578\u00a0999 %"; + + formatter = NumberFormat.getNumberInstance(Locale.FRANCE); + tempString = formatter.format (-5789.9876); + + if (tempString.equals(expectedDefault)) { + logln ("Bug 4070798 default test passed."); + } else { + errln("Failed:" + + " Expected " + expectedDefault + + " Received " + tempString ); + } + + + formatter = NumberFormat.getCurrencyInstance(Locale.FRANCE); + tempString = formatter.format( 5789.9876 ); + + if (tempString.equals(expectedCurrency) ) { + logln ("Bug 4070798 currency test assed."); + } else { + errln("Failed:" + + " Expected " + expectedCurrency + + " Received " + tempString ); + } + + + formatter = NumberFormat.getPercentInstance(Locale.FRANCE); + tempString = formatter.format (-5789.9876); + + if (tempString.equals(expectedPercent) ) { + logln ("Bug 4070798 percentage test passed."); + } else { + errln("Failed:" + + " Expected " + expectedPercent + + " Received " + tempString ); + } + } + /** + * Data rounding errors for French (Canada) locale + */ + public void Test4071005 () { + + NumberFormat formatter; + String tempString; + /* user error : + String expectedDefault = "-5 789,987"; + String expectedCurrency = "5 789,98 $"; + String expectedPercent = "-578 998%"; + */ + String expectedDefault = "-5\u00a0789,988"; + String expectedCurrency = "5\u00a0789,99 $"; + // changed for bug 6547501 + String expectedPercent = "-578\u00a0999 %"; + + formatter = NumberFormat.getNumberInstance(Locale.CANADA_FRENCH); + tempString = formatter.format (-5789.9876); + if (tempString.equals(expectedDefault)) { + logln ("Bug 4071005 default test passed."); + } else { + errln("Failed:" + + " Expected " + expectedDefault + + " Received " + tempString ); + } + + formatter = NumberFormat.getCurrencyInstance(Locale.CANADA_FRENCH); + tempString = formatter.format( 5789.9876 ) ; + + if (tempString.equals(expectedCurrency) ) { + logln ("Bug 4071005 currency test passed."); + } else { + errln("Failed:" + + " Expected " + expectedCurrency + + " Received " + tempString ); + } + formatter = NumberFormat.getPercentInstance(Locale.CANADA_FRENCH); + tempString = formatter.format (-5789.9876); + + if (tempString.equals(expectedPercent) ) { + logln ("Bug 4071005 percentage test passed."); + } else { + errln("Failed:" + + " Expected " + expectedPercent + + " Received " + tempString ); + } + } + + /** + * Data rounding errors for German (Germany) locale + */ + public void Test4071014 () { + NumberFormat formatter; + String tempString; + /* user error : + String expectedDefault = "-5.789,987"; + String expectedCurrency = "5.789,98 DM"; + String expectedPercent = "-578.998%"; + */ + String expectedDefault = "-5.789,988"; + String expectedCurrency = "5.789,99 \u20AC"; + String expectedPercent = "-578.999%"; + + formatter = NumberFormat.getNumberInstance(Locale.GERMANY); + tempString = formatter.format (-5789.9876); + + if (tempString.equals(expectedDefault)) { + logln ("Bug 4071014 default test passed."); + } else { + errln("Failed:" + + " Expected " + expectedDefault + + " Received " + tempString ); + } + + formatter = NumberFormat.getCurrencyInstance(Locale.GERMANY); + tempString = formatter.format( 5789.9876 ) ; + + if (tempString.equals(expectedCurrency) ) { + logln ("Bug 4071014 currency test passed."); + } else { + errln("Failed:" + + " Expected " + expectedCurrency + + " Received " + tempString ); + } + + formatter = NumberFormat.getPercentInstance(Locale.GERMANY); + tempString = formatter.format (-5789.9876); + + if (tempString.equals(expectedPercent) ) { + logln ("Bug 4071014 percentage test passed."); + } else { + errln("Failed:" + + " Expected " + expectedPercent + + " Received " + tempString ); + } + + } + /** + * Data rounding errors for Italian locale number formats + */ + public void Test4071859 () { + NumberFormat formatter; + String tempString; + /* user error : + String expectedDefault = "-5.789,987"; + String expectedCurrency = "-L. 5.789,98"; + String expectedPercent = "-578.998%"; + */ + String expectedDefault = "-5.789,988"; + String expectedCurrency = "-\u20AC 5.789,99"; + String expectedPercent = "-578.999%"; + + formatter = NumberFormat.getNumberInstance(Locale.ITALY); + tempString = formatter.format (-5789.9876); + + if (tempString.equals(expectedDefault)) { + logln ("Bug 4071859 default test passed."); + } else { + errln("Failed:" + + " Expected " + expectedDefault + + " Received " + tempString ); + } + + formatter = NumberFormat.getCurrencyInstance(Locale.ITALY); + tempString = formatter.format( -5789.9876 ) ; + + if (tempString.equals(expectedCurrency) ) { + logln ("Bug 4071859 currency test passed."); + } else { + errln("Failed:" + + " Expected " + expectedCurrency + + " Received " + tempString ); + } + + formatter = NumberFormat.getPercentInstance(Locale.ITALY); + tempString = formatter.format (-5789.9876); + + if (tempString.equals(expectedPercent) ) { + logln ("Bug 4071859 percentage test passed."); + } else { + errln("Failed:" + + " Expected " + expectedPercent + + " Received " + tempString ); + } + + } + + /* bug 4071859 + * Test rounding for nearest even. + */ + public void Test4093610() + { + Locale savedLocale = Locale.getDefault(); + Locale.setDefault(Locale.US); + DecimalFormat df = new DecimalFormat("#0.#"); + + roundingTest(df, 12.15, "12.2"); // Rounding-up. Above tie (12.150..) + roundingTest(df, 12.25, "12.2"); // No round-up. Exact + half-even rule. + roundingTest(df, 12.45, "12.4"); // No round-up. Below tie (12.449..) + roundingTest(df, 12.450000001,"12.5"); // Rounding-up. Above tie. + roundingTest(df, 12.55, "12.6"); // Rounding-up. Above tie (12.550..) + roundingTest(df, 12.650000001,"12.7"); // Rounding-up. Above tie. + roundingTest(df, 12.75, "12.8"); // Rounding-up. Exact + half-even rule. + roundingTest(df, 12.750000001,"12.8"); // Rounding-up. Above tie. + roundingTest(df, 12.85, "12.8"); // No round-up. Below tie (12.849..) + roundingTest(df, 12.850000001,"12.9"); // Rounding-up. Above tie. + roundingTest(df, 12.950000001,"13"); // Rounding-up. Above tie. + + Locale.setDefault(savedLocale); + } + + void roundingTest(DecimalFormat df, double x, String expected) + { + String out = df.format(x); + logln("" + x + " formats with 1 fractional digits to " + out); + if (!out.equals(expected)) errln("FAIL: Expected " + expected); + } + /** + * Tests the setMaximumFractionDigits limit. + */ + public void Test4098741() + { + try { + NumberFormat fmt = NumberFormat.getPercentInstance(); + fmt.setMaximumFractionDigits(20); + logln(fmt.format(.001)); + } catch (Exception foo) { + errln("Bug 4098471 failed with exception thrown : " + foo.getMessage()); + } + } + /** + * Tests illegal pattern exception. + * Fix comment : HShih A31 Part1 will not be fixed and javadoc needs to be updated. + * Part2 has been fixed. + */ + public void Test4074454() + { + Locale savedLocale = Locale.getDefault(); + Locale.setDefault(Locale.US); + try { + DecimalFormat fmt = new DecimalFormat("#,#00.00;-#.#"); + logln("Inconsistent negative pattern is fine."); + DecimalFormat newFmt = new DecimalFormat("#,#00.00 p''ieces;-#,#00.00 p''ieces"); + String tempString = newFmt.format(3456.78); + if (!tempString.equals("3,456.78 p'ieces")) + errln("Failed! 3,456.78 p'ieces expected, but got : " + tempString); + } catch (Exception foo) { + errln("An exception was thrown for any inconsistent negative pattern."); + } + Locale.setDefault(savedLocale); + } + + /** + * Tests all different comments. + * Response to some comments : + * [1] DecimalFormat.parse API documentation is more than just one line. + * This is not a reproducable doc error in 116 source code. + * [2] See updated javadoc. + * [3] Fixed. + * [4] NumberFormat.parse(String, ParsePosition) : If parsing fails, + * a null object will be returned. The unchanged parse position also + * reflects an error. + * NumberFormat.parse(String) : If parsing fails, an ParseException + * will be thrown. + * See updated javadoc for more details. + * [5] See updated javadoc. + * [6] See updated javadoc. + * [7] This is a correct behavior if the DateFormat object is linient. + * Otherwise, an IllegalArgumentException will be thrown when formatting + * "January 35". See GregorianCalendar class javadoc for more details. + */ + public void Test4099404() + { + try { + DecimalFormat fmt = new DecimalFormat("000.0#0"); + errln("Bug 4099404 failed applying illegal pattern \"000.0#0\""); + } catch (Exception foo) { + logln("Bug 4099404 pattern \"000.0#0\" passed"); + } + try { + DecimalFormat fmt = new DecimalFormat("0#0.000"); + errln("Bug 4099404 failed applying illegal pattern \"0#0.000\""); + } catch (Exception foo) { + logln("Bug 4099404 pattern \"0#0.000\" passed"); + } + } + /** + * DecimalFormat.applyPattern doesn't set minimum integer digits + */ + public void Test4101481() + { + DecimalFormat sdf = new DecimalFormat("#,##0"); + if (sdf.getMinimumIntegerDigits() != 1) + errln("Minimum integer digits : " + sdf.getMinimumIntegerDigits()); + } + /** + * Tests ParsePosition.setErrorPosition() and ParsePosition.getErrorPosition(). + */ + public void Test4052223() + { + try { + DecimalFormat fmt = new DecimalFormat("#,#00.00"); + Number num = fmt.parse("abc3"); + errln("Bug 4052223 failed : can't parse string \"a\". Got " + num); + } catch (ParseException foo) { + logln("Caught expected ParseException : " + foo.getMessage() + " at index : " + foo.getErrorOffset()); + } + } + /** + * API tests for API addition request A9. + */ + public void Test4061302() + { + DecimalFormatSymbols fmt = DecimalFormatSymbols.getInstance(); + String currency = fmt.getCurrencySymbol(); + String intlCurrency = fmt.getInternationalCurrencySymbol(); + char monDecSeparator = fmt.getMonetaryDecimalSeparator(); + if (currency.equals("") || + intlCurrency.equals("") || + monDecSeparator == 0) { + errln("getCurrencySymbols failed, got empty string."); + } + logln("Before set ==> Currency : " + currency + " Intl Currency : " + intlCurrency + " Monetary Decimal Separator : " + monDecSeparator); + fmt.setCurrencySymbol("XYZ"); + fmt.setInternationalCurrencySymbol("ABC"); + fmt.setMonetaryDecimalSeparator('*'); + currency = fmt.getCurrencySymbol(); + intlCurrency = fmt.getInternationalCurrencySymbol(); + monDecSeparator = fmt.getMonetaryDecimalSeparator(); + if (!currency.equals("XYZ") || + !intlCurrency.equals("ABC") || + monDecSeparator != '*') { + errln("setCurrencySymbols failed."); + } + logln("After set ==> Currency : " + currency + " Intl Currency : " + intlCurrency + " Monetary Decimal Separator : " + monDecSeparator); + } + /** + * API tests for API addition request A23. FieldPosition.getBeginIndex and + * FieldPosition.getEndIndex. + */ + public void Test4062486() + { + DecimalFormat fmt = new DecimalFormat("#,##0.00"); + StringBuffer formatted = new StringBuffer(); + FieldPosition field = new FieldPosition(0); + Double num = new Double(1234.5); + fmt.format(num, formatted, field); + if (field.getBeginIndex() != 0 && field.getEndIndex() != 5) + errln("Format 1234.5 failed. Begin index: " + field.getBeginIndex() + " End index: " + field.getEndIndex()); + field.setBeginIndex(7); + field.setEndIndex(4); + if (field.getBeginIndex() != 7 && field.getEndIndex() != 4) + errln("Set begin/end field indexes failed. Begin index: " + field.getBeginIndex() + " End index: " + field.getEndIndex()); + } + + /** + * DecimalFormat.parse incorrectly works with a group separator. + */ + public void Test4108738() + { + + DecimalFormat df = new DecimalFormat("#,##0.###", + DecimalFormatSymbols.getInstance(java.util.Locale.US)); + String text = "1.222,111"; + Number num = df.parse(text,new ParsePosition(0)); + if (!num.toString().equals("1.222")) + errln("\"" + text + "\" is parsed as " + num); + text = "1.222x111"; + num = df.parse(text,new ParsePosition(0)); + if (!num.toString().equals("1.222")) + errln("\"" + text + "\" is parsed as " + num); + } + + /** + * DecimalFormat.format() incorrectly formats negative doubles. + */ + public void Test4106658() + { + Locale savedLocale = Locale.getDefault(); + Locale.setDefault(Locale.US); + DecimalFormat df = new DecimalFormat(); // Corrected; see 4147706 + double d1 = -0.0; + double d2 = -0.0001; + StringBuffer buffer = new StringBuffer(); + logln("pattern: \"" + df.toPattern() + "\""); + df.format(d1, buffer, new FieldPosition(0)); + if (!buffer.toString().equals("-0")) { // Corrected; see 4147706 + errln(d1 + " is formatted as " + buffer); + } + buffer.setLength(0); + df.format(d2, buffer, new FieldPosition(0)); + if (!buffer.toString().equals("-0")) { // Corrected; see 4147706 + errln(d2 + " is formatted as " + buffer); + } + Locale.setDefault(savedLocale); + } + + /** + * DecimalFormat.parse returns 0 if string parameter is incorrect. + */ + public void Test4106662() + { + DecimalFormat df = new DecimalFormat(); + String text = "x"; + ParsePosition pos1 = new ParsePosition(0), pos2 = new ParsePosition(0); + + logln("pattern: \"" + df.toPattern() + "\""); + Number num = df.parse(text, pos1); + if (num != null) { + errln("Test Failed: \"" + text + "\" is parsed as " + num); + } + df = null; + df = new DecimalFormat("$###.00"); + num = df.parse("$", pos2); + if (num != null){ + errln("Test Failed: \"$\" is parsed as " + num); + } + } + + /** + * NumberFormat.parse doesn't return null + */ + public void Test4114639() + { + NumberFormat format = NumberFormat.getInstance(); + String text = "time 10:x"; + ParsePosition pos = new ParsePosition(8); + Number result = format.parse(text, pos); + if (result != null) errln("Should return null but got : " + result); // Should be null; it isn't + } + + /** + * DecimalFormat.format(long n) fails if n * multiplier > MAX_LONG. + */ + public void Test4106664() + { + DecimalFormat df = new DecimalFormat(); + long n = 1234567890123456L; + int m = 12345678; + BigInteger bigN = BigInteger.valueOf(n); + bigN = bigN.multiply(BigInteger.valueOf(m)); + df.setMultiplier(m); + df.setGroupingUsed(false); + logln("formated: " + + df.format(n, new StringBuffer(), new FieldPosition(0))); + logln("expected: " + bigN.toString()); + } + /** + * DecimalFormat.format incorrectly formats -0.0. + */ + public void Test4106667() + { + Locale savedLocale = Locale.getDefault(); + Locale.setDefault(Locale.US); + DecimalFormat df = new DecimalFormat(); + df.setPositivePrefix("+"); + double d = -0.0; + logln("pattern: \"" + df.toPattern() + "\""); + StringBuffer buffer = new StringBuffer(); + df.format(d, buffer, new FieldPosition(0)); + if (!buffer.toString().equals("-0")) { // Corrected; see 4147706 + errln(d + " is formatted as " + buffer); + } + Locale.setDefault(savedLocale); + } + + /** + * DecimalFormat.setMaximumIntegerDigits() works incorrectly. + */ + public void Test4110936() + { + NumberFormat nf = NumberFormat.getInstance(); + nf.setMaximumIntegerDigits(128); + logln("setMaximumIntegerDigits(128)"); + if (nf.getMaximumIntegerDigits() != 128) + errln("getMaximumIntegerDigits() returns " + + nf.getMaximumIntegerDigits()); + } + + /** + * Locale data should use generic currency symbol + * + * 1) Make sure that all currency formats use the generic currency symbol. + * 2) Make sure we get the same results using the generic symbol or a + * hard-coded one. + */ + public void Test4122840() + { + Locale[] locales = NumberFormat.getAvailableLocales(); + + for (int i = 0; i < locales.length; i++) { + ResourceBundle rb = LocaleData.getBundle("sun.text.resources.FormatData", + locales[i]); + // + // Get the currency pattern for this locale. We have to fish it + // out of the ResourceBundle directly, since DecimalFormat.toPattern + // will return the localized symbol, not \00a4 + // + String[] numPatterns = (String[])rb.getObject("NumberPatterns"); + String pattern = numPatterns[1]; + + if (pattern.indexOf("\u00A4") == -1 ) { + errln("Currency format for " + locales[i] + + " does not contain generic currency symbol:" + + pattern ); + } + + // Create a DecimalFormat using the pattern we got and format a number + DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(locales[i]); + DecimalFormat fmt1 = new DecimalFormat(pattern, symbols); + + String result1 = fmt1.format(1.111); + + // + // Now substitute in the locale's currency symbol and create another + // pattern. Replace the decimal separator with the monetary separator. + // + char decSep = symbols.getDecimalSeparator(); + char monSep = symbols.getMonetaryDecimalSeparator(); + StringBuffer buf = new StringBuffer(pattern); + for (int j = 0; j < buf.length(); j++) { + if (buf.charAt(j) == '\u00a4') { + String cur = "'" + symbols.getCurrencySymbol() + "'"; + buf.replace(j, j+1, cur); + j += cur.length() - 1; + } + } + symbols.setDecimalSeparator(monSep); + DecimalFormat fmt2 = new DecimalFormat(buf.toString(), symbols); + + String result2 = fmt2.format(1.111); + + if (!result1.equals(result2)) { + errln("Results for " + locales[i] + " differ: " + + result1 + " vs " + result2); + } + } + } + + /** + * DecimalFormat.format() delivers wrong string. + */ + public void Test4125885() + { + Locale savedLocale = Locale.getDefault(); + Locale.setDefault(Locale.US); + double rate = 12.34; + DecimalFormat formatDec = new DecimalFormat ("000.00"); + logln("toPattern: " + formatDec.toPattern()); + String rateString= formatDec.format(rate); + if (!rateString.equals("012.34")) + errln("result : " + rateString + " expected : 012.34"); + rate = 0.1234; + formatDec = null; + formatDec = new DecimalFormat ("+000.00%;-000.00%"); + logln("toPattern: " + formatDec.toPattern()); + rateString= formatDec.format(rate); + if (!rateString.equals("+012.34%")) + errln("result : " + rateString + " expected : +012.34%"); + Locale.setDefault(savedLocale); + } + + /** + ** + * DecimalFormat produces extra zeros when formatting numbers. + */ + public void Test4134034() { + Locale savedLocale = Locale.getDefault(); + Locale.setDefault(Locale.US); + DecimalFormat nf = new DecimalFormat("##,###,###.00"); + + String f = nf.format(9.02); + if (f.equals("9.02")) logln(f + " ok"); else errln("9.02 -> " + f + "; want 9.02"); + + f = nf.format(0); + if (f.equals(".00")) logln(f + " ok"); else errln("0 -> " + f + "; want .00"); + Locale.setDefault(savedLocale); + } + + /** + * CANNOT REPRODUCE - This bug could not be reproduced. It may be + * a duplicate of 4134034. + * + * JDK 1.1.6 Bug, did NOT occur in 1.1.5 + * Possibly related to bug 4125885. + * + * This class demonstrates a regression in version 1.1.6 + * of DecimalFormat class. + * + * 1.1.6 Results + * Value 1.2 Format #.00 Result '01.20' !!!wrong + * Value 1.2 Format 0.00 Result '001.20' !!!wrong + * Value 1.2 Format 00.00 Result '0001.20' !!!wrong + * Value 1.2 Format #0.0# Result '1.2' + * Value 1.2 Format #0.00 Result '001.20' !!!wrong + * + * 1.1.5 Results + * Value 1.2 Format #.00 Result '1.20' + * Value 1.2 Format 0.00 Result '1.20' + * Value 1.2 Format 00.00 Result '01.20' + * Value 1.2 Format #0.0# Result '1.2' + * Value 1.2 Format #0.00 Result '1.20' + */ + public void Test4134300() { + Locale savedLocale = Locale.getDefault(); + Locale.setDefault(Locale.US); + String[] DATA = { + // Pattern Expected string + "#.00", "1.20", + "0.00", "1.20", + "00.00", "01.20", + "#0.0#", "1.2", + "#0.00", "1.20", + }; + for (int i=0; i " + s); + s = f.format(-123.456); + if (!s.equals("-123.456")) + errln("Fail: Format empty pattern x -123.456 => " + s); + } + } + + /** + * BigDecimal numbers get their fractions truncated by NumberFormat. + */ + public void Test4141750() { + try { + String str = "12345.67"; + BigDecimal bd = new BigDecimal(str); + NumberFormat nf = NumberFormat.getInstance(Locale.US); + String sd = nf.format(bd); + if (!sd.endsWith("67")) { + errln("Fail: " + str + " x format -> " + sd); + } + } + catch (Exception e) { + errln(e.toString()); + e.printStackTrace(); + } + } + + /** + * DecimalFormat toPattern() doesn't quote special characters or handle + * single quotes. + */ + public void Test4145457() { + try { + DecimalFormat nf = (DecimalFormat)NumberFormat.getInstance(); + DecimalFormatSymbols sym = nf.getDecimalFormatSymbols(); + sym.setDecimalSeparator('\''); + nf.setDecimalFormatSymbols(sym); + double pi = 3.14159; + + String[] PATS = { "#.00 'num''ber'", "''#.00''" }; + + for (int i=0; i \"" + pat + '"'); + + if (val == val2 && out.equals(out2)) { + logln("Ok " + pi + " x \"" + PATS[i] + "\" -> \"" + + out + "\" -> " + val + " -> \"" + + out2 + "\" -> " + val2); + } + else { + errln("Fail " + pi + " x \"" + PATS[i] + "\" -> \"" + + out + "\" -> " + val + " -> \"" + + out2 + "\" -> " + val2); + } + } + } + catch (ParseException e) { + errln("Fail: " + e); + e.printStackTrace(); + } + } + + /** + * DecimalFormat.applyPattern() sets minimum integer digits incorrectly. + * CANNOT REPRODUCE + * This bug is a duplicate of 4139344, which is a duplicate of 4134300 + */ + public void Test4147295() { + DecimalFormat sdf = new DecimalFormat(); + String pattern = "#,###"; + logln("Applying pattern \"" + pattern + "\""); + sdf.applyPattern(pattern); + int minIntDig = sdf.getMinimumIntegerDigits(); + if (minIntDig != 0) { + errln("Test failed"); + errln(" Minimum integer digits : " + minIntDig); + errln(" new pattern: " + sdf.toPattern()); + } else { + logln("Test passed"); + logln(" Minimum integer digits : " + minIntDig); + } + } + + /** + * DecimalFormat formats -0.0 as +0.0 + * See also older related bug 4106658, 4106667 + */ + public void Test4147706() { + DecimalFormat df = new DecimalFormat("#,##0.0##"); + df.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.ENGLISH)); + double d1 = -0.0; + double d2 = -0.0001; + StringBuffer f1 = df.format(d1, new StringBuffer(), new FieldPosition(0)); + StringBuffer f2 = df.format(d2, new StringBuffer(), new FieldPosition(0)); + if (!f1.toString().equals("-0.0")) { + errln(d1 + " x \"" + df.toPattern() + "\" is formatted as \"" + f1 + '"'); + } + if (!f2.toString().equals("-0.0")) { + errln(d2 + " x \"" + df.toPattern() + "\" is formatted as \"" + f2 + '"'); + } + } + + /** + * NumberFormat cannot format Double.MAX_VALUE + */ + public void Test4162198() { + double dbl = Double.MAX_VALUE; + NumberFormat f = NumberFormat.getInstance(); + f.setMaximumFractionDigits(Integer.MAX_VALUE); + f.setMaximumIntegerDigits(Integer.MAX_VALUE); + String s = f.format(dbl); + logln("The number " + dbl + " formatted to " + s); + Number n = null; + try { + n = f.parse(s); + } catch (java.text.ParseException e) { + errln("Caught a ParseException:"); + e.printStackTrace(); + } + logln("The string " + s + " parsed as " + n); + if (n.doubleValue() != dbl) { + errln("Round trip failure"); + } + } + + /** + * NumberFormat does not parse negative zero. + */ + public void Test4162852() throws ParseException { + for (int i=0; i<2; ++i) { + NumberFormat f = (i == 0) ? NumberFormat.getInstance() + : NumberFormat.getPercentInstance(); + double d = -0.0; + String s = f.format(d); + double e = f.parse(s).doubleValue(); + logln("" + + d + " -> " + + '"' + s + '"' + " -> " + + e); + if (e != 0.0 || 1.0/e > 0.0) { + logln("Failed to parse negative zero"); + } + } + } + + /** + * NumberFormat truncates data + */ + public void Test4167494() throws Exception { + NumberFormat fmt = NumberFormat.getInstance(Locale.US); + + double a = Double.MAX_VALUE; + String s = fmt.format(a); + double b = fmt.parse(s).doubleValue(); + boolean match = a == b; + if (match) { + logln("" + a + " -> \"" + s + "\" -> " + b + " ok"); + } else { + errln("" + a + " -> \"" + s + "\" -> " + b + " FAIL"); + } + + // We don't test Double.MIN_VALUE because the locale data for the US + // currently doesn't specify enough digits to display Double.MIN_VALUE. + // This is correct for now; however, we leave this here as a reminder + // in case we want to address this later. + if (false) { + a = Double.MIN_VALUE; + s = fmt.format(a); + b = fmt.parse(s).doubleValue(); + match = a == b; + if (match) { + logln("" + a + " -> \"" + s + "\" -> " + b + " ok"); + } else { + errln("" + a + " -> \"" + s + "\" -> " + b + " FAIL"); + } + } + } + + /** + * DecimalFormat.parse() fails when ParseIntegerOnly set to true + */ + public void Test4170798() { + Locale savedLocale = Locale.getDefault(); + Locale.setDefault(Locale.US); + DecimalFormat df = new DecimalFormat(); + df.setParseIntegerOnly(true); + Number n = df.parse("-0.0", new ParsePosition(0)); + if (!(n instanceof Long || n instanceof Integer) + || n.intValue() != 0) { + errln("FAIL: parse(\"-0.0\") returns " + + n + " (" + n.getClass().getName() + ')'); + } + Locale.setDefault(savedLocale); + } + + /** + * toPattern only puts the first grouping separator in. + */ + public void Test4176114() { + String[] DATA = { + "00", "#00", + "000", "#000", // No grouping + "#000", "#000", // No grouping + "#,##0", "#,##0", + "#,000", "#,000", + "0,000", "#0,000", + "00,000", "#00,000", + "000,000", "#,000,000", + "0,000,000,000,000.0000", "#0,000,000,000,000.0000", // Reported + }; + for (int i=0; i " + s + ", want " + DATA[i+1]); + } + } + } + + /** + * DecimalFormat is incorrectly rounding numbers like 1.2501 to 1.2 + */ + public void Test4179818() { + String DATA[] = { + // Input Pattern Expected output + "1.2511", "#.#", "1.3", + "1.2501", "#.#", "1.3", + "0.9999", "#", "1", + }; + DecimalFormat fmt = new DecimalFormat("#", + DecimalFormatSymbols.getInstance(Locale.US)); + for (int i=0; i " + fmt.format(-1) + + ", exp ^1"); + } + if (!fmt.getNegativePrefix().equals("^")) { + errln("FAIL: (minus=^).getNegativePrefix -> " + + fmt.getNegativePrefix() + ", exp ^"); + } + sym.setMinusSign('-'); + + fmt.applyPattern("#%"); + sym.setPercent('^'); + fmt.setDecimalFormatSymbols(sym); + if (!fmt.format(0.25).equals("25^")) { + errln("FAIL: 0.25 x (percent=^) -> " + fmt.format(0.25) + + ", exp 25^"); + } + if (!fmt.getPositiveSuffix().equals("^")) { + errln("FAIL: (percent=^).getPositiveSuffix -> " + + fmt.getPositiveSuffix() + ", exp ^"); + } + sym.setPercent('%'); + + fmt.applyPattern("#\u2030"); + sym.setPerMill('^'); + fmt.setDecimalFormatSymbols(sym); + if (!fmt.format(0.25).equals("250^")) { + errln("FAIL: 0.25 x (permill=^) -> " + fmt.format(0.25) + + ", exp 250^"); + } + if (!fmt.getPositiveSuffix().equals("^")) { + errln("FAIL: (permill=^).getPositiveSuffix -> " + + fmt.getPositiveSuffix() + ", exp ^"); + } + sym.setPerMill('\u2030'); + + fmt.applyPattern("\u00A4#.00"); + sym.setCurrencySymbol("usd"); + fmt.setDecimalFormatSymbols(sym); + if (!fmt.format(12.5).equals("usd12.50")) { + errln("FAIL: 12.5 x (currency=usd) -> " + fmt.format(12.5) + + ", exp usd12.50"); + } + if (!fmt.getPositivePrefix().equals("usd")) { + errln("FAIL: (currency=usd).getPositivePrefix -> " + + fmt.getPositivePrefix() + ", exp usd"); + } + sym.setCurrencySymbol("$"); + + fmt.applyPattern("\u00A4\u00A4#.00"); + sym.setInternationalCurrencySymbol("DOL"); + fmt.setDecimalFormatSymbols(sym); + if (!fmt.format(12.5).equals("DOL12.50")) { + errln("FAIL: 12.5 x (intlcurrency=DOL) -> " + fmt.format(12.5) + + ", exp DOL12.50"); + } + if (!fmt.getPositivePrefix().equals("DOL")) { + errln("FAIL: (intlcurrency=DOL).getPositivePrefix -> " + + fmt.getPositivePrefix() + ", exp DOL"); + } + sym.setInternationalCurrencySymbol("USD"); + + // Since the pattern logic has changed, make sure that patterns round + // trip properly. Test stream in/out integrity too. + Locale[] avail = NumberFormat.getAvailableLocales(); + for (int i=0; i \"" + pat + + "\" -> \"" + f2.toPattern() + '"'); + } + + // Test toLocalizedPattern/applyLocalizedPattern round trip + pat = df.toLocalizedPattern(); + f2.applyLocalizedPattern(pat); + if (!df.equals(f2)) { + errln("FAIL: " + avail[i] + " -> localized \"" + pat + + "\" -> \"" + f2.toPattern() + '"'); + } + + // Test writeObject/readObject round trip + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(df); + oos.flush(); + baos.close(); + byte[] bytes = baos.toByteArray(); + ObjectInputStream ois = + new ObjectInputStream(new ByteArrayInputStream(bytes)); + f2 = (DecimalFormat) ois.readObject(); + if (!df.equals(f2)) { + errln("FAIL: Stream in/out " + avail[i] + " -> \"" + pat + + "\" -> " + + (f2 != null ? ("\""+f2.toPattern()+'"') : "null")); + } + + } + } + } + + /** + * DecimalFormat.parse() fails for mulipliers 2^n. + */ + public void Test4216742() throws ParseException { + DecimalFormat fmt = (DecimalFormat) NumberFormat.getInstance(Locale.US); + long[] DATA = { Long.MIN_VALUE, Long.MAX_VALUE, -100000000L, 100000000L}; + for (int i=0; i 0 != DATA[i] > 0) { + errln("\"" + str + "\" parse(x " + fmt.getMultiplier() + + ") => " + n); + } + } + } + } + + /** + * DecimalFormat formats 1.001 to "1.00" instead of "1" with 2 fraction + * digits. + */ + public void Test4217661() { + Object[] DATA = { + new Double(0.001), "0", + new Double(1.001), "1", + new Double(0.006), "0.01", + new Double(1.006), "1.01", + }; + NumberFormat fmt = NumberFormat.getInstance(Locale.US); + fmt.setMaximumFractionDigits(2); + for (int i=0; i