/*****************************************************************************************
 * $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/test/format/NumberRegression.java,v $ 
 * $Date: 2002/09/14 21:36:28 $ 
 * $Revision: 1.12 $
 *
 *****************************************************************************************
 **/

/** 
 * Port From:   JDK 1.4b1 : java.text.Format.NumberRegression
 * Source File: java/text/format/NumberRegression.java
 **/
 
/**
 * @test 1.49 01/05/21
 * @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
 * @summary Regression tests for NumberFormat and associated classes
 */

/***************************************************************************
*
*   Copyright (C) 1996-2002, International Business Machines
*   Corporation and others.  All Rights Reserved.
*
************************************************************************/

package com.ibm.icu.dev.test.format;

import com.ibm.icu.impl.ICULocaleData;
import com.ibm.icu.text.*;
import com.ibm.icu.util.*;

import java.io.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.FieldPosition;
import java.text.ParseException;
import java.text.ParsePosition;
import java.util.Date;
import java.util.Locale;
import java.util.ResourceBundle;

public class NumberRegression extends com.ibm.icu.dev.test.TestFmwk {

    public static void main(String[] args) throws Exception {
        new NumberRegression().run(args);
    }

	private static final char EURO = '\u20ac';

    /**
     * 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);
        if (!sBuf2.toString().equals("100"))
            errln(" format(d) = '" + sBuf2 + "'");
    }
    /**
     * DecimalFormatSymbols should be cloned in the ctor DecimalFormat.
     * DecimalFormat(String, DecimalFormatSymbols).
     */
    public void Test4087245 (){
        DecimalFormatSymbols symbols = new DecimalFormatSymbols();
        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; //The variable is never used
        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 = new DecimalFormatSymbols();
        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 (){
        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);
    }

    /**
     * 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()
    {
        logln("----- Test Application -----");
        ParsePosition pos;
        DecimalFormat df = new DecimalFormat();
        Number d = df.parse("123.55456", pos=new ParsePosition(0));
        if (!d.toString().equals("123.55456")) {
            errln("Result -> " + d.doubleValue());
        }
    }

    /* bugs 4069754, 4067878
     * null pointer thrown when accessing a deserialized DecimalFormat
     * object.
     */
    public void Test4069754() throws Exception
    {
        //try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            myformat it = new myformat();
            logln(it.Now());
            oos.writeObject(it);
            oos.flush();
            baos.close();
            logln("Save OK!");
            byte [] bytes = baos.toByteArray();
            ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
            myformat o = (myformat)ois.readObject();
            ois.close();
            it.Now();
            logln("Load OK!");
            if (!o._dateFormat.equals(it._dateFormat)) {
                throw new Exception("The saved and loaded object are not equals!");
            }
            logln("Compare 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 (){
        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());
        }
    }

    /**
     * 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 ()
    {
        DecimalFormat df = new DecimalFormat();
        String str = "0.1234";
        Double d1 = new Double(str);
        Number d2 = df.parse(str, new ParsePosition(0));
        logln(d1.toString());
        if (d2.doubleValue() != d1.doubleValue())
            errln("Bug 4095713 test failed, new double value : " + d2.doubleValue());
    }

    /**
     * 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 set to not 1.");
        }
        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(); //The variable is never used
        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 " + EURO; // euro
        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 $";
        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 " + EURO;
        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
	 * Note- with the Euro, there is no need for currency rounding anymore
     */
    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 = "-" + EURO + " 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("a) 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("b) 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("c) Failed:" +
            " Expected " + expectedPercent +
            " Received " + tempString );
        }

    }
    /* bug 4071859
     * Test rounding for nearest even.
     */
    public void Test4093610()
    {
        DecimalFormat df = new DecimalFormat("#0.#");
        roundingTest(df, 12.35, "12.4");
        roundingTest(df, 12.45, "12.4");
        roundingTest(df, 12.452,"12.5");
        roundingTest(df, 12.55, "12.6");
        roundingTest(df, 12.65, "12.6");
        roundingTest(df, 12.652,"12.7");
        roundingTest(df, 12.75, "12.8");
        roundingTest(df, 12.752,"12.8");
        roundingTest(df, 12.85, "12.8");
        roundingTest(df, 12.852,"12.9");
        roundingTest(df, 12.95, "13");
        roundingTest(df, 12.952,"13");

    }
    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()
    {
        try {
            DecimalFormat fmt = new DecimalFormat("#,#00.00;-#.#");
            logln("format 3456.78: " + fmt.format(3456.78)); //fix "The variable 'fmt' is never used"
            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!  3456.78 p'ieces expected, but got : " + tempString);
        } catch (Exception foo) {
            errln("An exception was thrown for any inconsistent negative pattern.");
        }
    }
    /**
     * 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");
            logln("format 3456.78: " + fmt.format(3456.78)); //fix "The variable 'fmt' is never used"
            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");
            logln("format 3456.78: " + fmt.format(3456.78)); //fix "The variable 'fmt' is never used"
            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 = new DecimalFormatSymbols();
        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.###", new
        DecimalFormatSymbols(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 = ICULocaleData.getResourceBundle("LocaleElements", 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 = new DecimalFormatSymbols(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(); //The variable is never used
            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()
    {
        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%");
    }

    /**
     **
     * DecimalFormat produces extra zeros when formatting numbers.
     */
    public void Test4134034() {
        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");
    }

    /**
     * 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() {
        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<DATA.length; i+=2) {
            String result = new DecimalFormat(DATA[i]).format(1.2);
            if (!result.equals(DATA[i+1])) {
                errln("Fail: 1.2 x " + DATA[i] + " = " + result +
                      "; want " + DATA[i+1]);
            }
            else {
                logln("Ok: 1.2 x " + DATA[i] + " = " + result);
            }
        }
    }

    /**
     * Empty pattern produces double negative prefix.
     */
    public void Test4140009() {
        for (int i=0; i<2; ++i) {
            DecimalFormat f = null;
            switch (i) {
            case 0:
                f = new DecimalFormat("",
                            new DecimalFormatSymbols(Locale.ENGLISH));
                break;
            case 1:
                f = new DecimalFormat("#.#",
                            new DecimalFormatSymbols(Locale.ENGLISH));
                f.applyPattern("");
                break;
            }
            String s = f.format(123.456);
            if (!s.equals("123.456"))
                errln("Fail: Format empty pattern x 123.456 => " + 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);
            String sd = NumberFormat.getInstance(Locale.US).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<PATS.length; ++i) {
                nf.applyPattern(PATS[i]);
                String out = nf.format(pi);
                String pat = nf.toPattern();
                double val = nf.parse(out).doubleValue();
            
                nf.applyPattern(pat);
                String out2 = nf.format(pi);
                String pat2 = nf.toPattern();
                double val2 = nf.parse(out2).doubleValue();
            
                if (!pat.equals(pat2))
                    errln("Fail with \"" + PATS[i] + "\": Patterns should concur, \"" +
                          pat + "\" vs. \"" + pat2 + "\"");
                else
                    logln("Ok \"" + PATS[i] + "\" toPattern() -> \"" + 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(new DecimalFormatSymbols(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 Double)
            || 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<DATA.length; i+=2) {
            DecimalFormat df = new DecimalFormat(DATA[i]);
            String s = df.toPattern();
            if (!s.equals(DATA[i+1])) {
                errln("FAIL: " + DATA[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("#",
                new DecimalFormatSymbols(Locale.US));
        for (int i=0; i<DATA.length; i+=3) {
            double in = Double.valueOf(DATA[i]).doubleValue();
            String pat = DATA[i+1];
            String exp = DATA[i+2];
            fmt.applyPattern(pat);
            String out = fmt.format(in);
            if (out.equals(exp)) {
                logln("Ok: " + in + " x " + pat + " = " + out);
            } else {
                errln("FAIL: " + in + " x  " + pat + " = " + out +
                      ", expected " + exp);
            }
        }
    }

    public void Test4185761() throws IOException, ClassNotFoundException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        
        NumberFormat nf = NumberFormat.getInstance(Locale.US);

	// Set special values we are going to search for in the output byte stream
	// These are all legal values.
        nf.setMinimumIntegerDigits(0x111); // Keep under 309
        nf.setMaximumIntegerDigits(0x112); // Keep under 309
        nf.setMinimumFractionDigits(0x113); // Keep under 340
        nf.setMaximumFractionDigits(0x114); // Keep under 340
        
        oos.writeObject(nf);
        oos.flush();
        baos.close();
        
        byte[] bytes = baos.toByteArray();

	// Scan for locations of min/max int/fract values in the byte array.
	// At the moment (ICU4J 2.1), there is only one instance of each target pair
        // in the byte stream, so assume first match is it.  Note this is not entirely
	// failsafe, and needs to be checked if we change the package or structure of
	// this class.
	// Current positions are 890, 880, 886, 876
	int[] offsets = new int[4];
	for (int i = 0; i < bytes.length - 1; ++i) {
	    if (bytes[i] == 0x01) { // high byte
		for (int j = 0; j < offsets.length; ++j) {
		    if ((offsets[j] == 0) && (bytes[i+1] == (0x11 + j))) { // low byte
			offsets[j] = i;
			break;
		    }
		}
	    }
	}

        {
            ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
            Object o = ois.readObject();
            ois.close();
            
            if (!nf.equals(o)) {
                errln("Fail: DateFormat serialization/equality bug");
            } else {
                logln("DateFormat serialization/equality is OKAY.");
            }
        }

	// Change the values in the byte stream so that min > max.
	// Numberformat should catch this and throw an exception.
	for (int i = 0; i < offsets.length; ++i) {
	    bytes[offsets[i]] = (byte)(4 - i);
	}

        {
            ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
            try {
                NumberFormat format = (NumberFormat) ois.readObject();
                logln("format: " + format.format(1234.56)); //fix "The variable is never used"
                errln("FAIL: Deserialized bogus NumberFormat with minXDigits > maxXDigits");
            } catch (InvalidObjectException e) {
                logln("Ok: " + e.getMessage());
            }
        }

	// Set values so they are too high, but min <= max
	// Format should pass the min<= max test, and DecimalFormat should reset to current maximum
	// (for compatibility with versions streamed out before the maximums were imposed).
	for (int i = 0; i < offsets.length; ++i) {
	    bytes[offsets[i]] = 4;
	}

        {
            ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
            NumberFormat format = (NumberFormat) ois.readObject();
            //For compatibility with previous version
            if ((format.getMaximumIntegerDigits() != 309) 
                || format.getMaximumFractionDigits() != 340) {
                errln("FAIL: Deserialized bogus NumberFormat with values out of range," +
					  " intMin: " + format.getMinimumIntegerDigits() +
					  " intMax: " + format.getMaximumIntegerDigits() +
					  " fracMin: " + format.getMinimumFractionDigits() +
					  " fracMax: " + format.getMaximumFractionDigits());
            } else {
                logln("Ok: Digit count out of range");
            }
        }
    }


    /**
     * Some DecimalFormatSymbols changes are not picked up by DecimalFormat.
     * This includes the minus sign, currency symbol, international currency
     * symbol, percent, and permille.  This is filed as bugs 4212072 and
     * 4212073.
     */
    public void Test4212072() throws IOException, ClassNotFoundException {
        DecimalFormatSymbols sym = new DecimalFormatSymbols(Locale.US);
        DecimalFormat fmt = new DecimalFormat("#", sym);

        sym.setMinusSign('^');
        fmt.setDecimalFormatSymbols(sym);
        if (!fmt.format(-1).equals("^1")) {
            errln("FAIL: -1 x (minus=^) -> " + 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");

        if (VersionInfo.ICU_VERSION == VersionInfo.getInstance(2,2)) {
            // bug in 2.2 that fails this test
            // to be fixed in the later versions
            System.out.println("\n        Test skipped for release 2.2");
            return;
        }
        
        // 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<avail.length; ++i) {
            for (int j=0; j<3; ++j) {
                NumberFormat nf;
                switch (j) {
                case 0:
                    nf = NumberFormat.getInstance(avail[i]);
                    break;
                case 1:
                    nf = NumberFormat.getCurrencyInstance(avail[i]);
                    break;
                default:
                    nf = NumberFormat.getPercentInstance(avail[i]);
                    break;
                }
                DecimalFormat df = (DecimalFormat) nf;
                
                // Test toPattern/applyPattern round trip
                String pat = df.toPattern();
                DecimalFormatSymbols symb = new DecimalFormatSymbols(avail[i]);
                DecimalFormat f2 = new DecimalFormat(pat, symb);
                if (!df.equals(f2)) {
                    errln("FAIL: " + avail[i] + " #" + j + " -> \"" + pat +
                          "\" -> \"" + f2.toPattern() + '"');
                }

                // Test toLocalizedPattern/applyLocalizedPattern round trip
                pat = df.toLocalizedPattern();
                f2.applyLocalizedPattern(pat);
                if (!df.equals(f2)) {
                    errln("FAIL: " + avail[i] + " #" + j + " -> localized \"" + pat +
                          "\" -> \"" + f2.toLocalizedPattern() + '"');
                }

                // 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"));
                }

            }
        }

        // @since ICU 2.4
        // Make sure that all special characters, when quoted in a suffix or
        // prefix, lose their special meaning.
        char[] SPECIALS = { '0', ',', '.', '\u2030', '%', '#',
                            ';', 'E', '*', '+', '-' };
        sym = new DecimalFormatSymbols(Locale.US);
        for (int j=0; j<SPECIALS.length; ++j) {
            char special = SPECIALS[j];
            String pat = "'" + special + "'#0'" + special + "'";
            try {
                fmt = new DecimalFormat(pat, sym);
                String pat2 = fmt.toPattern();
                if (!pat.equals(pat2)) {
                    errln("FAIL: Pattern \"" + pat + "\" => toPattern() => \"" +
                          pat2 + "\"");
                }
                String s = fmt.format(123);
                String exp = "" + special + "123" + special;
                if (!s.equals(exp)) {
                    errln("FAIL: 123 x \"" + pat + "\" => \"" + s + "\", exp \"" +
                          exp + "\"");
                }
            } catch (IllegalArgumentException e) {
                errln("FAIL: Pattern \"" + pat + "\" => " + e.getMessage());
            }
        }
    }

    /**
     * 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<DATA.length; ++i) {
            String str = Long.toString(DATA[i]);
            for (int m = 1; m <= 100; m++) {
                fmt.setMultiplier(m);
                long n = ((Number) fmt.parse(str)).longValue();
                if (n > 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<DATA.length; i+=2) {
            String s = fmt.format(((Double) DATA[i]).doubleValue());
            if (!s.equals(DATA[i+1])) {
                errln("FAIL: Got " + s + ", exp " + DATA[i+1]); 
            }
        }
    }
    
    /**
     * 4243011: Formatting .5 rounds to "1" instead of "0"
     */
    public void Test4243011() {
        double DATA[] = {0.5, 1.5, 2.5, 3.5, 4.5};
        String EXPECTED[] = {"0.", "2.", "2.", "4.", "4."};
        
        DecimalFormat format = new DecimalFormat("0.");
        for (int i = 0; i < DATA.length; i++) {
            String result = format.format(DATA[i]);
            if (result.equals(EXPECTED[i])) {
                logln("OK: got " + result);
            } else {
                errln("FAIL: got " + result);
            }
        }
    }
    
    /**
     * 4243108: format(0.0) gives "0.1" if preceded by parse("99.99")
     */
    public void Test4243108() {
        DecimalFormat f = new DecimalFormat("#.#");
        String result = f.format(0.0);
        if (result.equals("0")) {
            logln("OK: got " + result);
        } else {
            errln("FAIL: got " + result);
        }
        try {
            double dResult = f.parse("99.99").doubleValue();
            if (dResult == 99.99) {
                logln("OK: got " + dResult);
            } else {
                errln("FAIL: got " + dResult);
            }
        } catch (ParseException e) {
            errln("Caught a ParseException:");
            e.printStackTrace();
        }            
        result = f.format(0.0);
        if (result.equals("0")) {
            logln("OK: got " + result);
        } else {
            errln("FAIL: got " + result);
        }
    }
    
    /**
     * 4330377: DecimalFormat engineering notation gives incorrect results
     */
    public void test4330377() {
        /*
        double[] input = {5000.0, 500.0, 50.0, 5.0, 0.5, 0.05, 0.005, 0.0005,
               5050.0, 505.0, 50.5, 5.05, 0.505, 0.0505, 0.00505, 0.000505};
        String[] pattern = {"000.#E0", "##0.#E0", "#00.#E0"};
        String[][] expected = {
            // it's questionable whether "#00.#E0" should result in post-decimal
            // zeroes, i.e., whether "5.0E3", "5.0E0", "5.0E-3" are really good
            {"500E1", "5E3", "5.0E3"},
            {"500E0", "500E0", "500E0"},
            {"500E-1", "50E0", "50E0"},
            {"500E-2", "5E0", "5.0E0"},
            {"500E-3", "500E-3", "500E-3"},
            {"500E-4", "50E-3", "50E-3"},
            {"500E-5", "5E-3", "5.0E-3"},
            {"500E-6", "500E-6", "500E-6"},
            {"505E1", "5.05E3", "5.05E3"},
            {"505E0", "505E0", "505E0"},
            {"505E-1", "50.5E0", "50.5E0"},
            {"505E-2", "5.05E0", "5.05E0"},
            {"505E-3", "505E-3", "505E-3"},
            {"505E-4", "50.5E-3", "50.5E-3"},
            {"505E-5", "5.05E-3", "5.05E-3"},
            {"505E-6", "505E-6", "505E-6"}
        };
        for (int i = 0; i < input.length; i++) {
            for (int j = 0; j < pattern.length; j++) {
                DecimalFormat format = new DecimalFormat(pattern[j]);
                String result = format.format(input[i]);
                if (!result.equals(expected[i][j])) {
                    errln("FAIL: input: " + input[i] +
                            ", pattern: " + pattern[j] +
                            ", expected: " + expected[i][j] +
                            ", got: " + result);
                }
            }
        }
        */
    }
    
    /**
     * 4233840: NumberFormat does not round correctly
     */
    public void test4233840() {
        float f = 0.0099f;

        NumberFormat nf = new DecimalFormat("0.##", new DecimalFormatSymbols(Locale.US));
	nf.setMinimumFractionDigits(2);
	
	String result = nf.format(f);
	
	if (!result.equals("0.01")) {
	    errln("FAIL: input: " + f + ", expected: 0.01, got: " + result);
	}
    }
}

class myformat implements Serializable
{
    DateFormat _dateFormat = DateFormat.getDateInstance();

    public String Now()
    {
        GregorianCalendar calendar = new GregorianCalendar();
        Date t = calendar.getTime();
        String nowStr = _dateFormat.format(t);
        return nowStr;
    }
}

class MyNumberFormatTest extends NumberFormat {
    public StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos) {
        return new StringBuffer("");
    }
    public StringBuffer format(long number,StringBuffer toAppendTo, FieldPosition pos) {
        return new StringBuffer("");
    }
    public Number parse(String text, ParsePosition parsePosition) {
        return new Integer(0);
    }
    public StringBuffer format(BigDecimal number, StringBuffer toAppendTo, FieldPosition pos) {
        return new StringBuffer("");
    }
    public StringBuffer format(BigInteger number, StringBuffer toAppendTo, FieldPosition pos) {
        return new StringBuffer("");
    }
    public StringBuffer format(com.ibm.icu.math.BigDecimal number, StringBuffer toAppendTo, FieldPosition pos) {
        return new StringBuffer("");
    }
}

