Path: blob/master/test/jdk/java/text/Format/NumberFormat/NumberRegression.java
41152 views
/*1* Copyright (c) 1997, 2020, 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* @bug 4052223 4059870 4061302 4062486 4066646 4068693 4070798 4071005 407101426* 4071492 4071859 4074454 4074620 4075713 4083018 4086575 4087244 408724527* 4087251 4087535 4088161 4088503 4090489 4090504 4092480 4092561 409571328* 4098741 4099404 4101481 4106658 4106662 4106664 4108738 4110936 412284029* 4125885 4134034 4134300 4140009 4141750 4145457 4147295 4147706 416219830* 4162852 4167494 4170798 4176114 4179818 4185761 4212072 4212073 421674231* 4217661 4243011 4243108 4330377 4233840 4241880 4833877 8008577 822731332* @summary Regression tests for NumberFormat and associated classes33* @library /java/text/testlib34* @build IntlTest HexDumpReader TestUtils35* @modules java.base/sun.util.resources36* jdk.localedata37* @compile -XDignore.symbol.file NumberRegression.java38* @run main/othervm -Djava.locale.providers=COMPAT,SPI NumberRegression39*/4041/*42(C) Copyright Taligent, Inc. 1996 - All Rights Reserved43(C) Copyright IBM Corp. 1996 - All Rights Reserved4445The original version of this source code and documentation is copyrighted and46owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These materials are47provided under terms of a License Agreement between Taligent and Sun. This48technology is protected by multiple US and International patents. This notice and49attribution to Taligent may not be removed.50Taligent is a registered trademark of Taligent, Inc.51*/5253import java.text.*;54import java.util.*;55import java.math.BigDecimal;56import java.io.*;57import java.math.BigInteger;58import sun.util.resources.LocaleData;5960public class NumberRegression extends IntlTest {6162public static void main(String[] args) throws Exception {63new NumberRegression().run(args);64}6566/**67* NumberFormat.equals comparing with null should always return false.68*/69public void Test4075713(){7071try {72MyNumberFormatTest tmp = new MyNumberFormatTest();73if (!tmp.equals(null))74logln("NumberFormat.equals passed");75} catch (NullPointerException e) {76errln("(new MyNumberFormatTest()).equals(null) throws unexpected exception");77}78}7980/**81* NumberFormat.equals comparing two obj equal even the setGroupingUsed82* flag is different.83*/84public void Test4074620() {8586MyNumberFormatTest nf1 = new MyNumberFormatTest();87MyNumberFormatTest nf2 = new MyNumberFormatTest();8889nf1.setGroupingUsed(false);90nf2.setGroupingUsed(true);9192if (nf1.equals(nf2)) errln("Test for bug 4074620 failed");93else logln("Test for bug 4074620 passed.");94return;95}969798/**99* DecimalFormat.format() incorrectly uses maxFractionDigits setting.100*/101102public void Test4088161 (){103Locale locale = Locale.getDefault();104if (!TestUtils.usesAsciiDigits(locale)) {105logln("Skipping this test because locale is " + locale);106return;107}108109DecimalFormat df = new DecimalFormat();110double d = 100;111df.setMinimumFractionDigits(0);112df.setMaximumFractionDigits(16);113StringBuffer sBuf1 = new StringBuffer("");114FieldPosition fp1 = new FieldPosition(0);115logln("d = " + d);116logln("maxFractionDigits = " + df.getMaximumFractionDigits());117logln(" format(d) = '" + df.format(d, sBuf1, fp1) + "'");118df.setMaximumFractionDigits(17);119StringBuffer sBuf2 = new StringBuffer("");120FieldPosition fp2 = new FieldPosition(0);121logln("maxFractionDigits = " + df.getMaximumFractionDigits());122df.format(d, sBuf2, fp2);123String expected = "100";124if (!sBuf2.toString().equals(expected))125errln(" format(d) = '" + sBuf2 + "'");126}127/**128* DecimalFormatSymbols should be cloned in the ctor DecimalFormat.129* DecimalFormat(String, DecimalFormatSymbols).130*/131public void Test4087245 (){132DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance();133DecimalFormat df = new DecimalFormat("#,##0.0", symbols);134long n = 123;135StringBuffer buf1 = new StringBuffer();136StringBuffer buf2 = new StringBuffer();137logln("format(" + n + ") = " +138df.format(n, buf1, new FieldPosition(0)));139symbols.setDecimalSeparator('p'); // change value of field140logln("format(" + n + ") = " +141df.format(n, buf2, new FieldPosition(0)));142if (!buf1.toString().equals(buf2.toString()))143errln("Test for bug 4087245 failed");144}145/**146* DecimalFormat.format() incorrectly formats 0.0147*/148public void Test4087535 ()149{150DecimalFormat df = new DecimalFormat();151df.setMinimumIntegerDigits(0);152153double n = 0;154String buffer = new String();155buffer = df.format(n);156if (buffer.length() == 0)157errln(n + ": '" + buffer + "'");158n = 0.1;159buffer = df.format(n);160if (buffer.length() == 0)161errln(n + ": '" + buffer + "'");162}163164/**165* DecimalFormat.format fails when groupingSize is set to 0.166*/167public void Test4088503 (){168DecimalFormat df = new DecimalFormat();169df.setGroupingSize(0);170StringBuffer sBuf = new StringBuffer("");171FieldPosition fp = new FieldPosition(0);172try {173logln(df.format(123, sBuf, fp).toString());174} catch (Exception foo) {175errln("Test for bug 4088503 failed.");176}177178}179/**180* NumberFormat.getCurrencyInstance is wrong.181*/182public void Test4066646 () {183float returnfloat = 0.0f;184assignFloatValue(2.04f);185assignFloatValue(2.03f);186assignFloatValue(2.02f);187assignFloatValue(0.0f);188}189190public float assignFloatValue(float returnfloat)191{192logln(" VALUE " + returnfloat);193NumberFormat nfcommon = NumberFormat.getCurrencyInstance(Locale.US);194nfcommon.setGroupingUsed(false);195196String stringValue = nfcommon.format(returnfloat).substring(1);197if (Float.valueOf(stringValue).floatValue() != returnfloat)198errln(" DISPLAYVALUE " + stringValue);199return returnfloat;200} // End Of assignFloatValue()201202/**203* DecimalFormat throws exception when parsing "0"204*/205public void Test4059870() {206DecimalFormat format = new DecimalFormat("00");207try {208logln(format.parse("0").toString());209} catch (Exception e) { errln("Test for bug 4059870 failed : " + e); }210}211/**212* DecimalFormatSymbol.equals should always return false when213* comparing with null.214*/215216public void Test4083018 (){217DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance();218try {219if (!dfs.equals(null))220logln("Test Passed!");221} catch (Exception foo) {222errln("Test for bug 4083018 failed => Message : " + foo.getMessage());223}224}225/**226* DecimalFormat does not round up correctly.227*/228public void Test4071492 (){229Locale savedLocale = Locale.getDefault();230Locale.setDefault(Locale.US);231double x = 0.00159999;232NumberFormat nf = NumberFormat.getInstance();233nf.setMaximumFractionDigits(4);234String out = nf.format(x);235logln("0.00159999 formats with 4 fractional digits to " + out);236String expected = "0.0016";237if (!out.equals(expected))238errln("FAIL: Expected " + expected);239Locale.setDefault(savedLocale);240}241242/**243* A space as a group separator for localized pattern causes244* wrong format. WorkAround : use non-breaking space.245*/246public void Test4086575() {247248NumberFormat nf = NumberFormat.getInstance(Locale.FRANCE);249logln("nf toPattern1: " + ((DecimalFormat)nf).toPattern());250logln("nf toLocPattern1: " + ((DecimalFormat)nf).toLocalizedPattern());251252// No group separator253logln("...applyLocalizedPattern ###,00;(###,00) ");254((DecimalFormat)nf).applyLocalizedPattern("###,00;(###,00)");255logln("nf toPattern2: " + ((DecimalFormat)nf).toPattern());256logln("nf toLocPattern2: " + ((DecimalFormat)nf).toLocalizedPattern());257258logln("nf: " + nf.format(1234)); // 1234,00259logln("nf: " + nf.format(-1234)); // (1234,00)260261// Space as group separator262263logln("...applyLocalizedPattern # ###,00;(# ###,00) ");264((DecimalFormat)nf).applyLocalizedPattern("#\u00a0###,00;(#\u00a0###,00)");265logln("nf toPattern2: " + ((DecimalFormat)nf).toPattern());266logln("nf toLocPattern2: " + ((DecimalFormat)nf).toLocalizedPattern());267String buffer = nf.format(1234);268if (!buffer.equals("1\u00a0234,00"))269errln("nf : " + buffer); // Expect 1 234,00270buffer = nf.format(-1234);271if (!buffer.equals("(1\u00a0234,00)"))272errln("nf : " + buffer); // Expect (1 234,00)273274// Erroneously prints:275// 1234,00 ,276// (1234,00 ,)277278}279/**280* DecimalFormat.parse returns wrong value281*/282public void Test4068693()283{284Locale savedLocale = Locale.getDefault();285Locale.setDefault(Locale.US);286logln("----- Test Application -----");287ParsePosition pos;288DecimalFormat df = new DecimalFormat();289Double d = (Double)df.parse("123.55456", pos=new ParsePosition(0));290if (!d.toString().equals("123.55456")) {291errln("Result -> " + d);292}293Locale.setDefault(savedLocale);294}295296/* bugs 4069754, 4067878297* null pointer thrown when accessing a deserialized DecimalFormat298* object.299*/300public void Test4069754()301{302try {303myformat it = new myformat();304logln(it.Now());305FileOutputStream ostream = new FileOutputStream("t.tmp");306ObjectOutputStream p = new ObjectOutputStream(ostream);307p.writeObject(it);308ostream.close();309logln("Saved ok.");310311FileInputStream istream = new FileInputStream("t.tmp");312ObjectInputStream p2 = new ObjectInputStream(istream);313myformat it2 = (myformat)p2.readObject();314logln(it2.Now());315istream.close();316logln("Loaded ok.");317} catch (Exception foo) {318errln("Test for bug 4069754 or 4057878 failed => Exception: " + foo.getMessage());319}320}321322/**323* DecimalFormat.applyPattern(String) allows illegal patterns324*/325public void Test4087251 (){326DecimalFormat df = new DecimalFormat();327try {328df.applyPattern("#.#.#");329logln("toPattern() returns \"" + df.toPattern() + "\"");330errln("applyPattern(\"#.#.#\") doesn't throw IllegalArgumentException");331} catch (IllegalArgumentException e) {332logln("Caught Illegal Argument Error !");333}334// Second test; added 5/11/98 when reported to fail on 1.2b3335try {336df.applyPattern("#0.0#0#0");337logln("toPattern() returns \"" + df.toPattern() + "\"");338errln("applyPattern(\"#0.0#0#0\") doesn't throw IllegalArgumentException");339} catch (IllegalArgumentException e) {340logln("Ok - IllegalArgumentException for #0.0#0#0");341}342}343344/**345* DecimalFormat.format() loses precision346*/347public void Test4090489 (){348Locale savedLocale = Locale.getDefault();349Locale.setDefault(Locale.US);350DecimalFormat df = new DecimalFormat();351df.setMinimumFractionDigits(10);352df.setGroupingUsed(false);353double d = 1.000000000000001E7;354BigDecimal bd = new BigDecimal(d);355StringBuffer sb = new StringBuffer("");356FieldPosition fp = new FieldPosition(0);357logln("d = " + d);358logln("BigDecimal.toString(): " + bd.toString());359df.format(d, sb, fp);360if (!sb.toString().equals("10000000.0000000100")) {361errln("DecimalFormat.format(): " + sb.toString());362}363Locale.setDefault(savedLocale);364}365366/**367* DecimalFormat.format() loses precision368*/369public void Test4090504 ()370{371double d = 1;372logln("d = " + d);373DecimalFormat df = new DecimalFormat();374StringBuffer sb;375FieldPosition fp;376try {377for (int i = 17; i <= 20; i++) {378df.setMaximumFractionDigits(i);379sb = new StringBuffer("");380fp = new FieldPosition(0);381logln(" getMaximumFractionDigits() = " + i);382logln(" formated: " + df.format(d, sb, fp));383}384} catch (Exception foo) {385errln("Bug 4090504 regression test failed. Message : " + foo.getMessage());386}387}388/**389* DecimalFormat.parse(String str, ParsePosition pp) loses precision390*/391public void Test4095713 ()392{393Locale savedLocale = Locale.getDefault();394Locale.setDefault(Locale.US);395DecimalFormat df = new DecimalFormat();396String str = "0.1234";397Double d1 = 0.1234;398Double d2 = (Double) df.parse(str, new ParsePosition(0));399logln(d1.toString());400if (d2.doubleValue() != d1.doubleValue())401errln("Bug 4095713 test failed, new double value : " + d2);402Locale.setDefault(savedLocale);403}404405/**406* DecimalFormat.parse() fails when multiplier is not set to 1407*/408public void Test4092561 ()409{410Locale savedLocale = Locale.getDefault();411Locale.setDefault(Locale.US);412DecimalFormat df = new DecimalFormat();413414String str = Long.toString(Long.MIN_VALUE);415logln("Long.MIN_VALUE : " + df.parse(str, new ParsePosition(0)).toString());416df.setMultiplier(100);417Number num = df.parse(str, new ParsePosition(0));418if (num.doubleValue() != -9.223372036854776E16) {419errln("Bug 4092561 test failed when multiplier is not set to 1. Expected: -9.223372036854776E16, got: " + num.doubleValue());420}421422df.setMultiplier(-100);423num = df.parse(str, new ParsePosition(0));424if (num.doubleValue() != 9.223372036854776E16) {425errln("Bug 4092561 test failed when multiplier is not set to 1. Expected: 9.223372036854776E16, got: " + num.doubleValue());426}427428str = Long.toString(Long.MAX_VALUE);429logln("Long.MAX_VALUE : " + df.parse(str, new ParsePosition(0)).toString());430431df.setMultiplier(100);432num = df.parse(str, new ParsePosition(0));433if (num.doubleValue() != 9.223372036854776E16) {434errln("Bug 4092561 test failed when multiplier is not set to 1. Expected: 9.223372036854776E16, got: " + num.doubleValue());435}436437df.setMultiplier(-100);438num = df.parse(str, new ParsePosition(0));439if (num.doubleValue() != -9.223372036854776E16) {440errln("Bug 4092561 test failed when multiplier is not set to 1. Expected: -9.223372036854776E16, got: " + num.doubleValue());441}442443Locale.setDefault(savedLocale);444}445446/**447* DecimalFormat: Negative format ignored.448*/449public void Test4092480 ()450{451DecimalFormat dfFoo = new DecimalFormat("000");452453try {454dfFoo.applyPattern("0000;-000");455if (!dfFoo.toPattern().equals("#0000"))456errln("dfFoo.toPattern : " + dfFoo.toPattern());457logln(dfFoo.format(42));458logln(dfFoo.format(-42));459dfFoo.applyPattern("000;-000");460if (!dfFoo.toPattern().equals("#000"))461errln("dfFoo.toPattern : " + dfFoo.toPattern());462logln(dfFoo.format(42));463logln(dfFoo.format(-42));464465dfFoo.applyPattern("000;-0000");466if (!dfFoo.toPattern().equals("#000"))467errln("dfFoo.toPattern : " + dfFoo.toPattern());468logln(dfFoo.format(42));469logln(dfFoo.format(-42));470471dfFoo.applyPattern("0000;-000");472if (!dfFoo.toPattern().equals("#0000"))473errln("dfFoo.toPattern : " + dfFoo.toPattern());474logln(dfFoo.format(42));475logln(dfFoo.format(-42));476} catch (Exception foo) {477errln("Message " + foo.getMessage());478}479}480/**481* NumberFormat.getCurrencyInstance() produces format that uses482* decimal separator instead of monetary decimal separator.483*484* Rewrote this test not to depend on the actual pattern. Pattern should485* never contain the monetary separator! Decimal separator in pattern is486* interpreted as monetary separator if currency symbol is seen!487*/488public void Test4087244 () {489Locale de = new Locale("pt", "PT");490DecimalFormat df = (DecimalFormat) NumberFormat.getCurrencyInstance(de);491DecimalFormatSymbols sym = df.getDecimalFormatSymbols();492sym.setMonetaryDecimalSeparator('$');493df.setDecimalFormatSymbols(sym);494char decSep = sym.getDecimalSeparator();495char monSep = sym.getMonetaryDecimalSeparator();496char zero = sym.getZeroDigit();497if (decSep == monSep) {498errln("ERROR in test: want decimal sep != monetary sep");499} else {500df.setMinimumIntegerDigits(1);501df.setMinimumFractionDigits(2);502String str = df.format(1.23);503String monStr = "1" + monSep + "23";504String decStr = "1" + decSep + "23";505if (str.indexOf(monStr) >= 0 && str.indexOf(decStr) < 0) {506logln("OK: 1.23 -> \"" + str + "\" contains \"" +507monStr + "\" and not \"" + decStr + '"');508} else {509errln("FAIL: 1.23 -> \"" + str + "\", should contain \"" +510monStr +511"\" and not \"" + decStr + '"');512}513}514}515/**516* Number format data rounding errors for locale FR517*/518public void Test4070798 () {519NumberFormat formatter;520String tempString;521/* User error :522String expectedDefault = "-5\u00a0789,987";523String expectedCurrency = "5\u00a0789,98 F";524String expectedPercent = "-578\u00a0998%";525*/526String expectedDefault = "-5\u00a0789,988";527String expectedCurrency = "5\u00a0789,99 \u20AC";528// changed for bug 6547501529String expectedPercent = "-578\u00a0999 %";530531formatter = NumberFormat.getNumberInstance(Locale.FRANCE);532tempString = formatter.format (-5789.9876);533534if (tempString.equals(expectedDefault)) {535logln ("Bug 4070798 default test passed.");536} else {537errln("Failed:" +538" Expected " + expectedDefault +539" Received " + tempString );540}541542543formatter = NumberFormat.getCurrencyInstance(Locale.FRANCE);544tempString = formatter.format( 5789.9876 );545546if (tempString.equals(expectedCurrency) ) {547logln ("Bug 4070798 currency test assed.");548} else {549errln("Failed:" +550" Expected " + expectedCurrency +551" Received " + tempString );552}553554555formatter = NumberFormat.getPercentInstance(Locale.FRANCE);556tempString = formatter.format (-5789.9876);557558if (tempString.equals(expectedPercent) ) {559logln ("Bug 4070798 percentage test passed.");560} else {561errln("Failed:" +562" Expected " + expectedPercent +563" Received " + tempString );564}565}566/**567* Data rounding errors for French (Canada) locale568*/569public void Test4071005 () {570571NumberFormat formatter;572String tempString;573/* user error :574String expectedDefault = "-5 789,987";575String expectedCurrency = "5 789,98 $";576String expectedPercent = "-578 998%";577*/578String expectedDefault = "-5\u00a0789,988";579String expectedCurrency = "5\u00a0789,99 $";580// changed for bug 6547501581String expectedPercent = "-578\u00a0999 %";582583formatter = NumberFormat.getNumberInstance(Locale.CANADA_FRENCH);584tempString = formatter.format (-5789.9876);585if (tempString.equals(expectedDefault)) {586logln ("Bug 4071005 default test passed.");587} else {588errln("Failed:" +589" Expected " + expectedDefault +590" Received " + tempString );591}592593formatter = NumberFormat.getCurrencyInstance(Locale.CANADA_FRENCH);594tempString = formatter.format( 5789.9876 ) ;595596if (tempString.equals(expectedCurrency) ) {597logln ("Bug 4071005 currency test passed.");598} else {599errln("Failed:" +600" Expected " + expectedCurrency +601" Received " + tempString );602}603formatter = NumberFormat.getPercentInstance(Locale.CANADA_FRENCH);604tempString = formatter.format (-5789.9876);605606if (tempString.equals(expectedPercent) ) {607logln ("Bug 4071005 percentage test passed.");608} else {609errln("Failed:" +610" Expected " + expectedPercent +611" Received " + tempString );612}613}614615/**616* Data rounding errors for German (Germany) locale617*/618public void Test4071014 () {619NumberFormat formatter;620String tempString;621/* user error :622String expectedDefault = "-5.789,987";623String expectedCurrency = "5.789,98 DM";624String expectedPercent = "-578.998%";625*/626String expectedDefault = "-5.789,988";627String expectedCurrency = "5.789,99 \u20AC";628String expectedPercent = "-578.999%";629630formatter = NumberFormat.getNumberInstance(Locale.GERMANY);631tempString = formatter.format (-5789.9876);632633if (tempString.equals(expectedDefault)) {634logln ("Bug 4071014 default test passed.");635} else {636errln("Failed:" +637" Expected " + expectedDefault +638" Received " + tempString );639}640641formatter = NumberFormat.getCurrencyInstance(Locale.GERMANY);642tempString = formatter.format( 5789.9876 ) ;643644if (tempString.equals(expectedCurrency) ) {645logln ("Bug 4071014 currency test passed.");646} else {647errln("Failed:" +648" Expected " + expectedCurrency +649" Received " + tempString );650}651652formatter = NumberFormat.getPercentInstance(Locale.GERMANY);653tempString = formatter.format (-5789.9876);654655if (tempString.equals(expectedPercent) ) {656logln ("Bug 4071014 percentage test passed.");657} else {658errln("Failed:" +659" Expected " + expectedPercent +660" Received " + tempString );661}662663}664/**665* Data rounding errors for Italian locale number formats666*/667public void Test4071859 () {668NumberFormat formatter;669String tempString;670/* user error :671String expectedDefault = "-5.789,987";672String expectedCurrency = "-L. 5.789,98";673String expectedPercent = "-578.998%";674*/675String expectedDefault = "-5.789,988";676String expectedCurrency = "-\u20AC 5.789,99";677String expectedPercent = "-578.999%";678679formatter = NumberFormat.getNumberInstance(Locale.ITALY);680tempString = formatter.format (-5789.9876);681682if (tempString.equals(expectedDefault)) {683logln ("Bug 4071859 default test passed.");684} else {685errln("Failed:" +686" Expected " + expectedDefault +687" Received " + tempString );688}689690formatter = NumberFormat.getCurrencyInstance(Locale.ITALY);691tempString = formatter.format( -5789.9876 ) ;692693if (tempString.equals(expectedCurrency) ) {694logln ("Bug 4071859 currency test passed.");695} else {696errln("Failed:" +697" Expected " + expectedCurrency +698" Received " + tempString );699}700701formatter = NumberFormat.getPercentInstance(Locale.ITALY);702tempString = formatter.format (-5789.9876);703704if (tempString.equals(expectedPercent) ) {705logln ("Bug 4071859 percentage test passed.");706} else {707errln("Failed:" +708" Expected " + expectedPercent +709" Received " + tempString );710}711712}713714/* bug 4071859715* Test rounding for nearest even.716*/717public void Test4093610()718{719Locale savedLocale = Locale.getDefault();720Locale.setDefault(Locale.US);721DecimalFormat df = new DecimalFormat("#0.#");722723roundingTest(df, 12.15, "12.2"); // Rounding-up. Above tie (12.150..)724roundingTest(df, 12.25, "12.2"); // No round-up. Exact + half-even rule.725roundingTest(df, 12.45, "12.4"); // No round-up. Below tie (12.449..)726roundingTest(df, 12.450000001,"12.5"); // Rounding-up. Above tie.727roundingTest(df, 12.55, "12.6"); // Rounding-up. Above tie (12.550..)728roundingTest(df, 12.650000001,"12.7"); // Rounding-up. Above tie.729roundingTest(df, 12.75, "12.8"); // Rounding-up. Exact + half-even rule.730roundingTest(df, 12.750000001,"12.8"); // Rounding-up. Above tie.731roundingTest(df, 12.85, "12.8"); // No round-up. Below tie (12.849..)732roundingTest(df, 12.850000001,"12.9"); // Rounding-up. Above tie.733roundingTest(df, 12.950000001,"13"); // Rounding-up. Above tie.734735Locale.setDefault(savedLocale);736}737738void roundingTest(DecimalFormat df, double x, String expected)739{740String out = df.format(x);741logln("" + x + " formats with 1 fractional digits to " + out);742if (!out.equals(expected)) errln("FAIL: Expected " + expected);743}744/**745* Tests the setMaximumFractionDigits limit.746*/747public void Test4098741()748{749try {750NumberFormat fmt = NumberFormat.getPercentInstance();751fmt.setMaximumFractionDigits(20);752logln(fmt.format(.001));753} catch (Exception foo) {754errln("Bug 4098471 failed with exception thrown : " + foo.getMessage());755}756}757/**758* Tests illegal pattern exception.759* Fix comment : HShih A31 Part1 will not be fixed and javadoc needs to be updated.760* Part2 has been fixed.761*/762public void Test4074454()763{764Locale savedLocale = Locale.getDefault();765Locale.setDefault(Locale.US);766try {767DecimalFormat fmt = new DecimalFormat("#,#00.00;-#.#");768logln("Inconsistent negative pattern is fine.");769DecimalFormat newFmt = new DecimalFormat("#,#00.00 p''ieces;-#,#00.00 p''ieces");770String tempString = newFmt.format(3456.78);771if (!tempString.equals("3,456.78 p'ieces"))772errln("Failed! 3,456.78 p'ieces expected, but got : " + tempString);773} catch (Exception foo) {774errln("An exception was thrown for any inconsistent negative pattern.");775}776Locale.setDefault(savedLocale);777}778779/**780* Tests all different comments.781* Response to some comments :782* [1] DecimalFormat.parse API documentation is more than just one line.783* This is not a reproducable doc error in 116 source code.784* [2] See updated javadoc.785* [3] Fixed.786* [4] NumberFormat.parse(String, ParsePosition) : If parsing fails,787* a null object will be returned. The unchanged parse position also788* reflects an error.789* NumberFormat.parse(String) : If parsing fails, an ParseException790* will be thrown.791* See updated javadoc for more details.792* [5] See updated javadoc.793* [6] See updated javadoc.794* [7] This is a correct behavior if the DateFormat object is linient.795* Otherwise, an IllegalArgumentException will be thrown when formatting796* "January 35". See GregorianCalendar class javadoc for more details.797*/798public void Test4099404()799{800try {801DecimalFormat fmt = new DecimalFormat("000.0#0");802errln("Bug 4099404 failed applying illegal pattern \"000.0#0\"");803} catch (Exception foo) {804logln("Bug 4099404 pattern \"000.0#0\" passed");805}806try {807DecimalFormat fmt = new DecimalFormat("0#0.000");808errln("Bug 4099404 failed applying illegal pattern \"0#0.000\"");809} catch (Exception foo) {810logln("Bug 4099404 pattern \"0#0.000\" passed");811}812}813/**814* DecimalFormat.applyPattern doesn't set minimum integer digits815*/816public void Test4101481()817{818DecimalFormat sdf = new DecimalFormat("#,##0");819if (sdf.getMinimumIntegerDigits() != 1)820errln("Minimum integer digits : " + sdf.getMinimumIntegerDigits());821}822/**823* Tests ParsePosition.setErrorPosition() and ParsePosition.getErrorPosition().824*/825public void Test4052223()826{827try {828DecimalFormat fmt = new DecimalFormat("#,#00.00");829Number num = fmt.parse("abc3");830errln("Bug 4052223 failed : can't parse string \"a\". Got " + num);831} catch (ParseException foo) {832logln("Caught expected ParseException : " + foo.getMessage() + " at index : " + foo.getErrorOffset());833}834}835/**836* API tests for API addition request A9.837*/838public void Test4061302()839{840DecimalFormatSymbols fmt = DecimalFormatSymbols.getInstance();841String currency = fmt.getCurrencySymbol();842String intlCurrency = fmt.getInternationalCurrencySymbol();843char monDecSeparator = fmt.getMonetaryDecimalSeparator();844if (currency.equals("") ||845intlCurrency.equals("") ||846monDecSeparator == 0) {847errln("getCurrencySymbols failed, got empty string.");848}849logln("Before set ==> Currency : " + currency + " Intl Currency : " + intlCurrency + " Monetary Decimal Separator : " + monDecSeparator);850fmt.setCurrencySymbol("XYZ");851fmt.setInternationalCurrencySymbol("ABC");852fmt.setMonetaryDecimalSeparator('*');853currency = fmt.getCurrencySymbol();854intlCurrency = fmt.getInternationalCurrencySymbol();855monDecSeparator = fmt.getMonetaryDecimalSeparator();856if (!currency.equals("XYZ") ||857!intlCurrency.equals("ABC") ||858monDecSeparator != '*') {859errln("setCurrencySymbols failed.");860}861logln("After set ==> Currency : " + currency + " Intl Currency : " + intlCurrency + " Monetary Decimal Separator : " + monDecSeparator);862}863/**864* API tests for API addition request A23. FieldPosition.getBeginIndex and865* FieldPosition.getEndIndex.866*/867public void Test4062486()868{869DecimalFormat fmt = new DecimalFormat("#,##0.00");870StringBuffer formatted = new StringBuffer();871FieldPosition field = new FieldPosition(0);872Double num = 1234.5;873fmt.format(num, formatted, field);874if (field.getBeginIndex() != 0 && field.getEndIndex() != 5)875errln("Format 1234.5 failed. Begin index: " + field.getBeginIndex() + " End index: " + field.getEndIndex());876field.setBeginIndex(7);877field.setEndIndex(4);878if (field.getBeginIndex() != 7 && field.getEndIndex() != 4)879errln("Set begin/end field indexes failed. Begin index: " + field.getBeginIndex() + " End index: " + field.getEndIndex());880}881882/**883* DecimalFormat.parse incorrectly works with a group separator.884*/885public void Test4108738()886{887888DecimalFormat df = new DecimalFormat("#,##0.###",889DecimalFormatSymbols.getInstance(java.util.Locale.US));890String text = "1.222,111";891Number num = df.parse(text,new ParsePosition(0));892if (!num.toString().equals("1.222"))893errln("\"" + text + "\" is parsed as " + num);894text = "1.222x111";895num = df.parse(text,new ParsePosition(0));896if (!num.toString().equals("1.222"))897errln("\"" + text + "\" is parsed as " + num);898}899900/**901* DecimalFormat.format() incorrectly formats negative doubles.902*/903public void Test4106658()904{905Locale savedLocale = Locale.getDefault();906Locale.setDefault(Locale.US);907DecimalFormat df = new DecimalFormat(); // Corrected; see 4147706908double d1 = -0.0;909double d2 = -0.0001;910StringBuffer buffer = new StringBuffer();911logln("pattern: \"" + df.toPattern() + "\"");912df.format(d1, buffer, new FieldPosition(0));913if (!buffer.toString().equals("-0")) { // Corrected; see 4147706914errln(d1 + " is formatted as " + buffer);915}916buffer.setLength(0);917df.format(d2, buffer, new FieldPosition(0));918if (!buffer.toString().equals("-0")) { // Corrected; see 4147706919errln(d2 + " is formatted as " + buffer);920}921Locale.setDefault(savedLocale);922}923924/**925* DecimalFormat.parse returns 0 if string parameter is incorrect.926*/927public void Test4106662()928{929DecimalFormat df = new DecimalFormat();930String text = "x";931ParsePosition pos1 = new ParsePosition(0), pos2 = new ParsePosition(0);932933logln("pattern: \"" + df.toPattern() + "\"");934Number num = df.parse(text, pos1);935if (num != null) {936errln("Test Failed: \"" + text + "\" is parsed as " + num);937}938df = null;939df = new DecimalFormat("$###.00");940num = df.parse("$", pos2);941if (num != null){942errln("Test Failed: \"$\" is parsed as " + num);943}944}945946/**947* NumberFormat.parse doesn't return null948*/949public void Test4114639()950{951NumberFormat format = NumberFormat.getInstance();952String text = "time 10:x";953ParsePosition pos = new ParsePosition(8);954Number result = format.parse(text, pos);955if (result != null) errln("Should return null but got : " + result); // Should be null; it isn't956}957958/**959* DecimalFormat.format(long n) fails if n * multiplier > MAX_LONG.960*/961public void Test4106664()962{963DecimalFormat df = new DecimalFormat();964long n = 1234567890123456L;965int m = 12345678;966BigInteger bigN = BigInteger.valueOf(n);967bigN = bigN.multiply(BigInteger.valueOf(m));968df.setMultiplier(m);969df.setGroupingUsed(false);970logln("formated: " +971df.format(n, new StringBuffer(), new FieldPosition(0)));972logln("expected: " + bigN.toString());973}974/**975* DecimalFormat.format incorrectly formats -0.0.976*/977public void Test4106667()978{979Locale savedLocale = Locale.getDefault();980Locale.setDefault(Locale.US);981DecimalFormat df = new DecimalFormat();982df.setPositivePrefix("+");983double d = -0.0;984logln("pattern: \"" + df.toPattern() + "\"");985StringBuffer buffer = new StringBuffer();986df.format(d, buffer, new FieldPosition(0));987if (!buffer.toString().equals("-0")) { // Corrected; see 4147706988errln(d + " is formatted as " + buffer);989}990Locale.setDefault(savedLocale);991}992993/**994* DecimalFormat.setMaximumIntegerDigits() works incorrectly.995*/996public void Test4110936()997{998NumberFormat nf = NumberFormat.getInstance();999nf.setMaximumIntegerDigits(128);1000logln("setMaximumIntegerDigits(128)");1001if (nf.getMaximumIntegerDigits() != 128)1002errln("getMaximumIntegerDigits() returns " +1003nf.getMaximumIntegerDigits());1004}10051006/**1007* Locale data should use generic currency symbol1008*1009* 1) Make sure that all currency formats use the generic currency symbol.1010* 2) Make sure we get the same results using the generic symbol or a1011* hard-coded one.1012*/1013public void Test4122840()1014{1015Locale[] locales = NumberFormat.getAvailableLocales();10161017for (int i = 0; i < locales.length; i++) {1018ResourceBundle rb = LocaleData.getBundle("sun.text.resources.FormatData",1019locales[i]);1020//1021// Get the currency pattern for this locale. We have to fish it1022// out of the ResourceBundle directly, since DecimalFormat.toPattern1023// will return the localized symbol, not \00a41024//1025String[] numPatterns = (String[])rb.getObject("NumberPatterns");1026String pattern = numPatterns[1];10271028if (pattern.indexOf("\u00A4") == -1 ) {1029errln("Currency format for " + locales[i] +1030" does not contain generic currency symbol:" +1031pattern );1032}10331034// Create a DecimalFormat using the pattern we got and format a number1035DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(locales[i]);1036DecimalFormat fmt1 = new DecimalFormat(pattern, symbols);10371038String result1 = fmt1.format(1.111);10391040//1041// Now substitute in the locale's currency symbol and create another1042// pattern. Replace the decimal separator with the monetary separator.1043//1044char decSep = symbols.getDecimalSeparator();1045char monSep = symbols.getMonetaryDecimalSeparator();1046StringBuffer buf = new StringBuffer(pattern);1047for (int j = 0; j < buf.length(); j++) {1048if (buf.charAt(j) == '\u00a4') {1049String cur = "'" + symbols.getCurrencySymbol() + "'";1050buf.replace(j, j+1, cur);1051j += cur.length() - 1;1052}1053}1054symbols.setDecimalSeparator(monSep);1055DecimalFormat fmt2 = new DecimalFormat(buf.toString(), symbols);10561057String result2 = fmt2.format(1.111);10581059if (!result1.equals(result2)) {1060errln("Results for " + locales[i] + " differ: " +1061result1 + " vs " + result2);1062}1063}1064}10651066/**1067* DecimalFormat.format() delivers wrong string.1068*/1069public void Test4125885()1070{1071Locale savedLocale = Locale.getDefault();1072Locale.setDefault(Locale.US);1073double rate = 12.34;1074DecimalFormat formatDec = new DecimalFormat ("000.00");1075logln("toPattern: " + formatDec.toPattern());1076String rateString= formatDec.format(rate);1077if (!rateString.equals("012.34"))1078errln("result : " + rateString + " expected : 012.34");1079rate = 0.1234;1080formatDec = null;1081formatDec = new DecimalFormat ("+000.00%;-000.00%");1082logln("toPattern: " + formatDec.toPattern());1083rateString= formatDec.format(rate);1084if (!rateString.equals("+012.34%"))1085errln("result : " + rateString + " expected : +012.34%");1086Locale.setDefault(savedLocale);1087}10881089/**1090**1091* DecimalFormat produces extra zeros when formatting numbers.1092*/1093public void Test4134034() {1094Locale savedLocale = Locale.getDefault();1095Locale.setDefault(Locale.US);1096DecimalFormat nf = new DecimalFormat("##,###,###.00");10971098String f = nf.format(9.02);1099if (f.equals("9.02")) logln(f + " ok"); else errln("9.02 -> " + f + "; want 9.02");11001101f = nf.format(0);1102if (f.equals(".00")) logln(f + " ok"); else errln("0 -> " + f + "; want .00");1103Locale.setDefault(savedLocale);1104}11051106/**1107* CANNOT REPRODUCE - This bug could not be reproduced. It may be1108* a duplicate of 4134034.1109*1110* JDK 1.1.6 Bug, did NOT occur in 1.1.51111* Possibly related to bug 4125885.1112*1113* This class demonstrates a regression in version 1.1.61114* of DecimalFormat class.1115*1116* 1.1.6 Results1117* Value 1.2 Format #.00 Result '01.20' !!!wrong1118* Value 1.2 Format 0.00 Result '001.20' !!!wrong1119* Value 1.2 Format 00.00 Result '0001.20' !!!wrong1120* Value 1.2 Format #0.0# Result '1.2'1121* Value 1.2 Format #0.00 Result '001.20' !!!wrong1122*1123* 1.1.5 Results1124* Value 1.2 Format #.00 Result '1.20'1125* Value 1.2 Format 0.00 Result '1.20'1126* Value 1.2 Format 00.00 Result '01.20'1127* Value 1.2 Format #0.0# Result '1.2'1128* Value 1.2 Format #0.00 Result '1.20'1129*/1130public void Test4134300() {1131Locale savedLocale = Locale.getDefault();1132Locale.setDefault(Locale.US);1133String[] DATA = {1134// Pattern Expected string1135"#.00", "1.20",1136"0.00", "1.20",1137"00.00", "01.20",1138"#0.0#", "1.2",1139"#0.00", "1.20",1140};1141for (int i=0; i<DATA.length; i+=2) {1142String result = new DecimalFormat(DATA[i]).format(1.2);1143if (!result.equals(DATA[i+1])) {1144errln("Fail: 1.2 x " + DATA[i] + " = " + result +1145"; want " + DATA[i+1]);1146}1147else {1148logln("Ok: 1.2 x " + DATA[i] + " = " + result);1149}1150}1151Locale.setDefault(savedLocale);1152}11531154/**1155* Empty pattern produces double negative prefix.1156*/1157public void Test4140009() {1158for (int i=0; i<2; ++i) {1159DecimalFormat f = null;1160switch (i) {1161case 0:1162f = new DecimalFormat("",1163DecimalFormatSymbols.getInstance(Locale.ENGLISH));1164break;1165case 1:1166f = new DecimalFormat("#.#",1167DecimalFormatSymbols.getInstance(Locale.ENGLISH));1168f.applyPattern("");1169break;1170}1171String s = f.format(123.456);1172if (!s.equals("123.456"))1173errln("Fail: Format empty pattern x 123.456 => " + s);1174s = f.format(-123.456);1175if (!s.equals("-123.456"))1176errln("Fail: Format empty pattern x -123.456 => " + s);1177}1178}11791180/**1181* BigDecimal numbers get their fractions truncated by NumberFormat.1182*/1183public void Test4141750() {1184try {1185String str = "12345.67";1186BigDecimal bd = new BigDecimal(str);1187NumberFormat nf = NumberFormat.getInstance(Locale.US);1188String sd = nf.format(bd);1189if (!sd.endsWith("67")) {1190errln("Fail: " + str + " x format -> " + sd);1191}1192}1193catch (Exception e) {1194errln(e.toString());1195e.printStackTrace();1196}1197}11981199/**1200* DecimalFormat toPattern() doesn't quote special characters or handle1201* single quotes.1202*/1203public void Test4145457() {1204try {1205DecimalFormat nf = (DecimalFormat)NumberFormat.getInstance();1206DecimalFormatSymbols sym = nf.getDecimalFormatSymbols();1207sym.setDecimalSeparator('\'');1208nf.setDecimalFormatSymbols(sym);1209double pi = 3.14159;12101211String[] PATS = { "#.00 'num''ber'", "''#.00''" };12121213for (int i=0; i<PATS.length; ++i) {1214nf.applyPattern(PATS[i]);1215String out = nf.format(pi);1216String pat = nf.toPattern();1217double val = nf.parse(out).doubleValue();12181219nf.applyPattern(pat);1220String out2 = nf.format(pi);1221String pat2 = nf.toPattern();1222double val2 = nf.parse(out2).doubleValue();12231224if (!pat.equals(pat2))1225errln("Fail with \"" + PATS[i] + "\": Patterns should concur, \"" +1226pat + "\" vs. \"" + pat2 + "\"");1227else1228logln("Ok \"" + PATS[i] + "\" toPattern() -> \"" + pat + '"');12291230if (val == val2 && out.equals(out2)) {1231logln("Ok " + pi + " x \"" + PATS[i] + "\" -> \"" +1232out + "\" -> " + val + " -> \"" +1233out2 + "\" -> " + val2);1234}1235else {1236errln("Fail " + pi + " x \"" + PATS[i] + "\" -> \"" +1237out + "\" -> " + val + " -> \"" +1238out2 + "\" -> " + val2);1239}1240}1241}1242catch (ParseException e) {1243errln("Fail: " + e);1244e.printStackTrace();1245}1246}12471248/**1249* DecimalFormat.applyPattern() sets minimum integer digits incorrectly.1250* CANNOT REPRODUCE1251* This bug is a duplicate of 4139344, which is a duplicate of 41343001252*/1253public void Test4147295() {1254DecimalFormat sdf = new DecimalFormat();1255String pattern = "#,###";1256logln("Applying pattern \"" + pattern + "\"");1257sdf.applyPattern(pattern);1258int minIntDig = sdf.getMinimumIntegerDigits();1259if (minIntDig != 0) {1260errln("Test failed");1261errln(" Minimum integer digits : " + minIntDig);1262errln(" new pattern: " + sdf.toPattern());1263} else {1264logln("Test passed");1265logln(" Minimum integer digits : " + minIntDig);1266}1267}12681269/**1270* DecimalFormat formats -0.0 as +0.01271* See also older related bug 4106658, 41066671272*/1273public void Test4147706() {1274DecimalFormat df = new DecimalFormat("#,##0.0##");1275df.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.ENGLISH));1276double d1 = -0.0;1277double d2 = -0.0001;1278StringBuffer f1 = df.format(d1, new StringBuffer(), new FieldPosition(0));1279StringBuffer f2 = df.format(d2, new StringBuffer(), new FieldPosition(0));1280if (!f1.toString().equals("-0.0")) {1281errln(d1 + " x \"" + df.toPattern() + "\" is formatted as \"" + f1 + '"');1282}1283if (!f2.toString().equals("-0.0")) {1284errln(d2 + " x \"" + df.toPattern() + "\" is formatted as \"" + f2 + '"');1285}1286}12871288/**1289* NumberFormat cannot format Double.MAX_VALUE1290*/1291public void Test4162198() {1292double dbl = Double.MAX_VALUE;1293NumberFormat f = NumberFormat.getInstance();1294f.setMaximumFractionDigits(Integer.MAX_VALUE);1295f.setMaximumIntegerDigits(Integer.MAX_VALUE);1296String s = f.format(dbl);1297logln("The number " + dbl + " formatted to " + s);1298Number n = null;1299try {1300n = f.parse(s);1301} catch (java.text.ParseException e) {1302errln("Caught a ParseException:");1303e.printStackTrace();1304}1305logln("The string " + s + " parsed as " + n);1306if (n.doubleValue() != dbl) {1307errln("Round trip failure");1308}1309}13101311/**1312* NumberFormat does not parse negative zero.1313*/1314public void Test4162852() throws ParseException {1315for (int i=0; i<2; ++i) {1316NumberFormat f = (i == 0) ? NumberFormat.getInstance()1317: NumberFormat.getPercentInstance();1318double d = -0.0;1319String s = f.format(d);1320double e = f.parse(s).doubleValue();1321logln("" +1322d + " -> " +1323'"' + s + '"' + " -> " +1324e);1325if (e != 0.0 || 1.0/e > 0.0) {1326logln("Failed to parse negative zero");1327}1328}1329}13301331/**1332* NumberFormat truncates data1333*/1334public void Test4167494() throws Exception {1335NumberFormat fmt = NumberFormat.getInstance(Locale.US);13361337double a = Double.MAX_VALUE;1338String s = fmt.format(a);1339double b = fmt.parse(s).doubleValue();1340boolean match = a == b;1341if (match) {1342logln("" + a + " -> \"" + s + "\" -> " + b + " ok");1343} else {1344errln("" + a + " -> \"" + s + "\" -> " + b + " FAIL");1345}13461347// We don't test Double.MIN_VALUE because the locale data for the US1348// currently doesn't specify enough digits to display Double.MIN_VALUE.1349// This is correct for now; however, we leave this here as a reminder1350// in case we want to address this later.1351if (false) {1352a = Double.MIN_VALUE;1353s = fmt.format(a);1354b = fmt.parse(s).doubleValue();1355match = a == b;1356if (match) {1357logln("" + a + " -> \"" + s + "\" -> " + b + " ok");1358} else {1359errln("" + a + " -> \"" + s + "\" -> " + b + " FAIL");1360}1361}1362}13631364/**1365* DecimalFormat.parse() fails when ParseIntegerOnly set to true1366*/1367public void Test4170798() {1368Locale savedLocale = Locale.getDefault();1369Locale.setDefault(Locale.US);1370DecimalFormat df = new DecimalFormat();1371df.setParseIntegerOnly(true);1372Number n = df.parse("-0.0", new ParsePosition(0));1373if (!(n instanceof Long || n instanceof Integer)1374|| n.intValue() != 0) {1375errln("FAIL: parse(\"-0.0\") returns " +1376n + " (" + n.getClass().getName() + ')');1377}1378Locale.setDefault(savedLocale);1379}13801381/**1382* toPattern only puts the first grouping separator in.1383*/1384public void Test4176114() {1385String[] DATA = {1386"00", "#00",1387"000", "#000", // No grouping1388"#000", "#000", // No grouping1389"#,##0", "#,##0",1390"#,000", "#,000",1391"0,000", "#0,000",1392"00,000", "#00,000",1393"000,000", "#,000,000",1394"0,000,000,000,000.0000", "#0,000,000,000,000.0000", // Reported1395};1396for (int i=0; i<DATA.length; i+=2) {1397DecimalFormat df = new DecimalFormat(DATA[i]);1398String s = df.toPattern();1399if (!s.equals(DATA[i+1])) {1400errln("FAIL: " + DATA[i] + " -> " + s + ", want " + DATA[i+1]);1401}1402}1403}14041405/**1406* DecimalFormat is incorrectly rounding numbers like 1.2501 to 1.21407*/1408public void Test4179818() {1409String DATA[] = {1410// Input Pattern Expected output1411"1.2511", "#.#", "1.3",1412"1.2501", "#.#", "1.3",1413"0.9999", "#", "1",1414};1415DecimalFormat fmt = new DecimalFormat("#",1416DecimalFormatSymbols.getInstance(Locale.US));1417for (int i=0; i<DATA.length; i+=3) {1418double in = Double.valueOf(DATA[i]);1419String pat = DATA[i+1];1420String exp = DATA[i+2];1421fmt.applyPattern(pat);1422String out = fmt.format(in);1423if (out.equals(exp)) {1424logln("Ok: " + in + " x " + pat + " = " + out);1425} else {1426errln("FAIL: " + in + " x " + pat + " = " + out +1427", expected " + exp);1428}1429}1430}14311432public void Test4185761() throws IOException, ClassNotFoundException {1433/* Code used to write out the initial files, which are1434* then edited manually:1435NumberFormat nf = NumberFormat.getInstance(Locale.US);1436nf.setMinimumIntegerDigits(0x111); // Keep under 3091437nf.setMaximumIntegerDigits(0x112); // Keep under 3091438nf.setMinimumFractionDigits(0x113); // Keep under 3401439nf.setMaximumFractionDigits(0x114); // Keep under 3401440FileOutputStream ostream =1441new FileOutputStream("NumberFormat4185761");1442ObjectOutputStream p = new ObjectOutputStream(ostream);1443p.writeObject(nf);1444ostream.close();1445*/14461447// File minint maxint minfrac maxfrac1448// NumberFormat4185761a 0x122 0x121 0x124 0x1231449// NumberFormat4185761b 0x311 0x312 0x313 0x3141450// File a is bad because the mins are smaller than the maxes.1451// File b is bad because the values are too big for a DecimalFormat.1452// These files have a sufix ".ser.txt".14531454InputStream istream = HexDumpReader.getStreamFromHexDump("NumberFormat4185761a.ser.txt");1455ObjectInputStream p = new ObjectInputStream(istream);1456try {1457NumberFormat nf = (NumberFormat) p.readObject();1458errln("FAIL: Deserialized bogus NumberFormat int:" +1459nf.getMinimumIntegerDigits() + ".." +1460nf.getMaximumIntegerDigits() + " frac:" +1461nf.getMinimumFractionDigits() + ".." +1462nf.getMaximumFractionDigits());1463} catch (InvalidObjectException e) {1464logln("Ok: " + e.getMessage());1465}1466istream.close();14671468istream = HexDumpReader.getStreamFromHexDump("NumberFormat4185761b.ser.txt");1469p = new ObjectInputStream(istream);1470try {1471NumberFormat nf = (NumberFormat) p.readObject();1472errln("FAIL: Deserialized bogus DecimalFormat int:" +1473nf.getMinimumIntegerDigits() + ".." +1474nf.getMaximumIntegerDigits() + " frac:" +1475nf.getMinimumFractionDigits() + ".." +1476nf.getMaximumFractionDigits());1477} catch (InvalidObjectException e) {1478logln("Ok: " + e.getMessage());1479}1480istream.close();1481}148214831484/**1485* Some DecimalFormatSymbols changes are not picked up by DecimalFormat.1486* This includes the minus sign, currency symbol, international currency1487* symbol, percent, and permille. This is filed as bugs 4212072 and1488* 4212073.1489*/1490public void Test4212072() throws IOException, ClassNotFoundException {1491DecimalFormatSymbols sym = DecimalFormatSymbols.getInstance(Locale.US);1492DecimalFormat fmt = new DecimalFormat("#", sym);14931494sym.setMinusSign('^');1495fmt.setDecimalFormatSymbols(sym);1496if (!fmt.format(-1).equals("^1")) {1497errln("FAIL: -1 x (minus=^) -> " + fmt.format(-1) +1498", exp ^1");1499}1500if (!fmt.getNegativePrefix().equals("^")) {1501errln("FAIL: (minus=^).getNegativePrefix -> " +1502fmt.getNegativePrefix() + ", exp ^");1503}1504sym.setMinusSign('-');15051506fmt.applyPattern("#%");1507sym.setPercent('^');1508fmt.setDecimalFormatSymbols(sym);1509if (!fmt.format(0.25).equals("25^")) {1510errln("FAIL: 0.25 x (percent=^) -> " + fmt.format(0.25) +1511", exp 25^");1512}1513if (!fmt.getPositiveSuffix().equals("^")) {1514errln("FAIL: (percent=^).getPositiveSuffix -> " +1515fmt.getPositiveSuffix() + ", exp ^");1516}1517sym.setPercent('%');15181519fmt.applyPattern("#\u2030");1520sym.setPerMill('^');1521fmt.setDecimalFormatSymbols(sym);1522if (!fmt.format(0.25).equals("250^")) {1523errln("FAIL: 0.25 x (permill=^) -> " + fmt.format(0.25) +1524", exp 250^");1525}1526if (!fmt.getPositiveSuffix().equals("^")) {1527errln("FAIL: (permill=^).getPositiveSuffix -> " +1528fmt.getPositiveSuffix() + ", exp ^");1529}1530sym.setPerMill('\u2030');15311532fmt.applyPattern("\u00A4#.00");1533sym.setCurrencySymbol("usd");1534fmt.setDecimalFormatSymbols(sym);1535if (!fmt.format(12.5).equals("usd12.50")) {1536errln("FAIL: 12.5 x (currency=usd) -> " + fmt.format(12.5) +1537", exp usd12.50");1538}1539if (!fmt.getPositivePrefix().equals("usd")) {1540errln("FAIL: (currency=usd).getPositivePrefix -> " +1541fmt.getPositivePrefix() + ", exp usd");1542}1543sym.setCurrencySymbol("$");15441545fmt.applyPattern("\u00A4\u00A4#.00");1546sym.setInternationalCurrencySymbol("DOL");1547fmt.setDecimalFormatSymbols(sym);1548if (!fmt.format(12.5).equals("DOL12.50")) {1549errln("FAIL: 12.5 x (intlcurrency=DOL) -> " + fmt.format(12.5) +1550", exp DOL12.50");1551}1552if (!fmt.getPositivePrefix().equals("DOL")) {1553errln("FAIL: (intlcurrency=DOL).getPositivePrefix -> " +1554fmt.getPositivePrefix() + ", exp DOL");1555}1556sym.setInternationalCurrencySymbol("USD");15571558// Since the pattern logic has changed, make sure that patterns round1559// trip properly. Test stream in/out integrity too.1560Locale[] avail = NumberFormat.getAvailableLocales();1561for (int i=0; i<avail.length; ++i) {1562for (int j=0; j<3; ++j) {1563NumberFormat nf;1564switch (j) {1565case 0:1566nf = NumberFormat.getInstance(avail[i]);1567break;1568case 1:1569nf = NumberFormat.getCurrencyInstance(avail[i]);1570break;1571default:1572nf = NumberFormat.getPercentInstance(avail[i]);1573break;1574}1575DecimalFormat df = (DecimalFormat) nf;15761577// Test toPattern/applyPattern round trip1578String pat = df.toPattern();1579DecimalFormatSymbols symb = DecimalFormatSymbols.getInstance(avail[i]);1580DecimalFormat f2 = new DecimalFormat(pat, symb);1581if (!df.equals(f2)) {1582errln("FAIL: " + avail[i] + " -> \"" + pat +1583"\" -> \"" + f2.toPattern() + '"');1584}15851586// Test toLocalizedPattern/applyLocalizedPattern round trip1587pat = df.toLocalizedPattern();1588f2.applyLocalizedPattern(pat);1589if (!df.equals(f2)) {1590errln("FAIL: " + avail[i] + " -> localized \"" + pat +1591"\" -> \"" + f2.toPattern() + '"');1592}15931594// Test writeObject/readObject round trip1595ByteArrayOutputStream baos = new ByteArrayOutputStream();1596ObjectOutputStream oos = new ObjectOutputStream(baos);1597oos.writeObject(df);1598oos.flush();1599baos.close();1600byte[] bytes = baos.toByteArray();1601ObjectInputStream ois =1602new ObjectInputStream(new ByteArrayInputStream(bytes));1603f2 = (DecimalFormat) ois.readObject();1604if (!df.equals(f2)) {1605errln("FAIL: Stream in/out " + avail[i] + " -> \"" + pat +1606"\" -> " +1607(f2 != null ? ("\""+f2.toPattern()+'"') : "null"));1608}16091610}1611}1612}16131614/**1615* DecimalFormat.parse() fails for mulipliers 2^n.1616*/1617public void Test4216742() throws ParseException {1618DecimalFormat fmt = (DecimalFormat) NumberFormat.getInstance(Locale.US);1619long[] DATA = { Long.MIN_VALUE, Long.MAX_VALUE, -100000000L, 100000000L};1620for (int i=0; i<DATA.length; ++i) {1621String str = Long.toString(DATA[i]);1622for (int m = 1; m <= 100; m++) {1623fmt.setMultiplier(m);1624long n = fmt.parse(str).longValue();1625if (n > 0 != DATA[i] > 0) {1626errln("\"" + str + "\" parse(x " + fmt.getMultiplier() +1627") => " + n);1628}1629}1630}1631}16321633/**1634* DecimalFormat formats 1.001 to "1.00" instead of "1" with 2 fraction1635* digits.1636*/1637public void Test4217661() {1638Object[] DATA = {16390.001, "0",16401.001, "1",16410.006, "0.01",16421.006, "1.01",1643};1644NumberFormat fmt = NumberFormat.getInstance(Locale.US);1645fmt.setMaximumFractionDigits(2);1646for (int i=0; i<DATA.length; i+=2) {1647String s = fmt.format((Double) DATA[i]);1648if (!s.equals(DATA[i+1])) {1649errln("FAIL: Got " + s + ", exp " + DATA[i+1]);1650}1651}1652}16531654/**1655* 4243011: Formatting .5 rounds to "1" instead of "0"1656*/1657public void Test4243011() {1658Locale savedLocale = Locale.getDefault();1659Locale.setDefault(Locale.US);1660double DATA[] = {0.5, 1.5, 2.5, 3.5, 4.5};1661String EXPECTED[] = {"0.", "2.", "2.", "4.", "4."};16621663DecimalFormat format = new DecimalFormat("0.");1664for (int i = 0; i < DATA.length; i++) {1665String result = format.format(DATA[i]);1666if (result.equals(EXPECTED[i])) {1667logln("OK: got " + result);1668} else {1669errln("FAIL: got " + result);1670}1671}1672Locale.setDefault(savedLocale);1673}16741675/**1676* 4243108: format(0.0) gives "0.1" if preceded by parse("99.99")1677*/1678public void Test4243108() {1679Locale savedLocale = Locale.getDefault();1680Locale.setDefault(Locale.US);1681DecimalFormat f = new DecimalFormat("#.#");1682String result = f.format(0.0);1683if (result.equals("0")) {1684logln("OK: got " + result);1685} else {1686errln("FAIL: got " + result);1687}1688try {1689double dResult = f.parse("99.99").doubleValue();1690if (dResult == 99.99) {1691logln("OK: got " + dResult);1692} else {1693errln("FAIL: got " + dResult);1694}1695} catch (ParseException e) {1696errln("Caught a ParseException:");1697e.printStackTrace();1698}1699result = f.format(0.0);1700if (result.equals("0")) {1701logln("OK: got " + result);1702} else {1703errln("FAIL: got " + result);1704}1705Locale.setDefault(savedLocale);1706}17071708/**1709* 4330377: DecimalFormat engineering notation gives incorrect results1710*/1711public void test4330377() {1712Locale savedLocale = Locale.getDefault();1713Locale.setDefault(Locale.US);1714double[] input = {5000.0, 500.0, 50.0, 5.0, 0.5, 0.05, 0.005, 0.0005,17155050.0, 505.0, 50.5, 5.05, 0.505, 0.0505, 0.00505, 0.000505};1716String[] pattern = {"000.#E0", "##0.#E0", "#00.#E0"};1717String[][] expected = {1718// it's questionable whether "#00.#E0" should result in post-decimal1719// zeroes, i.e., whether "5.0E3", "5.0E0", "5.0E-3" are really good1720{"500E1", "5E3", "5.0E3"},1721{"500E0", "500E0", "500E0"},1722{"500E-1", "50E0", "50E0"},1723{"500E-2", "5E0", "5.0E0"},1724{"500E-3", "500E-3", "500E-3"},1725{"500E-4", "50E-3", "50E-3"},1726{"500E-5", "5E-3", "5.0E-3"},1727{"500E-6", "500E-6", "500E-6"},1728{"505E1", "5.05E3", "5.05E3"},1729{"505E0", "505E0", "505E0"},1730{"505E-1", "50.5E0", "50.5E0"},1731{"505E-2", "5.05E0", "5.05E0"},1732{"505E-3", "505E-3", "505E-3"},1733{"505E-4", "50.5E-3", "50.5E-3"},1734{"505E-5", "5.05E-3", "5.05E-3"},1735{"505E-6", "505E-6", "505E-6"}1736};1737for (int i = 0; i < input.length; i++) {1738for (int j = 0; j < pattern.length; j++) {1739DecimalFormat format = new DecimalFormat(pattern[j]);1740String result = format.format(input[i]);1741if (!result.equals(expected[i][j])) {1742errln("FAIL: input: " + input[i] +1743", pattern: " + pattern[j] +1744", expected: " + expected[i][j] +1745", got: " + result);1746}1747}1748}1749Locale.setDefault(savedLocale);1750}17511752/**1753* 4233840: NumberFormat does not round correctly1754*/1755public void test4233840() {1756float f = 0.0099f;17571758NumberFormat nf = new DecimalFormat("0.##", DecimalFormatSymbols.getInstance(Locale.US));1759nf.setMinimumFractionDigits(2);17601761String result = nf.format(f);17621763if (!result.equals("0.01")) {1764errln("FAIL: input: " + f + ", expected: 0.01, got: " + result);1765}1766}17671768/**1769* 4241880: Decimal format doesnt round a double properly when the number is less than 11770*/1771public void test4241880() {1772Locale savedLocale = Locale.getDefault();1773Locale.setDefault(Locale.US);1774double[] input = {1775.019, .009, .015, .016, .014,1776.004, .005, .006, .007, .008,1777.5, 1.5, .25, .55, .045,1778.035, .0005, .0015,1779};1780String[] pattern = {1781"##0%", "##0%", "##0%", "##0%", "##0%",1782"##0%", "##0%", "##0%", "##0%", "##0%",1783"#,##0", "#,##0", "#,##0.0", "#,##0.0", "#,##0.00",1784"#,##0.00", "#,##0.000", "#,##0.000",1785};1786String[] expected = {1787"2%", "1%", "2%", "2%", "1%",1788"0%", "0%", "1%", "1%", "1%",1789"0", "2", "0.2", "0.6", "0.04",1790"0.04", "0.000", "0.002",1791};1792for (int i = 0; i < input.length; i++) {1793DecimalFormat format = new DecimalFormat(pattern[i]);1794String result = format.format(input[i]);1795if (!result.equals(expected[i])) {1796errln("FAIL: input: " + input[i] +1797", pattern: " + pattern[i] +1798", expected: " + expected[i] +1799", got: " + result);1800}1801}1802Locale.setDefault(savedLocale);1803}18041805/**1806* Test for get/setMonetaryGroupingSeparator() methods.1807* @since 151808*/1809public void test8227313() throws ParseException {1810var nrmSep = 'n';1811var monSep = 'm';1812var curSym = "Cur";1813var inputNum = 10;1814var nrmPattern = ",#";1815var monPattern = "\u00a4 ,#";1816var expectedNrmFmt = "1n0";1817var expectedMonFmt = "Cur 1m0";18181819var ndfs = DecimalFormatSymbols.getInstance();1820ndfs.setGroupingSeparator(nrmSep);1821var nf = new DecimalFormat(nrmPattern, ndfs);1822var mdfs = DecimalFormatSymbols.getInstance();1823mdfs.setMonetaryGroupingSeparator(monSep);1824mdfs.setCurrencySymbol(curSym);1825var mf = new DecimalFormat(monPattern, mdfs);18261827// get test1828char gotNrmSep = mdfs.getGroupingSeparator();1829char gotMonSep = mdfs.getMonetaryGroupingSeparator();1830if (gotMonSep != monSep) {1831errln("FAIL: getMonetaryGroupingSeparator() returned incorrect value. expected: "1832+ monSep + ", got: " + gotMonSep);1833}1834if (gotMonSep == gotNrmSep) {1835errln("FAIL: getMonetaryGroupingSeparator() returned the same value with " +1836"getGroupingSeparator(): monetary sep: " + gotMonSep +1837", normal sep: " + gotNrmSep);1838}18391840// format test1841var formatted = mf.format(inputNum);1842if (!formatted.equals(expectedMonFmt)) {1843errln("FAIL: format failed. expected: " + expectedMonFmt +1844", got: " + formatted);1845}1846formatted = nf.format(inputNum);1847if (!formatted.equals(expectedNrmFmt)) {1848errln("FAIL: normal format failed. expected: " + expectedNrmFmt +1849", got: " + formatted);1850}18511852// parse test1853Number parsed = mf.parse(expectedMonFmt);1854if (parsed.intValue() != inputNum) {1855errln("FAIL: parse failed. expected: " + inputNum +1856", got: " + parsed);1857}1858parsed = nf.parse(expectedNrmFmt);1859if (parsed.intValue() != inputNum) {1860errln("FAIL: normal parse failed. expected: " + inputNum +1861", got: " + parsed);1862}1863}1864}18651866@SuppressWarnings("serial")1867class myformat implements Serializable1868{1869DateFormat _dateFormat = DateFormat.getDateInstance();18701871public String Now()1872{1873GregorianCalendar calendar = new GregorianCalendar();1874Date t = calendar.getTime();1875String nowStr = _dateFormat.format(t);1876return nowStr;1877}1878}18791880@SuppressWarnings("serial")1881class MyNumberFormatTest extends NumberFormat {1882public StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos) {1883return new StringBuffer("");1884}1885public StringBuffer format(long number,StringBuffer toAppendTo, FieldPosition pos) {1886return new StringBuffer("");1887}1888public Number parse(String text, ParsePosition parsePosition) {1889return 0;1890}1891}189218931894