/***********************************************************************
 * Copyright (c) 1997-2013, International Business Machines Corporation
 * and others. All Rights Reserved.
 ***********************************************************************/
 
#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING

#include "numrgts.h"

#include <float.h> // DBL_MIN, DBL_MAX
#include <stdio.h>

#include "unicode/dcfmtsym.h"
#include "unicode/decimfmt.h"
#include "unicode/locid.h"
#include "unicode/resbund.h"
#include "unicode/calendar.h"
#include "unicode/datefmt.h"
#include "unicode/ucurr.h"
#include "putilimp.h"

class MyNumberFormatTest : public NumberFormat 
{
public:

    virtual UClassID getDynamicClassID(void) const;
  
    virtual UnicodeString& format(    double            number, 
                    UnicodeString&        toAppendTo, 
                    FieldPositionIterator* posIter,
                    UErrorCode& status) const
    {
        return NumberFormat::format(number, toAppendTo, posIter, status);
    }

    /* Just keep this here to make some of the compilers happy */
    virtual UnicodeString& format(const Formattable& obj,
                                  UnicodeString& toAppendTo,
                                  FieldPosition& pos,
                                  UErrorCode& status) const
    {
        return NumberFormat::format(obj, toAppendTo, pos, status);
    }

    /* Just use one of the format functions */
    virtual UnicodeString& format(    double            /* number */, 
                    UnicodeString&        toAppendTo, 
                    FieldPosition&        /* pos */) const
    {
        toAppendTo = "";
        return toAppendTo;
    }
  
    /*
    public Number parse(String text, ParsePosition parsePosition) 
    { return new Integer(0); }
    */
  
    /* Just use one of the parse functions */
    virtual void parse(    const UnicodeString&    /* text */, 
            Formattable&            result, 
            ParsePosition&          /* parsePosition */) const
    {
        result.setLong((int32_t)0);
    }
  
    virtual void parse(    const UnicodeString&    text, 
            Formattable&            result, 
            UErrorCode&            status) const 
    {
        NumberFormat::parse(text, result, status);
    }
    virtual Format* clone() const 
    { return NULL; }

    virtual UnicodeString& format(int32_t, 
                UnicodeString& foo, 
                FieldPosition&) const
    { return foo.remove(); }

    virtual UnicodeString& format(int64_t, 
                UnicodeString& foo, 
                FieldPosition&) const
    { return foo.remove(); }

    virtual void applyPattern(const UnicodeString&, UParseError&, UErrorCode&){
    }
};

int32_t gMyNumberFormatTestClassID;
UClassID MyNumberFormatTest::getDynamicClassID()  const
{
    return (UClassID)&gMyNumberFormatTestClassID;
}


// *****************************************************************************
// class NumberFormatRegressionTest
// *****************************************************************************

#define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break

void 
NumberFormatRegressionTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
{
    // if (exec) logln((UnicodeString)"TestSuite NumberFormatRegressionTest");
    switch (index) {
        CASE(0,Test4075713);
        CASE(1,Test4074620);
        CASE(2,Test4088161);
        CASE(3,Test4087245);
        CASE(4,Test4087535);
        CASE(5,Test4088503);
        CASE(6,Test4066646);
        CASE(7,Test4059870);
        CASE(8,Test4083018);
        CASE(9,Test4071492);
        CASE(10,Test4086575);
        CASE(11,Test4068693);
        CASE(12,Test4069754);
        CASE(13,Test4087251);
        CASE(14,Test4090489);
        CASE(15,Test4090504);
        CASE(16,Test4095713);
        CASE(17,Test4092561);
        CASE(18,Test4092480);
        CASE(19,Test4087244);
        CASE(20,Test4070798);
        CASE(21,Test4071005);
        CASE(22,Test4071014);
        CASE(23,Test4071859);
        CASE(24,Test4093610);
        CASE(25,Test4098741);
        CASE(26,Test4074454);
        CASE(27,Test4099404);
        CASE(28,Test4101481);
        CASE(29,Test4052223);
        CASE(30,Test4061302);
        CASE(31,Test4062486);
        CASE(32,Test4108738);
        CASE(33,Test4106658);
        CASE(34,Test4106662);
        CASE(35,Test4114639);
        CASE(36,Test4106664);
        CASE(37,Test4106667);
        CASE(38,Test4110936);
        CASE(39,Test4122840);
        CASE(40,Test4125885);
        CASE(41,Test4134034);
        CASE(42,Test4134300);
        CASE(43,Test4140009);
        CASE(44,Test4141750);
        CASE(45,Test4145457);
        CASE(46,Test4147295);
        CASE(47,Test4147706);
        CASE(48,Test4162198);
        CASE(49,Test4162852);
        CASE(50,Test4167494);
        CASE(51,Test4170798);
        CASE(52,Test4176114);
        CASE(53,Test4179818);
        CASE(54,Test4212072);
        CASE(55,Test4216742);
        CASE(56,Test4217661);
        CASE(57,Test4161100);
        CASE(58,Test4243011);
        CASE(59,Test4243108);
        CASE(60,TestJ691);
        CASE(61,Test8199);
        CASE(62,Test9109);
        CASE(63,Test9780);
        CASE(64,Test9677);
        CASE(65,Test10361);

        default: name = ""; break;
    }
}

UBool 
NumberFormatRegressionTest::failure(UErrorCode status, const UnicodeString& msg, const Locale& l, UBool possibleDataError)
{
    if(U_FAILURE(status)) {
        if (possibleDataError) {
            dataerrln(UnicodeString("FAIL: ", "") + msg
                  + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status), "") + UnicodeString(l.getName(),""));
        } else {
            errcheckln(status, UnicodeString("FAIL: ", "") + msg
                  + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status), "") + UnicodeString(l.getName(),""));
        }
        return TRUE;
    }

    return FALSE;
}

UBool 
NumberFormatRegressionTest::failure(UErrorCode status, const UnicodeString& msg, const char *l, UBool possibleDataError)
{
    if(U_FAILURE(status)) {
        if (possibleDataError) {
            dataerrln(UnicodeString("FAIL: ", "") + msg
                  + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status), "") + UnicodeString(l, ""));
        } else {
            errcheckln(status, UnicodeString("FAIL: ", "") + msg
                  + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status), "") + UnicodeString(l, ""));
        }
        return TRUE;
    }

    return FALSE;
}

UBool 
NumberFormatRegressionTest::failure(UErrorCode status, const UnicodeString& msg, UBool possibleDataError)
{
    if(U_FAILURE(status)) {
        if (possibleDataError) {
            dataerrln(UnicodeString("FAIL: ", "") + msg
                  + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status), ""));
        } else {
            errcheckln(status, UnicodeString("FAIL: ", "") + msg
                  + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status), ""));
        }
        return TRUE;
    }

    return FALSE;
}

/**
 * Convert Java-style strings with \u Unicode escapes into UnicodeString objects
 */
inline UnicodeString str(const char *input)
{
  return CharsToUnicodeString(input);
}

/* @bug 4075713
 * NumberFormat.equals comparing with null should always return false.
 */
// {sfb} kind of silly in C++, just checking for new success
void NumberFormatRegressionTest::Test4075713(void)
{
    //try {
        MyNumberFormatTest *tmp = new MyNumberFormatTest();
        if(tmp != NULL)
            logln("NumberFormat.equals passed");
    /*} catch (NullPointerException e) {
        errln("(new MyNumberFormatTest()).equals(null) throws unexpected exception");
    }*/
    
    delete tmp;
}

/* @bug 4074620
 * NumberFormat.equals comparing two obj equal even the setGroupingUsed
 * flag is different.
 */
void NumberFormatRegressionTest::Test4074620(void) 
{

    MyNumberFormatTest *nf1 = new MyNumberFormatTest();
    MyNumberFormatTest *nf2 = new MyNumberFormatTest();

    nf1->setGroupingUsed(FALSE);
    nf2->setGroupingUsed(TRUE);

    if(nf1 == nf2) 
        errln("Test for bug 4074620 failed");
    else 
        logln("Test for bug 4074620 passed.");
    
    delete nf1;
    delete nf2;
}


/* @bug 4088161
 * DecimalFormat.format() incorrectly uses maxFractionDigits setting.
 */

void NumberFormatRegressionTest::Test4088161 (void)
{
    UErrorCode status = U_ZERO_ERROR;
    DecimalFormat *df = new DecimalFormat(status);
    if (!failure(status, "new DecimalFormat", "")) {
        double d = 100;
        df->setMinimumFractionDigits(0);
        df->setMaximumFractionDigits(16);
        UnicodeString sBuf1;
        FieldPosition fp1(0);
        logln(UnicodeString("d = ") + d);
        logln(UnicodeString("maxFractionDigits = ") + df->getMaximumFractionDigits());

        logln(" format(d) = '" + df->format(d, sBuf1, fp1) + "'");
        df->setMaximumFractionDigits(17);
        UnicodeString sBuf2;
        FieldPosition fp2(0);
        logln(UnicodeString("maxFractionDigits = ") + df->getMaximumFractionDigits());
        sBuf2 = df->format(d, sBuf2, fp2);
        if(sBuf2 != "100")
            errln(" format(d) = '" + sBuf2 + "'");
    }

    delete df;
}

/* @bug 4087245
 * DecimalFormatSymbols should be cloned in the ctor DecimalFormat.
 * DecimalFormat(String, DecimalFormatSymbols).
 */
void NumberFormatRegressionTest::Test4087245 (void)
{
    UErrorCode status = U_ZERO_ERROR;
    DecimalFormatSymbols *symbols = new DecimalFormatSymbols(status);
    failure(status, "new DecimalFormatSymbols", "");
    // {sfb} One note about this test: if you pass in a pointer
    // to the symbols, they are adopted and this test will fail,
    // even though that is the correct behavior.  To test the cloning
    // of the symbols, it is necessary to pass in a reference to the symbols
    DecimalFormat *df = new DecimalFormat("#,##0.0", *symbols, status);
    failure(status, "new DecimalFormat with symbols", "");
    int32_t n = 123;
    UnicodeString buf1;
    UnicodeString buf2;
    FieldPosition pos(FieldPosition::DONT_CARE);
    logln(UnicodeString("format(") + n + ") = " + 
        df->format(n, buf1, pos));
    symbols->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, UnicodeString((UChar)0x70)); // change value of field
    logln(UnicodeString("format(") + n + ") = " +
        df->format(n, buf2, pos));
    if(buf1 != buf2)
        errln("Test for bug 4087245 failed");

    delete df;
    delete symbols;
}

/* @bug 4087535
 * DecimalFormat.format() incorrectly formats 0.0
 */
void NumberFormatRegressionTest::Test4087535 (void)
{
    UErrorCode status = U_ZERO_ERROR;
    DecimalFormat *df = new DecimalFormat(status);
    failure(status, "new DecimalFormat", "");
    df->setMinimumIntegerDigits(0);

    double n = 0;
    UnicodeString buffer;
    FieldPosition pos(FieldPosition::DONT_CARE);
    buffer = df->format(n, buffer, pos);
    if (buffer.length() == 0)
        errln(/*n + */": '" + buffer + "'");
    n = 0.1;
    buffer = df->format(n, buffer, pos);
    if (buffer.length() == 0)
        errln(/*n + */": '" + buffer + "'");

    delete df;
}

/* @bug 4088503
 * DecimalFormat.format fails when groupingSize is set to 0.
 */
// {sfb} how do I tell if this worked? --> FieldPosition doesn't change ??
void NumberFormatRegressionTest::Test4088503 (void)
{
    UErrorCode status = U_ZERO_ERROR;
    DecimalFormat *df = new DecimalFormat(status);
    failure(status, "new DecimalFormat", "");
    df->setGroupingSize(0);
    UnicodeString sBuf;
    FieldPosition fp(FieldPosition::DONT_CARE);
    //try {
        logln(df->format((int32_t)123, sBuf, fp));
        //if(fp == FieldPosition(0))
        //    errln("Test for bug 4088503 failed.");
    /*} catch (Exception foo) {
        errln("Test for bug 4088503 failed.");
    }*/
    delete df;

}
/* @bug 4066646
 * NumberFormat.getCurrencyInstance is wrong.
 */
void NumberFormatRegressionTest::Test4066646 (void) 
{
    assignFloatValue(2.04f);
    assignFloatValue(2.03f);
    assignFloatValue(2.02f);
    assignFloatValue(0.0f);
}

float 
NumberFormatRegressionTest::assignFloatValue(float returnfloat)
{
    logln(UnicodeString(" VALUE ") + returnfloat);
    UErrorCode status = U_ZERO_ERROR;
    NumberFormat *nfcommon =  NumberFormat::createCurrencyInstance(Locale::getUS(), status);
    if (failure(status, "NumberFormat::createCurrencyInstance", Locale::getUS(), TRUE)){
        delete nfcommon;
        return returnfloat;
    }
    nfcommon->setGroupingUsed(FALSE);

    UnicodeString stringValue;
    stringValue = nfcommon->format(returnfloat, stringValue);
    logln(" DISPLAYVALUE " + stringValue);
    Formattable result;
    nfcommon->parse(stringValue, result, status);
    failure(status, "nfcommon->parse", Locale::getUS());
    float floatResult = (float) (result.getType() == Formattable::kDouble 
                                        ? result.getDouble() : result.getLong());
    if( uprv_fabs(floatResult - returnfloat) > 0.0001)
    //String stringValue = nfcommon.format(returnfloat).substring(1);
    //if (Float.valueOf(stringValue).floatValue() != returnfloat)
        errln(UnicodeString("FAIL: expected ") + returnfloat + ", got " + floatResult + " (" + stringValue+")");
    
    delete nfcommon;
    return returnfloat;
} // End Of assignFloatValue()

/* @bug 4059870
 * DecimalFormat throws exception when parsing "0"
 */
void NumberFormatRegressionTest::Test4059870(void) 
{
    UErrorCode status = U_ZERO_ERROR;
    DecimalFormat *format = new DecimalFormat("00", status);
    failure(status, "new Decimalformat", Locale::getUS());
    //try {
        Formattable result;
        UnicodeString str;
        format->parse(UnicodeString("0"), result, status);
        failure(status, "format->parse", Locale::getUS());
        
    /*} 
    catch (Exception e) { 
        errln("Test for bug 4059870 failed : " + e); 
    }*/

    delete format;
}
/* @bug 4083018
 * DecimalFormatSymbol.equals should always return false when
 * comparing with null.
 */
// {sfb} this is silly in C++
void NumberFormatRegressionTest::Test4083018 (void)
{
    UErrorCode status = U_ZERO_ERROR;
    DecimalFormatSymbols *dfs = new DecimalFormatSymbols(status);
    failure(status, "new DecimalFormatSymbols", Locale::getUS());
    //try {
        if (dfs != NULL)
            logln("Test Passed!");
        else
            errln("Test for bug 4083018 failed");
    /*} catch (Exception foo) {
        errln("Test for bug 4083018 failed => Message : " + foo.getMessage());
    }*/

    delete dfs;
}

/* @bug 4071492
 * DecimalFormat does not round up correctly.
 */
void NumberFormatRegressionTest::Test4071492 (void)
{
    double x = 0.00159999;
    UErrorCode status = U_ZERO_ERROR;
    NumberFormat *nf = NumberFormat::createInstance(status);
    if (failure(status, "NumberFormat::createInstance", Locale::getUS(), TRUE)) {
        delete nf;
        return;
    }
    nf->setMaximumFractionDigits(4);
    UnicodeString out;
    FieldPosition pos(FieldPosition::DONT_CARE);
    out = nf->format(x, out, pos);
    logln("0.00159999 formats with 4 fractional digits to " + out);
    UnicodeString expected("0.0016");
    if (out != expected)
        errln("FAIL: Expected " + expected);

    delete nf;
}

/* @bug 4086575
 * A space as a group separator for localized pattern causes
 * wrong format.  WorkAround : use non-breaking space.
 */
void NumberFormatRegressionTest::Test4086575(void) 
{
    UErrorCode status = U_ZERO_ERROR;
    NumberFormat *nf1 = NumberFormat::createInstance(Locale::getFrance(), status);

    // TODO: There is not a good way to find out that the creation of this number format has
    // failed. Major rewiring of format construction proposed.
    if(U_FAILURE(status)) {
      dataerrln("Something is wrong with French number format - it should not fallback. Exitting - %s", u_errorName(status));
      delete nf1;
      return;
    }
    failure(status, "NumberFormat::createInstance", Locale::getFrance());

    // C++ workaround to make sure cast works
    DecimalFormat *nf = dynamic_cast<DecimalFormat *>(nf1);
    if(nf == NULL) {
        errln("NumberFormat::createInstance returned incorrect type.");
        return;
    }

    UnicodeString temp;
    logln("nf toPattern1: " + nf->toPattern(temp));
    logln("nf toLocPattern1: " + nf->toLocalizedPattern(temp));
    
    // No group separator
    logln("...applyLocalizedPattern ###,00;(###,00) ");
    nf->applyLocalizedPattern(UnicodeString("###,00;(###,00)"), status);
    failure(status, "nf->applyLocalizedPattern", Locale::getFrance());
    logln("nf toPattern2: " + nf->toPattern(temp));
    logln("nf toLocPattern2: " + nf->toLocalizedPattern(temp));

    FieldPosition pos(FieldPosition::DONT_CARE);
    logln("nf: " + nf->format((int32_t)1234, temp, pos)); // 1234,00
    logln("nf: " + nf->format((int32_t)-1234, temp, pos)); // (1234,00)

    // Space as group separator

    logln("...applyLocalizedPattern # ###,00;(# ###,00) ");
    // nbsp = \u00a0
    //nf->applyLocalizedPattern("#\u00a0###,00;(#\u00a0###,00)");
    UChar patChars[] = {
             0x23, 0x00a0, 0x23, 0x23, 0x23, 0x2c, 0x30, 0x30, 0x3b, 
        0x28, 0x23, 0x00a0, 0x23, 0x23, 0x23, 0x2c, 0x30, 0x30, 0x29
    };
    UnicodeString pat(patChars, 19, 19);
    nf->applyLocalizedPattern(pat, status);
    failure(status, "nf->applyLocalizedPattern", Locale::getFrance());
    logln("nf toPattern2: " + nf->toPattern(temp));
    logln("nf toLocPattern2: " + nf->toLocalizedPattern(temp));
    UnicodeString buffer;
    buffer = nf->format((int32_t)1234, buffer, pos);
    //if (buffer != UnicodeString("1\u00a0234,00"))
    UChar c[] = {
        0x31, 0x00a0, 0x32, 0x33, 0x34, 0x2c, 0x30, 0x30
    };
    UnicodeString cc(c, 8, 8);
    if (buffer != cc)
        errln("nf : " + buffer); // Expect 1 234,00
    
    buffer.remove();
    buffer = nf->format((int32_t)-1234, buffer, pos);
    UChar c1[] = {
        0x28, 0x31, 0x00a0, 0x32, 0x33, 0x34, 0x2c, 0x30, 0x30, 0x29
    };
    UnicodeString cc1(c1, 10, 10);
    if (buffer != cc1)
        errln("nf : " + buffer); // Expect (1 234,00)

    // Erroneously prints:
    // 1234,00 ,
    // (1234,00 ,)

    delete nf1;
}
/* @bug 4068693
 * DecimalFormat.parse returns wrong value
 */
// {sfb} slightly converted into a round-trip test, since in C++
// there is no Double.toString()
void NumberFormatRegressionTest::Test4068693(void)
{
    logln("----- Test Application -----");
    ParsePosition pos(0);
    UErrorCode status = U_ZERO_ERROR;
    DecimalFormat *df = new DecimalFormat(status);
    if(U_FAILURE(status)) {
      errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
      delete df;
      return;
    }
    failure(status, "new DecimalFormat");
    Formattable d;
    //Double d = (Double)df.parse("123.55456", pos=new ParsePosition(0));
    df->parse(UnicodeString("123.55456"), d, pos);
    //if (!d.toString().equals("123.55456")) {
    UnicodeString dstr;
    df->setMaximumFractionDigits(999);
    df->setMaximumIntegerDigits(999);
    FieldPosition fp(FieldPosition::DONT_CARE);
    dstr = df->format(d.getDouble(), dstr, fp);
    if (dstr != UnicodeString("123.55456")) {
        errln(UnicodeString("Result -> ") + d.getDouble());
    }

    delete df;
}

/* @bug 4069754, 4067878
 * null pointer thrown when accessing a deserialized DecimalFormat
 * object.
 */
// {sfb} doesn't apply in C++
void NumberFormatRegressionTest::Test4069754(void)
{
/*    try {
        myformat it = new myformat();
        logln(it.Now());
        FileOutputStream ostream = new FileOutputStream("t.tmp");
        ObjectOutputStream p = new ObjectOutputStream(ostream);
        p.writeObject(it);
        ostream.close();
        logln("Saved ok.");

        FileInputStream istream = new FileInputStream("t.tmp");
        ObjectInputStream p2 = new ObjectInputStream(istream);
        myformat it2 = (myformat)p2.readObject();
        logln(it2.Now());
        istream.close();
        logln("Loaded ok.");
    } catch (Exception foo) {
        errln("Test for bug 4069754 or 4057878 failed => Exception: " + foo.getMessage());
    }
*/}

/* @bug 4087251
 * DecimalFormat.applyPattern(String) allows illegal patterns
 */
void NumberFormatRegressionTest::Test4087251 (void)
{
    UErrorCode status = U_ZERO_ERROR;
    DecimalFormat *df = new DecimalFormat(status);
    if(U_FAILURE(status)) {
      errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
      delete df;
      return;
    }
    failure(status, "new DecimalFormat");
    //try {
        df->applyPattern(UnicodeString("#.#.#"), status);
        if( ! U_FAILURE(status))
            errln("df->applyPattern with illegal pattern didn't fail");
        UnicodeString temp;
        logln("toPattern() returns \"" + df->toPattern(temp) + "\"");
        //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", status);
        if( ! U_FAILURE(status))
            errln("df->applyPattern with illegal pattern didn't fail");
        logln("toPattern() returns \"" + df->toPattern(temp) + "\"");
        //errln("applyPattern(\"#0.0#0#0\") doesn't throw IllegalArgumentException");
    /*} catch (IllegalArgumentException e) {
        logln("Ok - IllegalArgumentException for #0.0#0#0");
    }*/

    delete df;
}

/* @bug 4090489
 * DecimalFormat.format() loses precision
 */
void NumberFormatRegressionTest::Test4090489 (void)
{
// {sfb} sprintf doesn't correctly handle the double, so there is nothing
// that NumberFormat can do.  For some reason, it does not format the last 1.

/*    UErrorCode status = U_ZERO_ERROR;
    DecimalFormat *df = new DecimalFormat(status);
    failure(status, "new DecimalFormat");
    df->setMinimumFractionDigits(10);
    df->setMaximumFractionDigits(999);
    df->setGroupingUsed(FALSE);
    double d = 1.000000000000001E7;
    //BigDecimal bd = new BigDecimal(d);
    UnicodeString sb;
    FieldPosition fp(0);
    logln(UnicodeString("d = ") + d);
    //logln("BigDecimal.toString():  " + bd.toString());
    df->format(d, sb, fp);
    if (sb != "10000000.0000000100") {
        errln("DecimalFormat.format(): " + sb);
    }
*/
}

/* @bug 4090504
 * DecimalFormat.format() loses precision
 */
void NumberFormatRegressionTest::Test4090504 (void)
{
    double d = 1;
    logln(UnicodeString("d = ") + d);
    UErrorCode status = U_ZERO_ERROR;
    DecimalFormat *df = new DecimalFormat(status);
    if(U_FAILURE(status)) {
      errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
      delete df;
      return;
    }
    failure(status, "new DecimalFormat");
    UnicodeString sb;
    FieldPosition fp(FieldPosition::DONT_CARE);
    //try {
        for (int i = 17; i <= 20; i++) {
            df->setMaximumFractionDigits(i);
            //sb = new StringBuffer("");
            fp.setField(0);
            logln(UnicodeString("  getMaximumFractionDigits() = ") + i);
            logln(UnicodeString("  formated: ") + df->format(d, sb, fp));
        }
    /*} catch (Exception foo) {
        errln("Bug 4090504 regression test failed. Message : " + foo.getMessage());
    }*/

    delete df;
}
/* @bug 4095713
 * DecimalFormat.parse(String str, ParsePosition pp) loses precision
 */
void NumberFormatRegressionTest::Test4095713 (void)
{
    UErrorCode status = U_ZERO_ERROR;
    DecimalFormat *df = new DecimalFormat(status);
    if(U_FAILURE(status)) {
      errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
      delete df;
      return;
    }
    failure(status, "new DecimalFormat");
    UnicodeString str("0.1234");
    double d1 = 0.1234;
    //Double d1 = new Double(str);
    //Double d2 = (Double) df.parse(str, new ParsePosition(0));
    Formattable d2;
    ParsePosition pp(0);
    df->parse(str, d2, pp);
    logln(UnicodeString("") + d1);
    if (d2.getDouble() != d1)
        errln(UnicodeString("Bug 4095713 test failed, new double value : ") + d2.getDouble());
    delete df;
}

/* @bug 4092561
 * DecimalFormat.parse() fails when multiplier is not set to 1
 */
// {sfb} not sure what to do with this one
void NumberFormatRegressionTest::Test4092561 (void)
{
    UErrorCode status = U_ZERO_ERROR;
    DecimalFormat *df = new DecimalFormat(status);
    if(U_FAILURE(status)) {
      errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
      delete df;
      return;
    }
    failure(status, "new DecimalFormat");

    // {sfb} going to cheat here and use sprintf ??

    /*UnicodeString 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.");
*/
    delete df;
}

/* @bug 4092480
 * DecimalFormat: Negative format ignored.
 */
void NumberFormatRegressionTest::Test4092480 (void)
{
    UErrorCode status = U_ZERO_ERROR;
    DecimalFormat *dfFoo = new DecimalFormat(UnicodeString("000"), status);
    if(U_FAILURE(status)) {
      errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
      delete dfFoo;
      return;
    }
    failure(status, "new DecimalFormat");

    //try {
        dfFoo->applyPattern("0000;-000", status);
        failure(status, "dfFoo->applyPattern");
        UnicodeString temp;
        if (dfFoo->toPattern(temp) != UnicodeString("#0000"))
            errln("dfFoo.toPattern : " + dfFoo->toPattern(temp));
        FieldPosition pos(FieldPosition::DONT_CARE);
        logln(dfFoo->format((int32_t)42, temp, pos));
        logln(dfFoo->format((int32_t)-42, temp, pos));
        dfFoo->applyPattern("000;-000", status);
        failure(status, "dfFoo->applyPattern");
        if (dfFoo->toPattern(temp) != UnicodeString("#000"))
            errln("dfFoo.toPattern : " + dfFoo->toPattern(temp));
        logln(dfFoo->format((int32_t)42,temp, pos));
        logln(dfFoo->format((int32_t)-42, temp, pos));

        dfFoo->applyPattern("000;-0000", status);
        failure(status, "dfFoo->applyPattern");
        if (dfFoo->toPattern(temp) != UnicodeString("#000"))
            errln("dfFoo.toPattern : " + dfFoo->toPattern(temp));
        logln(dfFoo->format((int32_t)42, temp, pos));
        logln(dfFoo->format((int32_t)-42, temp, pos));

        dfFoo->applyPattern("0000;-000", status);
        failure(status, "dfFoo->applyPattern");
        if (dfFoo->toPattern(temp) != UnicodeString("#0000"))
            errln("dfFoo.toPattern : " + dfFoo->toPattern(temp));
        logln(dfFoo->format((int32_t)42, temp, pos));
        logln(dfFoo->format((int32_t)-42, temp, pos));
    /*} catch (Exception foo) {
        errln("Message " + foo.getMessage());
    }*/

    delete dfFoo;
}
/* @bug 4087244
 * 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!
 */
void NumberFormatRegressionTest::Test4087244 (void) {
    UErrorCode status = U_ZERO_ERROR;
    char loc[256] = {0};
    uloc_canonicalize("pt_PT_PREEURO", loc, 256, &status);
    Locale *de = new Locale(loc);
    NumberFormat *nf = NumberFormat::createCurrencyInstance(*de, status);
    if(U_FAILURE(status)) {
      dataerrln("Error creating DecimalFormat: %s", u_errorName(status));
      delete nf;
      return;
    }
    DecimalFormat *df = dynamic_cast<DecimalFormat *>(nf);
    if(df == NULL) {
        errln("expected DecimalFormat!");
        return;
    }
    const DecimalFormatSymbols *sym = df->getDecimalFormatSymbols();
    UnicodeString decSep = sym->getSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol);
    UnicodeString monSep = sym->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol);
    if (decSep == monSep) {
        errln("ERROR in test: want decimal sep != monetary sep");
        return;
    }
    df->setMinimumIntegerDigits(1);
    df->setMinimumFractionDigits(2);
    UnicodeString str;
    FieldPosition pos;
    df->format(1.23, str, pos);
    UnicodeString monStr("1x23");
    monStr.replace((int32_t)1, 1, monSep);
    UnicodeString decStr("1x23");
    decStr.replace((int32_t)1, 1, decSep);
    if (str.indexOf(monStr) >= 0 && str.indexOf(decStr) < 0) {
        logln(UnicodeString("OK: 1.23 -> \"") + str + "\" contains \"" +
              monStr + "\" and not \"" + decStr + '"');
    } else {
        errln(UnicodeString("FAIL: 1.23 -> \"") + str + "\", should contain \"" +
              monStr +
              "\" and not \"" + decStr + '"');
    }
    delete de;
    delete nf;
}
/* @bug 4070798
 * Number format data rounding errors for locale FR
 */
void NumberFormatRegressionTest::Test4070798 (void) 
{
    NumberFormat *formatter;
    UnicodeString tempString;
    
    /* User error :
    String expectedDefault = "-5\u00a0789,987";
    String expectedCurrency = "5\u00a0789,98\u00a0F";
    String expectedPercent = "-578\u00a0998%";
    */
    UChar chars1 [] = {
        0x2d, 0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x38, 0x38
    };
    UChar chars2 [] = {
        0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x39, 0x00a0, 0x46
    };
    UChar chars3 [] = {
        0x2d, 0x35, 0x37, 0x38, 0x00a0, 0x39, 0x39, 0x39, 0x00a0, 0x25
    };
    UnicodeString expectedDefault(chars1, 10, 10);
    UnicodeString expectedCurrency(chars2, 10, 10);
    UnicodeString expectedPercent(chars3, 10, 10);

    UErrorCode status = U_ZERO_ERROR;
    char loc[256]={0};
    int len = uloc_canonicalize("fr_FR_PREEURO", loc, 256, &status);
    (void)len;  // Suppress set but not used warning.
    formatter = NumberFormat::createInstance(Locale(loc), status);
    if(U_FAILURE(status)) {
      dataerrln("Error creating DecimalFormat: %s", u_errorName(status));
      delete formatter;
      return;
    }
    failure(status, "NumberFormat::createNumberInstance", loc);
    tempString = formatter->format (-5789.9876, tempString);

    if (tempString == expectedDefault) {
        logln ("Bug 4070798 default test passed.");
    } else {
        errln(UnicodeString("Failed:") +
        " Expected " + expectedDefault +
        " Received " + tempString );
    }
    delete formatter;
    len = uloc_canonicalize("fr_FR_PREEURO", loc, 256, &status);
    formatter = NumberFormat::createCurrencyInstance(loc, status);
    failure(status, "NumberFormat::createCurrencyInstance", loc);
    tempString.remove();
    tempString = formatter->format( 5789.9876, tempString );

    if (tempString == expectedCurrency) {
        logln ("Bug 4070798 currency test passed.");
    } else {
        errln(UnicodeString("Failed:") +
        " Expected " + expectedCurrency +
        " Received " + tempString );
    }
    delete formatter;
   
    uloc_canonicalize("fr_FR_PREEURO", loc, 256, &status);
    formatter = NumberFormat::createPercentInstance(Locale(loc), status);
    failure(status, "NumberFormat::createPercentInstance", loc);
    tempString.remove();
    tempString = formatter->format (-5789.9876, tempString);

    if (tempString == expectedPercent) {
        logln ("Bug 4070798 percentage test passed.");
    } else {
        errln(UnicodeString("Failed:") +
        " Expected " + expectedPercent +
        " Received " + tempString );
    }

    delete formatter;
}
/* @bug 4071005
 * Data rounding errors for French (Canada) locale
 */
void NumberFormatRegressionTest::Test4071005 (void) 
{
    NumberFormat *formatter;
    UnicodeString tempString;
    /* User error :
    String expectedDefault = "-5\u00a0789,987";
    String expectedCurrency = "5\u00a0789,98\u00a0$";
    String expectedPercent = "-578\u00a0998%";
    */
    UChar chars1 [] = {
        0x2d, 0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x38, 0x38
    };
    UChar chars2 [] = {
        0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x39, 0x00a0, 0x24
    };
    UChar chars3 [] = {
        0x2d, 0x35, 0x37, 0x38, 0x00a0, 0x39, 0x39, 0x39, 0x00a0, 0x25
    };
    UnicodeString expectedDefault(chars1, 10, 10);
    UnicodeString expectedCurrency(chars2, 10, 10);
    UnicodeString expectedPercent(chars3, 10, 10);

    UErrorCode status = U_ZERO_ERROR;
    formatter = NumberFormat::createInstance(Locale::getCanadaFrench(), status);
    if (failure(status, "NumberFormat::createNumberInstance", Locale::getCanadaFrench(), TRUE)){
        delete formatter;
        return;
    };
    tempString = formatter->format (-5789.9876, tempString);

    if (tempString == expectedDefault) {
        logln ("Bug 4071005 default test passed.");
    } else {
        errln(UnicodeString("Failed:") +
        " Expected " + expectedDefault +
        " Received " + tempString );
    }
    delete formatter;

    formatter = NumberFormat::createCurrencyInstance(Locale::getCanadaFrench(), status);
    failure(status, "NumberFormat::createCurrencyInstance", Locale::getCanadaFrench());
    tempString.remove();
    tempString = formatter->format( 5789.9876, tempString );

    if (tempString == expectedCurrency) {
        logln ("Bug 4071005 currency test assed.");
    } else {
        errln(UnicodeString("Failed:") +
        " Expected " + expectedCurrency +
        " Received " + tempString );
    }
    delete formatter;

    formatter = NumberFormat::createPercentInstance(Locale::getCanadaFrench(), status);
    failure(status, "NumberFormat::createPercentInstance", Locale::getCanadaFrench());
    tempString.remove();
    tempString = formatter->format (-5789.9876, tempString);

    if (tempString == expectedPercent) {
        logln ("Bug 4071005 percentage test passed.");
    } else {
        errln(UnicodeString("Failed:") +
        " Expected " + expectedPercent +
        " Received " + tempString );
    }

    delete formatter;
}

/* @bug 4071014
 * Data rounding errors for German (Germany) locale
 */
void NumberFormatRegressionTest::Test4071014 (void) 
{
    NumberFormat *formatter;
    UnicodeString tempString;
    /* user error :
    String expectedDefault = "-5.789,987";
    String expectedCurrency = "5.789,98 DEM";
    String expectedPercent = "-578.998%";
    */
    UnicodeString expectedDefault("-5.789,988");
    UnicodeString expectedCurrency("5.789,99\\u00A0DEM");
    UnicodeString expectedPercent("-578.999\\u00A0%");

    expectedCurrency = expectedCurrency.unescape();
    expectedPercent = expectedPercent.unescape();

    UErrorCode status = U_ZERO_ERROR;
    char loc[256]={0};
    uloc_canonicalize("de_DE_PREEURO", loc, 256, &status);
    formatter = NumberFormat::createInstance(Locale(loc), status);
    if (failure(status, "NumberFormat::createNumberInstance", loc, TRUE)){
        delete formatter;
        return;
    }
    tempString.remove();
    tempString = formatter->format (-5789.9876, tempString);

    if (tempString == expectedDefault) {
        logln ("Bug 4071014 default test passed.");
    } else {
        errln(UnicodeString("Failed:") +
        " Expected " + expectedDefault +
        " Received " + tempString );
    }
    delete formatter;
    uloc_canonicalize("de_DE_PREEURO", loc, 256, &status);
    formatter = NumberFormat::createCurrencyInstance(Locale(loc), status);
    failure(status, "NumberFormat::createCurrencyInstance", loc);
    tempString.remove();
    tempString = formatter->format( 5789.9876, tempString );

    if (tempString == expectedCurrency) {
        logln ("Bug 4071014 currency test assed.");
    } else {
        errln(UnicodeString("Failed:") +
        " Expected " + expectedCurrency +
        " Received " + tempString );
    }
    delete formatter;

    formatter = NumberFormat::createPercentInstance(Locale::getGermany(), status);
    failure(status, "NumberFormat::createPercentInstance", Locale::getGermany());
    tempString.remove();
    tempString = formatter->format (-5789.9876, tempString);

    if (tempString == expectedPercent) {
        logln ("Bug 4071014 percentage test passed.");
    } else {
        errln(UnicodeString("Failed:") +
        " Expected " + expectedPercent +
        " Received " + tempString );
    }

    delete formatter;
}
/* @bug 4071859
 * Data rounding errors for Italian locale number formats
 */
void NumberFormatRegressionTest::Test4071859 (void) 
{
    NumberFormat *formatter;
    UnicodeString tempString;
    /* user error :
    String expectedDefault = "-5.789,987";
    String expectedCurrency = "-L.\\u00A05.789,98";
    String expectedPercent = "-578.998%";
    */
    UnicodeString expectedDefault("-5.789,988");
    UnicodeString expectedCurrency("-ITL\\u00A05.790", -1, US_INV);
    UnicodeString expectedPercent("-578.999%");
    expectedCurrency = expectedCurrency.unescape();

    UErrorCode status = U_ZERO_ERROR;
    char loc[256]={0};
    uloc_canonicalize("it_IT_PREEURO", loc, 256, &status);
    formatter = NumberFormat::createInstance(Locale(loc), status);
    if (failure(status, "NumberFormat::createNumberInstance", TRUE)){
        delete formatter;
        return;
    };
    tempString = formatter->format (-5789.9876, tempString);

    if (tempString == expectedDefault) {
        logln ("Bug 4071859 default test passed.");
    } else {
        errln(UnicodeString("Failed:") +
        " Expected " + expectedDefault +
        " Received " + tempString );
    }
    delete formatter;
    uloc_canonicalize("it_IT_PREEURO", loc, 256, &status);
    formatter = NumberFormat::createCurrencyInstance(Locale(loc), status);
    failure(status, "NumberFormat::createCurrencyInstance");
    tempString.remove();
    tempString = formatter->format( -5789.9876, tempString );

    if (tempString == expectedCurrency) {
        logln ("Bug 4071859 currency test assed.");
    } else {
        errln(UnicodeString("Failed:") +
        " Expected " + expectedCurrency +
        " Received " + tempString );
    }
    delete formatter;
    uloc_canonicalize("it_IT_PREEURO", loc, 256, &status);
    formatter = NumberFormat::createPercentInstance(Locale(loc), status);
    failure(status, "NumberFormat::createPercentInstance");
    tempString.remove();
    tempString = formatter->format (-5789.9876, tempString);

    if (tempString == expectedPercent) {
        logln ("Bug 4071859 percentage test passed.");
    } else {
        errln(UnicodeString("Failed:") +
        " Expected " + expectedPercent +
        " Received " + tempString );
    }

    delete formatter;
}
/* @bug 4071859
 * Test rounding for nearest even.
 */
void NumberFormatRegressionTest::Test4093610(void)
{
    UErrorCode status = U_ZERO_ERROR;
    DecimalFormat *df = new DecimalFormat("#0.#", status);
    if (!failure(status, "new DecimalFormat")) {
        UnicodeString s("12.4");
        roundingTest(df, 12.35, s);
        roundingTest(df, 12.45, s);
        s = "12.5";
        roundingTest(df, 12.452,s);
        s = "12.6";
        roundingTest(df, 12.55, s);
        roundingTest(df, 12.65, s);
        s = "12.7";
        roundingTest(df, 12.652,s);
        s = "12.8";
        roundingTest(df, 12.75, s);
        roundingTest(df, 12.752,s);
        roundingTest(df, 12.85, s);
        s = "12.9";
        roundingTest(df, 12.852,s);
        s = "13";
        roundingTest(df, 12.95, s);
        roundingTest(df, 12.952,s);
    }

    delete df;
}

void NumberFormatRegressionTest::roundingTest(DecimalFormat *df, double x, UnicodeString& expected)
{
    UnicodeString out;
    FieldPosition pos(FieldPosition::DONT_CARE);
    out = df->format(x, out, pos);
    logln(UnicodeString("") + x + " formats with 1 fractional digits to " + out);
    if (out != expected) 
        errln("FAIL: Expected " + expected);
}
/* @bug 4098741
 * Tests the setMaximumFractionDigits limit.
 */
void NumberFormatRegressionTest::Test4098741(void)
{
    //try {
    UErrorCode status = U_ZERO_ERROR;
    NumberFormat *fmt = NumberFormat::createPercentInstance(status);
    if (U_FAILURE(status)) {
        dataerrln("Error calling NumberFormat::createPercentInstance");
        delete fmt;
        return;
    }

        fmt->setMaximumFractionDigits(20);
        UnicodeString temp;
        logln(fmt->format(.001, temp));
    /*} catch (Exception foo) {
        errln("Bug 4098471 failed with exception thrown : " + foo.getMessage());
    }*/
    delete fmt;
}
/* @bug 4074454
 * Tests illegal pattern exception.
 * Fix comment : HShih A31 Part1 will not be fixed and javadoc needs to be updated.
 * Part2 has been fixed.
 */
void NumberFormatRegressionTest::Test4074454(void)
{
    //try {
    UErrorCode status = U_ZERO_ERROR;  
    DecimalFormat *fmt = new DecimalFormat("#,#00.00;-#.#", status);
    if(U_FAILURE(status)) {
      errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
      delete fmt;
      return;
    }
    failure(status, "new DecimalFormat");
      logln("Inconsistent negative pattern is fine.");
        DecimalFormat *newFmt = new DecimalFormat("#,#00.00 p''ieces;-#,#00.00 p''ieces", status);
        failure(status, "new DecimalFormat");
        UnicodeString tempString;
        FieldPosition pos(FieldPosition::DONT_CARE);
        tempString = newFmt->format(3456.78, tempString, pos);
        if (tempString != UnicodeString("3,456.78 p'ieces"))
            dataerrln("Failed!  3456.78 p'ieces expected, but got : " + tempString);
    /*} catch (Exception foo) {
        errln("An exception was thrown for any inconsistent negative pattern.");
    }*/

    delete fmt;
    delete newFmt;
}
/* @bug 4099404
 * 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.
 */
void NumberFormatRegressionTest::Test4099404(void)
{
    //try {
        UErrorCode status = U_ZERO_ERROR;
        DecimalFormat *fmt = new DecimalFormat(UnicodeString("000.0#0"), status);
        if(! U_FAILURE(status))
            errln(UnicodeString("Bug 4099404 failed applying illegal pattern \"000.0#0\""));
    /*} catch (Exception foo) {
        logln("Bug 4099404 pattern \"000.0#0\" passed");
    }*/
    delete fmt;
    fmt = 0;
        //try {
        fmt = new DecimalFormat(UnicodeString("0#0.000"), status);
        if( !U_FAILURE(status))
           errln("Bug 4099404 failed applying illegal pattern \"0#0.000\"");
    /*} catch (Exception foo) {
        logln("Bug 4099404 pattern \"0#0.000\" passed");
    }*/

    delete fmt;
}
/* @bug 4101481
 * DecimalFormat.applyPattern doesn't set minimum integer digits
 */
void NumberFormatRegressionTest::Test4101481(void)
{
    UErrorCode status = U_ZERO_ERROR;
    DecimalFormat *sdf = new DecimalFormat(UnicodeString("#,##0"), status);
    if(U_FAILURE(status)) {
      errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
      delete sdf;
      return;
    }
    failure(status, "new DecimalFormat");
    if (sdf->getMinimumIntegerDigits() != 1)
        errln(UnicodeString("Minimum integer digits : ") + sdf->getMinimumIntegerDigits());
    delete sdf;
}
/* @bug 4052223 (API addition request A27)
 * Tests ParsePosition.setErrorPosition() and ParsePosition.getErrorPosition().
 */
void NumberFormatRegressionTest::Test4052223(void)
{
    //try {
    UErrorCode status = U_ZERO_ERROR;
        DecimalFormat *fmt = new DecimalFormat(UnicodeString("#,#00.00"), status);
        if(U_FAILURE(status)) {
          errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
          delete fmt;
          return;
        }
        failure(status, "new DecimalFormat");
        Formattable num;
        fmt->parse(UnicodeString("abc3"), num, status);
        if(! U_FAILURE(status))
            errln(UnicodeString("Bug 4052223 failed : can't parse string \"a\".  Got ") /*+ num*/);
    /*} catch (ParseException foo) {
        logln("Caught expected ParseException : " + foo.getMessage() + " at index : " + foo.getErrorOffset());
    }*/
    delete fmt;
}
/* @bug 4061302
 * API tests for API addition request A9.
 */
void NumberFormatRegressionTest::Test4061302(void)
{
    UErrorCode status = U_ZERO_ERROR;
    DecimalFormatSymbols *fmt = new DecimalFormatSymbols(status);
    failure(status, "new DecimalFormatSymbols");
    UnicodeString currency(fmt->getSymbol(DecimalFormatSymbols::kCurrencySymbol));
    UnicodeString intlCurrency(fmt->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol));
    UnicodeString monDecSeparator(fmt->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol));
    if (currency == UnicodeString("") ||
        intlCurrency == UnicodeString("") ||
        monDecSeparator == UnicodeString(""))
    {
        errln("getCurrencySymbols failed, got empty string.");
    }
    UnicodeString monDecSeparatorStr;
    monDecSeparatorStr.append(monDecSeparator);
    logln((UnicodeString)"Before set ==> Currency : " + currency +(UnicodeString)" Intl Currency : " + intlCurrency + (UnicodeString)" Monetary Decimal Separator : " + monDecSeparatorStr);
    fmt->setSymbol(DecimalFormatSymbols::kCurrencySymbol, UnicodeString("XYZ"));
    fmt->setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol, UnicodeString("ABC"));
    fmt->setSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol, UnicodeString((UChar)0x002A/*'*'*/));
    currency = fmt->getSymbol(DecimalFormatSymbols::kCurrencySymbol);
    intlCurrency = fmt->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol);
    monDecSeparator = fmt->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol);
    if (currency != UnicodeString("XYZ") ||
        intlCurrency != UnicodeString("ABC") ||
        monDecSeparator != UnicodeString((UChar)0x002A/*'*'*/)) {
        errln("setCurrencySymbols failed.");
    }
    monDecSeparatorStr.remove();
    monDecSeparatorStr.append(monDecSeparator);
    logln("After set ==> Currency : " + currency + " Intl Currency : " + intlCurrency + " Monetary Decimal Separator : " + monDecSeparatorStr);

    delete fmt;
}
/* @bug 4062486
 * API tests for API addition request A23. FieldPosition.getBeginIndex and
 * FieldPosition.getEndIndex.
 */
void NumberFormatRegressionTest::Test4062486(void)
{
    UErrorCode status = U_ZERO_ERROR;
    DecimalFormat *fmt = new DecimalFormat(UnicodeString("#,##0.00"), status);
    failure(status, "new DecimalFormat");
    UnicodeString formatted;
    FieldPosition field(0);
    double num = 1234.5;
    fmt->format(num, formatted, field);
    if (field.getBeginIndex() != 0 && field.getEndIndex() != 5)
        errln(UnicodeString("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()*/);

    delete fmt;
}

/* @bug 4108738
 * DecimalFormat.parse incorrectly works with a group separator.
 */
void NumberFormatRegressionTest::Test4108738(void)
{
    UErrorCode status = U_ZERO_ERROR;
    DecimalFormatSymbols *syms = new DecimalFormatSymbols(Locale::getUS(), status);
    failure(status, "new DecimalFormatSymbols");
    DecimalFormat *df = new DecimalFormat("#,##0.###", syms, status);
    if(U_FAILURE(status)) {
      errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
      delete df;
      return;
    }
    failure(status, "new DecimalFormat");
    UnicodeString text("1.222,111");
    Formattable num;
    ParsePosition pp(0);
    df->parse(text, num, pp);
    
    // {sfb} how to do this (again) ?
    // shouldn't just be another round-trip test, should it?
    UnicodeString temp;
    FieldPosition pos(FieldPosition::DONT_CARE);
    temp = df->format(num.getDouble(), temp, pos);
    //if (!num.toString().equals("1.222"))
    if (temp != UnicodeString("1.222"))
        //errln("\"" + text + "\"  is parsed as " + num);
        errln("\"" + text + "\"  is parsed as " + temp);
    text = UnicodeString("1.222x111");
    pp = ParsePosition(0);
    df->parse(text, num, pp);
    temp.remove();
    temp = df->format(num.getDouble(), temp, pos);
    //if (!num.toString().equals("1.222"))
    if (temp != UnicodeString("1.222"))
        errln("\"" + text + "\"  is parsed as " + temp);

    delete df;
}

/* @bug 4106658
 * DecimalFormat.format() incorrectly formats negative doubles.
 */
void NumberFormatRegressionTest::Test4106658(void)
{
    UErrorCode status = U_ZERO_ERROR;
    DecimalFormat *df = new DecimalFormat(status); // Corrected; see 4147706
    if(U_FAILURE(status)) {
      errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
      delete df;
      return;
    }
    failure(status, "new DecimalFormat");
    volatile double d1 = 0.0;   // volatile to prevent code optimization
    double d2 = -0.0001;
    UnicodeString buffer;
    UnicodeString temp;
    FieldPosition pos(FieldPosition::DONT_CARE);

#if U_PLATFORM == U_PF_HPUX
    d1 = 0.0 * -1.0;    // old HPUX compiler ignores volatile keyword
#else
    d1 *= -1.0; // Some compilers have a problem with defining -0.0
#endif
    logln("pattern: \"" + df->toPattern(temp) + "\"");
    df->format(d1, buffer, pos);
    if (buffer != UnicodeString("-0")) // Corrected; see 4147706
        errln(UnicodeString("") + d1 + "      is formatted as " + buffer);
    buffer.remove();
    df->format(d2, buffer, pos);
    if (buffer != UnicodeString("-0")) // Corrected; see 4147706
        errln(UnicodeString("") + d2 + "      is formatted as " + buffer);

    delete df;
}

/* @bug 4106662
 * DecimalFormat.parse returns 0 if string parameter is incorrect.
 */
void NumberFormatRegressionTest::Test4106662(void)
{
    UErrorCode status = U_ZERO_ERROR;
    DecimalFormat *df = new DecimalFormat(status);
    if(U_FAILURE(status)) {
      errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
      delete df;
      return;
    }
    failure(status, "new DecimalFormat");
    UnicodeString text("x");
    ParsePosition pos1(0), pos2(0);

    UnicodeString temp;
    logln("pattern: \"" + df->toPattern(temp) + "\"");
    Formattable num;
    df->parse(text, num, pos1);
    if (pos1 == ParsePosition(0)/*num != null*/) {
        errln(UnicodeString("Test Failed: \"") + text + "\" is parsed as " /*+ num*/);
    }
    delete df;
    df = new DecimalFormat(UnicodeString("$###.00"), status);
    failure(status, "new DecimalFormat");
    df->parse(UnicodeString("$"), num, pos2);
    if (pos2 == ParsePosition(0) /*num != null*/){
        errln(UnicodeString("Test Failed: \"$\" is parsed as ") /*+ num*/);
    }

    delete df;
}

/* @bug 4114639 (duplicate of 4106662)
 * NumberFormat.parse doesn't return null
 */
void NumberFormatRegressionTest::Test4114639(void)
{
    UErrorCode status = U_ZERO_ERROR;
    NumberFormat *format = NumberFormat::createInstance(status);
    if(U_FAILURE(status)) {
      dataerrln("Error creating DecimalFormat: %s", u_errorName(status));
      delete format;
      return;
    }
    failure(status, "NumberFormat::createInstance");
    UnicodeString text("time 10:x");
    ParsePosition pos(8);
    Formattable result;
    format->parse(text, result, pos);
    if (/*result != null*/pos.getErrorIndex() != 8) 
        errln(UnicodeString("Should return null but got : ") /*+ result*/); // Should be null; it isn't

    delete format;
}

/* @bug 4106664
 * TODO: this test does not work because we need to use a 64 bit number and a
 * a double only MAY only have 52 bits of precision.
 * DecimalFormat.format(long n) fails if n * multiplier > MAX_LONG.
 */
void NumberFormatRegressionTest::Test4106664(void)
{
    UErrorCode status = U_ZERO_ERROR;
    DecimalFormat *df = new DecimalFormat(status);
    if(U_FAILURE(status)) {
      errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
      delete df;
      return;
    }
    failure(status, "new DecimalFormat");
    // {sfb} long in java is 64 bits
    /*long*/double n = 1234567890123456.0;
    /*int*/int32_t m = 12345678;
    // {sfb} will this work?
    //BigInteger bigN = BigInteger.valueOf(n);
    //bigN = bigN.multiply(BigInteger.valueOf(m));
    double bigN = n * m;
    df->setMultiplier(m);
    df->setGroupingUsed(FALSE);
    UnicodeString temp;
    FieldPosition pos(FieldPosition::DONT_CARE);
    logln("formated: " +
        df->format(n, temp, pos));
    
    char buf [128];
    sprintf(buf, "%g", bigN);
    //logln("expected: " + bigN.toString());
    logln(UnicodeString("expected: ") + buf);

    delete df;
}
/* @bug 4106667 (duplicate of 4106658)
 * DecimalFormat.format incorrectly formats -0.0.
 */
void NumberFormatRegressionTest::Test4106667(void)
{
    UErrorCode status = U_ZERO_ERROR;
    DecimalFormat *df = new DecimalFormat(status);
    if(U_FAILURE(status)) {
      errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
      delete df;
      return;
    }
    failure(status, "new DecimalFormat");
    UChar foo [] = { 0x002B };
    UnicodeString bar(foo, 1, 1);
    volatile double d = 0.0;   // volatile to prevent code optimization
    UnicodeString temp;
    UnicodeString buffer;
    FieldPosition pos(FieldPosition::DONT_CARE);

    logln("pattern: \"" + df->toPattern(temp) + "\"");
#if U_PLATFORM == U_PF_HPUX
    d = 0.0 * -1.0;    // old HPUX compiler ignores volatile keyword
#else
    d *= -1.0; // Some compilers have a problem with defining -0.0
#endif
    df->setPositivePrefix(/*"+"*/bar);
    df->format(d, buffer, pos);
    if (buffer != UnicodeString("-0")) // Corrected; see 4147706
        errln(/*d + */UnicodeString("  is formatted as ") + buffer);

    delete df;
}

/* @bug 4110936
 * DecimalFormat.setMaximumIntegerDigits() works incorrectly.
 */
#if U_PLATFORM == U_PF_OS390
#   define MAX_INT_DIGITS 70
#else
#   define MAX_INT_DIGITS 128
#endif

void NumberFormatRegressionTest::Test4110936(void)
{
    UErrorCode status = U_ZERO_ERROR;
    NumberFormat *nf = NumberFormat::createInstance(status);
    if(U_FAILURE(status)) {
      dataerrln("Error creating DecimalFormat: %s", u_errorName(status));
      delete nf;
      return;
    }
    failure(status, "NumberFormat::createInstance");
    nf->setMaximumIntegerDigits(MAX_INT_DIGITS);
    logln("setMaximumIntegerDigits(MAX_INT_DIGITS)");
    if (nf->getMaximumIntegerDigits() != MAX_INT_DIGITS)
        errln(UnicodeString("getMaximumIntegerDigits() returns ") +
            nf->getMaximumIntegerDigits());

    delete nf;
}

/* @bug 4122840
 * 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.
 */
void NumberFormatRegressionTest::Test4122840(void)
{
    int32_t count = 0;
    const Locale *locales = Locale::getAvailableLocales(count);
    
    for (int i = 0; i < count; i++) {
        UErrorCode status = U_ZERO_ERROR;
        ResourceBundle *rb = new ResourceBundle(
            NULL/*"java.text.resources.LocaleElements"*/, 
            locales[i], status);
        failure(status, "new ResourceBundle");
        ResourceBundle numPat = rb->getWithFallback("NumberElements", status);
        failure(status, "rb.get(NumberElements)");
        numPat = numPat.getWithFallback("latn",status);
        failure(status, "rb.get(latn)");
        numPat = numPat.getWithFallback("patterns",status);
        failure(status, "rb.get(patterns)");
        numPat = numPat.getWithFallback("currencyFormat",status);
        failure(status, "rb.get(currencyFormat)");
       //
        // 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
        //
        UnicodeString pattern = numPat.getString(status);
        failure(status, "rb->getString()");

        UChar fo[] = { 0x00A4 };
        UnicodeString foo(fo, 1, 1);

        //if (pattern.indexOf("\u00A4") == -1 ) {
        if (pattern.indexOf(foo) == -1 ) {
            errln(UnicodeString("Currency format for ") + UnicodeString(locales[i].getName()) +
                    " 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], status);
        failure(status, "new DecimalFormatSymbols");
        DecimalFormat *fmt1 = new DecimalFormat(pattern, *symbols, status);
        failure(status, "new DecimalFormat");
        
        UnicodeString result1;
        FieldPosition pos(FieldPosition::DONT_CARE);
        result1 = fmt1->format(1.111, result1, pos);
        
        //
        // Now substitute in the locale's currency symbol and create another
        // pattern.  We have to skip locales where the currency symbol
        // contains decimal separators, because that confuses things
        //
        UChar ba[] = { 0x002E/*'.'*/ };
        UnicodeString bar(ba, 1, 1);

        if (symbols->getSymbol(DecimalFormatSymbols::kCurrencySymbol).indexOf(bar) == -1) {
            // {sfb} Also, switch the decimal separator to the monetary decimal
            // separator to mimic the behavior of a currency format
            symbols->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol,
                symbols->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol));
            
            UnicodeString buf(pattern);
            for (int j = 0; j < buf.length(); j++) {
                if (buf[j] == 0x00a4 ) {
                    if(buf[j + 1] == 0x00a4) {
                        // {sfb} added to support double currency marker (intl currency sign)
                        buf.replace(j, /*j+*/2, symbols->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol));
                        j += symbols->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol).length();
                    }
                    else {
                        buf.replace(j, /*j+*/1, symbols->getSymbol(DecimalFormatSymbols::kCurrencySymbol)); 
                        j += symbols->getSymbol(DecimalFormatSymbols::kCurrencySymbol).length() - 1;
                    }                    
                }
            }

            DecimalFormat *fmt2 = new DecimalFormat(buf, *symbols, status);
            failure(status, "new DecimalFormat");
            
            // Get the currency (if there is one) so we can set the rounding and fraction
            const UChar *currency = fmt1->getCurrency();
            if (*currency != 0) {
                double rounding = ucurr_getRoundingIncrement(currency, &status);
                int32_t frac = ucurr_getDefaultFractionDigits(currency, &status);
                if (U_SUCCESS(status)) {
                    fmt2->setRoundingIncrement(rounding);
                    fmt2->setMinimumFractionDigits(frac);
                    fmt2->setMaximumFractionDigits(frac);
                }
                else {
                    failure(status, "Fetching currency rounding/fractions");
                }
            }
            
            UnicodeString result2;
            fmt2->format(1.111, result2, pos);
            
            if (result1 != result2) {
                errln("Results for " + (UnicodeString)(locales[i].getName()) + " differ: " +
                        result1 + " vs " + result2);
            }
        
            delete fmt2;
        }
    
        delete rb;
        delete fmt1;
        delete symbols;
    }
}
 
/* @bug 4125885
 * DecimalFormat.format() delivers wrong string.
 */
void NumberFormatRegressionTest::Test4125885(void)
{
    UErrorCode status = U_ZERO_ERROR;
    double rate = 12.34;
    DecimalFormat *formatDec = new DecimalFormat ("000.00", status);
    if(U_FAILURE(status)) {
      errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
      delete formatDec;
      return;
    }
    failure(status, "new DecimalFormat");
    UnicodeString temp;
    logln("toPattern: " + formatDec->toPattern(temp));
    UnicodeString rateString;
    FieldPosition pos(FieldPosition::DONT_CARE);
    rateString = formatDec->format(rate, rateString, pos);
    if (rateString != UnicodeString("012.34"))
        errln("result : " + rateString + " expected : 012.34");
    rate = 0.1234;
    delete formatDec;// = null;
    formatDec = new DecimalFormat ("+000.00%;-000.00%", status);
    failure(status, "new DecimalFormat");
    logln("toPattern: " + formatDec->toPattern(temp));
    rateString.remove();
    rateString = formatDec->format(rate, rateString, pos);
    if (rateString != UnicodeString("+012.34%"))
        errln("result : " + rateString + " expected : +012.34%");

    delete formatDec;
}

/**
 * @bug 4134034
 * DecimalFormat produces extra zeros when formatting numbers.
 */
void NumberFormatRegressionTest::Test4134034(void) 
{
    UErrorCode status = U_ZERO_ERROR;
    DecimalFormat *nf = new DecimalFormat("##,###,###.00", status);
    if (!failure(status, "new DecimalFormat")) {
        UnicodeString f;
        FieldPosition pos(FieldPosition::DONT_CARE);
        f = nf->format(9.02, f, pos);
        if (f == UnicodeString("9.02")) 
            logln(f + " ok"); 
        else 
            errln("9.02 -> " + f + "; want 9.02");

        f.remove();
        f = nf->format((int32_t)0, f, pos);
        if (f == UnicodeString(".00")) 
            logln(f + " ok"); 
        else 
            errln("0 -> " + f + "; want .00");
    }

    delete nf;
}

/**
 * @bug 4134300
 * 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'
 */
void NumberFormatRegressionTest::Test4134300(void) {
    UnicodeString DATA [] = {
     // Pattern      Expected string
        UnicodeString("#.00"),      UnicodeString("1.20"),
        UnicodeString("0.00"),      UnicodeString("1.20"),
        UnicodeString("00.00"),     UnicodeString("01.20"),
        UnicodeString("#0.0#"),     UnicodeString("1.2"),
        UnicodeString("#0.00"),     UnicodeString("1.20")
    };

    for (int i=0; i< 10; i+=2) {
        UnicodeString result;
        UErrorCode status = U_ZERO_ERROR;
        DecimalFormat *df = new DecimalFormat(DATA[i], status);
        if (!failure(status, "new DecimalFormat")) {
            FieldPosition pos(FieldPosition::DONT_CARE);
            result = df->format(1.2, result, pos);
            if (result != DATA[i+1]) {
                errln("Fail: 1.2 x " + DATA[i] + " = " + result +
                      "; want " + DATA[i+1]);
            }
            else {
                logln("Ok: 1.2 x " + DATA[i] + " = " + result);
            }
        }
    
        delete df;
    }
}

/**
 * @bug 4140009
 * Empty pattern produces double negative prefix.
 */
void NumberFormatRegressionTest::Test4140009(void) 
{
    UErrorCode status = U_ZERO_ERROR;
    DecimalFormatSymbols *syms = new DecimalFormatSymbols(Locale::getEnglish(), status);
    failure(status, "new DecimalFormatSymbols");
    DecimalFormat *f = new DecimalFormat(UnicodeString(""), syms, status);
    if (!failure(status, "new DecimalFormat")) {
        UnicodeString s;
        FieldPosition pos(FieldPosition::DONT_CARE);
        s = f->format(123.456, s, pos);
        if (s != UnicodeString("123.456"))
            errln("Fail: Format empty pattern x 123.456 => " + s);
        s.remove();
        s = f->format(-123.456, s, pos);
        if (s != UnicodeString("-123.456"))
            errln("Fail: Format empty pattern x -123.456 => " + s);
    }
    delete f;
}

/**
 * @bug 4141750
 * BigDecimal numbers get their fractions truncated by NumberFormat.
 */
// {sfb} not pertinent in C++ ??
void NumberFormatRegressionTest::Test4141750(void) {
    /*try {
        UnicodeString 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();
    }*/
}

/**
 * @bug 4145457
 * DecimalFormat toPattern() doesn't quote special characters or handle
 * single quotes.
 */
void NumberFormatRegressionTest::Test4145457() {
    //try {
    UErrorCode status = U_ZERO_ERROR;
    NumberFormat *nff = NumberFormat::createInstance(status);
    if (failure(status, "NumberFormat::createInstance", TRUE)){
        delete nff;
        return;
    };
    DecimalFormat *nf = dynamic_cast<DecimalFormat *>(nff);
    if(nf == NULL) {
        errln("DecimalFormat needed to continue");
        return;
    }

    DecimalFormatSymbols *sym = (DecimalFormatSymbols*) nf->getDecimalFormatSymbols();
    sym->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, (UChar)/*'\''*/0x0027);
    nf->setDecimalFormatSymbols(*sym);
    double pi = 3.14159;
    
    UnicodeString PATS [] = { 
        UnicodeString("#.00 'num''ber'"), UnicodeString("''#.00''")
    };

    for (int32_t i=0; i<2; ++i) {
        nf->applyPattern(PATS[i], status);
        failure(status, "nf->applyPattern");
        UnicodeString out;
        FieldPosition pos(FieldPosition::DONT_CARE);
        out = nf->format(pi, out, pos);
        UnicodeString pat;
        pat = nf->toPattern(pat);
        Formattable num;
        ParsePosition pp(0);
        nf->parse(out, num, pp);
        double val = num.getDouble();
        
        nf->applyPattern(pat, status);
        failure(status, "nf->applyPattern");
        UnicodeString out2;
        out2 = nf->format(pi, out2, pos);
        UnicodeString pat2;
        pat2 = nf->toPattern(pat2);
        pp.setIndex(0);
        nf->parse(out2, num, pp);
        double val2 = num.getDouble();
        
        if (pat != pat2)
            errln("Fail with \"" + PATS[i] + "\": Patterns should concur, \"" +
                pat + "\" vs. \"" + pat2 + "\"");
        else
            logln("Ok \"" + PATS[i] + "\" toPattern() -> \"" + pat + '"');
        
        if (val == val2 && out == out2) {
            logln(UnicodeString("Ok ") + pi + " x \"" + PATS[i] + "\" -> \"" +
                out + "\" -> " + val + " -> \"" +
                out2 + "\" -> " + val2);
        }
        else {
            errln(UnicodeString("Fail ") + pi + " x \"" + PATS[i] + "\" -> \"" +
                out + "\" -> " + val + " -> \"" +
                out2 + "\" -> " + val2);
        }
    }
    /*}
    catch (ParseException e) {
        errln("Fail: " + e);
        e.printStackTrace();
    }*/

    delete nff;
}

/**
 * @bug 4147295
 * DecimalFormat.applyPattern() sets minimum integer digits incorrectly.
 * CANNOT REPRODUCE
 * This bug is a duplicate of 4139344, which is a duplicate of 4134300
 */
void NumberFormatRegressionTest::Test4147295(void) 
{
    UErrorCode status = U_ZERO_ERROR;
    DecimalFormat *sdf = new DecimalFormat(status);
    UnicodeString pattern("#,###");
    logln("Applying pattern \"" + pattern + "\"");
    sdf->applyPattern(pattern, status);
    if (!failure(status, "sdf->applyPattern")) {
        int minIntDig = sdf->getMinimumIntegerDigits();
        if (minIntDig != 0) {
            errln("Test failed");
            errln(UnicodeString(" Minimum integer digits : ") + minIntDig);
            UnicodeString temp;
            errln(UnicodeString(" new pattern: ") + sdf->toPattern(temp));
        } else {
            logln("Test passed");
            logln(UnicodeString(" Minimum integer digits : ") + minIntDig);
        }
    }
    delete sdf;
}

/**
 * @bug 4147706
 * DecimalFormat formats -0.0 as +0.0
 * See also older related bug 4106658, 4106667
 */
void NumberFormatRegressionTest::Test4147706(void) 
{
    UErrorCode status = U_ZERO_ERROR;
    DecimalFormat *df = new DecimalFormat("#,##0.0##", status);
    failure(status, "new DecimalFormat");
    DecimalFormatSymbols *syms = new DecimalFormatSymbols(Locale::getEnglish(), status);
    if (!failure(status, "new DecimalFormatSymbols")) {
        UnicodeString f1;
        UnicodeString f2, temp;
        FieldPosition pos(FieldPosition::DONT_CARE);
        volatile double d1 = 0.0;   // volatile to prevent code optimization
        double d2 = -0.0001;

#if U_PLATFORM == U_PF_HPUX
        d1 = 0.0 * -1.0;    // old HPUX compiler ignores volatile keyword
#else
        d1 *= -1.0; // Some compilers have a problem with defining -0.0
#endif
        df->adoptDecimalFormatSymbols(syms);
        f1 = df->format(d1, f1, pos);
        f2 = df->format(d2, f2, pos);
        if (f1 != UnicodeString("-0.0")) {
            errln(UnicodeString("") + d1 + UnicodeString(" x \"") + df->toPattern(temp) + "\" is formatted as \"" + f1 + '"');
        }
        if (f2 != UnicodeString("-0.0")) {
            errln(UnicodeString("") + d2 + UnicodeString(" x \"") + df->toPattern(temp) + "\" is formatted as \"" + f2 + '"');
        }
    }
    
    delete df;
}


// Not applicable, since no serialization in C++
/*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;
}
}*/

/**
 * @bug 4162198
 * NumberFormat cannot format Double.MAX_VALUE
 */
// TODO: make this test actually test something
void 
NumberFormatRegressionTest::Test4162198(void) 
{
    // for some reason, DBL_MAX will not round trip. (bug in sprintf/atof)
    double dbl = INT32_MAX * 1000.0;
    UErrorCode status = U_ZERO_ERROR;
    NumberFormat *f = NumberFormat::createInstance(status);
    if(U_FAILURE(status)) {
        dataerrln("Couldn't create number format - %s", u_errorName(status));
        return;
    }
    f->setMaximumFractionDigits(INT32_MAX);
    f->setMaximumIntegerDigits(INT32_MAX);
    UnicodeString s;
    f->format(dbl,s);
    logln(UnicodeString("The number ") + dbl + " formatted to " + s);
    Formattable n;
    //try {
    f->parse(s, n, status);
    if(U_FAILURE(status))
        errln("Couldn't parse!");
    //} catch (java.text.ParseException e) {
    //    errln("Caught a ParseException:");
    //    e.printStackTrace();
    //}
    
    //logln("The string " + s + " parsed as " + n);

    // {dlf} The old code assumes n is a double, but it isn't any more...
    // Formattable apparently does not and never did interconvert... too bad.
    //if(n.getDouble() != dbl) {
    //    errln("Round trip failure");
    //}
    if (n.getInt64() != dbl) {
        errln("Round trip failure");
    }

    delete f;
}

/**
 * @bug 4162852
 * NumberFormat does not parse negative zero.
 */
void 
NumberFormatRegressionTest::Test4162852(void) 
{
    UErrorCode status = U_ZERO_ERROR;
    for(int32_t i=0; i < 2; ++i) {
        NumberFormat *f = (i == 0) ? NumberFormat::createInstance(status)
            : NumberFormat::createPercentInstance(status);
        if(U_FAILURE(status)) {
            dataerrln("Couldn't create number format - %s", u_errorName(status));
            return;
        }
        double d = 0.0;
        d *= -1.0;
        UnicodeString s;
        f->format(d, s);
        Formattable n;
        f->parse(s, n, status);
        if(U_FAILURE(status))
            errln("Couldn't parse!");
        double e = n.getDouble();
        logln(UnicodeString("") +
              d + " -> " +
              '"' + s + '"' + " -> " + e);
#if (U_PLATFORM == U_PF_OS390 && !defined(IEEE_754)) || U_PLATFORM == U_PF_OS400
        if (e != 0.0) {
#else
        if (e != 0.0 || 1.0/e > 0.0) {
#endif
            logln("Failed to parse negative zero");
        }
        delete f;
    }
}

static double _u_abs(double a) { return a<0?-a:a; }

/**
 * May 17 1999 sync up - liu
 * @bug 4167494
 * NumberFormat truncates data
 */
void NumberFormatRegressionTest::Test4167494(void) {
    UErrorCode status = U_ZERO_ERROR;
    NumberFormat *fmt = NumberFormat::createInstance(Locale::getUS(), status);
    if (failure(status, "NumberFormat::createInstance", TRUE)){
        delete fmt;
        return;
    };

    double a = DBL_MAX * 0.99; // DBL_MAX itself overflows to +Inf
    UnicodeString s;
    fmt->format(a, s);
    Formattable num;
    fmt->parse(s, num, status);
    failure(status, "Parse");
    if (num.getType() == Formattable::kDouble &&
        _u_abs(num.getDouble() - a) / a < 0.01) { // RT within 1%
        logln(UnicodeString("") + a + " -> \"" + s + "\" -> " +
              toString(num) + " ok");
    } else {
        errln(UnicodeString("") + a + " -> \"" + s + "\" -> " +
              toString(num) + " 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.

    delete fmt;
}

/**
 * May 17 1999 sync up - liu
 * @bug 4170798
 * DecimalFormat.parse() fails when ParseIntegerOnly set to true
 */
void NumberFormatRegressionTest::Test4170798(void) {
    UErrorCode status = U_ZERO_ERROR;
    NumberFormat *nf = NumberFormat::createInstance(Locale::getUS(), status);
    if (failure(status, "NumberFormat::createInstance", TRUE)){
        delete nf;
        return;
    };
    DecimalFormat *df = dynamic_cast<DecimalFormat *>(nf);
    if(df == NULL) {
        errln("DecimalFormat needed to continue");
        return;
    }
    df->setParseIntegerOnly(TRUE);
    Formattable n;
    ParsePosition pos(0);
    df->parse("-0.0", n, pos);
    if (n.getType() != Formattable::kLong
        || n.getLong() != 0) {
        errln(UnicodeString("FAIL: parse(\"-0.0\") returns ") + toString(n));
    }
    delete nf;
}

/**
 * May 17 1999 sync up - liu
 * toPattern only puts the first grouping separator in.
 */
void NumberFormatRegressionTest::Test4176114(void) {
    const char* 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
    };
    int DATA_length = (int)(sizeof(DATA) / sizeof(DATA[0]));
    UErrorCode status = U_ZERO_ERROR;
    UnicodeString s;
    for (int i=0; i<DATA_length; i+=2) {
        DecimalFormat df(DATA[i], status);
        if (!failure(status, "DecimalFormat constructor")) {
            df.toPattern(s);
            UnicodeString exp(DATA[i+1]);
            if (s != exp) {
                errln(UnicodeString("FAIL: ") + DATA[i] + " -> " +
                      s + ", want " + exp);
            }
        }
    }
}

/**
 * May 17 1999 sync up - liu
 * @bug 4179818
 * DecimalFormat is incorrectly rounding numbers like 1.2501 to 1.2
 */
void NumberFormatRegressionTest::Test4179818(void) {
    const char* DATA[] = {
        // Input  Pattern  Expected output
        "1.2511", "#.#",   "1.3",
        "1.2501", "#.#",   "1.3",
        "0.9999", "#",     "1",
    };
    int DATA_length = (int)(sizeof(DATA) / sizeof(DATA[0])); 
    double DOUBLE[] = {
        1.2511,
        1.2501,
        0.9999,
    };
    UErrorCode status = U_ZERO_ERROR;
    DecimalFormatSymbols sym(Locale::getUS(), status);
    failure(status, "Construct DecimalFormatSymbols");
    DecimalFormat fmt("#", sym, status);
    if (!failure(status, "Construct DecimalFormat")) {
        for (int i=0; i<DATA_length; i+=3) {
            double in = DOUBLE[i/3];
            UnicodeString pat(DATA[i+1]);
            UnicodeString exp(DATA[i+2]);
            fmt.applyPattern(pat, status);
            failure(status, "applyPattern");
            UnicodeString out;
            FieldPosition pos;
            fmt.format(in, out, pos);
            if (out == exp) {
                logln(UnicodeString("Ok: ") + in + " x " + pat + " = " + out);
            } else {
                errln(UnicodeString("FAIL: ") + in + " x  " + pat + " = " + out +
                      ", expected " + exp);
            }
        }
    }
}

/**
 * May 17 1999 sync up - liu
 * 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.
 */
void NumberFormatRegressionTest::Test4212072(void) {
    UErrorCode status = U_ZERO_ERROR;
    DecimalFormatSymbols sym(Locale::getUS(), status);

    failure(status, "DecimalFormatSymbols ct", Locale::getUS());
    DecimalFormat fmt(UnicodeString("#"), sym, status);
    if(failure(status, "DecimalFormat ct", Locale::getUS())) {
        return;
    }

    UnicodeString s;
    FieldPosition pos;

    sym.setSymbol(DecimalFormatSymbols::kMinusSignSymbol, (UChar)0x5e);
    fmt.setDecimalFormatSymbols(sym);
    s.remove();
    if (fmt.format((int32_t)-1, s, pos) != UNICODE_STRING("^1", 2)) {
        errln(UnicodeString("FAIL: -1 x (minus=^) -> ") + s +
              ", exp ^1");
    }
    s.remove();
    if (fmt.getNegativePrefix(s) != UnicodeString((UChar)0x5e)) {
        errln(UnicodeString("FAIL: (minus=^).getNegativePrefix -> ") +
              s + ", exp ^");
    }
    sym.setSymbol(DecimalFormatSymbols::kMinusSignSymbol, (UChar)0x2d);

    fmt.applyPattern(UnicodeString("#%"), status);
    failure(status, "applyPattern percent");
    sym.setSymbol(DecimalFormatSymbols::kPercentSymbol, (UChar)0x5e);
    fmt.setDecimalFormatSymbols(sym);
    s.remove();
    if (fmt.format(0.25, s, pos) != UNICODE_STRING("25^", 3)) {
        errln(UnicodeString("FAIL: 0.25 x (percent=^) -> ") + s +
              ", exp 25^");
    }
    s.remove();
    if (fmt.getPositiveSuffix(s) != UnicodeString((UChar)0x5e)) {
        errln(UnicodeString("FAIL: (percent=^).getPositiveSuffix -> ") +
              s + ", exp ^");
    }
    sym.setSymbol(DecimalFormatSymbols::kPercentSymbol, (UChar)0x25);

    fmt.applyPattern(str("#\\u2030"), status);
    failure(status, "applyPattern permill");
    sym.setSymbol(DecimalFormatSymbols::kPerMillSymbol, (UChar)0x5e);
    fmt.setDecimalFormatSymbols(sym);
    s.remove();
    if (fmt.format(0.25, s, pos) != UNICODE_STRING("250^", 4)) {
        errln(UnicodeString("FAIL: 0.25 x (permill=^) -> ") + s +
              ", exp 250^");
    }
    s.remove();
    if (fmt.getPositiveSuffix(s) != UnicodeString((UChar)0x5e)) {
        errln(UnicodeString("FAIL: (permill=^).getPositiveSuffix -> ") +
              s + ", exp ^");
    }
    sym.setSymbol(DecimalFormatSymbols::kPerMillSymbol, (UChar)0x2030);

    fmt.applyPattern(str("\\u00A4#.00"), status);
    failure(status, "applyPattern currency");
    sym.setSymbol(DecimalFormatSymbols::kCurrencySymbol, "usd");
    fmt.setDecimalFormatSymbols(sym);
    s.remove();
    if (fmt.format(12.5, s, pos) != UnicodeString("usd12.50")) {
        errln(UnicodeString("FAIL: 12.5 x (currency=usd) -> ") + s +
              ", exp usd12.50");
    }
    s.remove();
    if (fmt.getPositivePrefix(s) != UnicodeString("usd")) {
        errln(UnicodeString("FAIL: (currency=usd).getPositivePrefix -> ") +
              s + ", exp usd");
    }
    sym.setSymbol(DecimalFormatSymbols::kCurrencySymbol, "$");

    fmt.applyPattern(str("\\u00A4\\u00A4#.00"), status);
    failure(status, "applyPattern intl currency");
    sym.setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol, "DOL");
    fmt.setDecimalFormatSymbols(sym);
    s.remove();
    if (fmt.format(12.5, s, pos) != UnicodeString("DOL12.50")) {
        errln(UnicodeString("FAIL: 12.5 x (intlcurrency=DOL) -> ") + s +
              ", exp DOL12.50");
    }
    s.remove();
    if (fmt.getPositivePrefix(s) != UnicodeString("DOL")) {
        errln(UnicodeString("FAIL: (intlcurrency=DOL).getPositivePrefix -> ") +
              s + ", exp DOL");
    }
    sym.setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol, "USD");

    // Since the pattern logic has changed, make sure that patterns round
    // trip properly.  Test stream in/out integrity too.
    int32_t n;
    const Locale* avail = NumberFormat::getAvailableLocales(n);
    static const char* type[] = {
        "",
        "$ ",
        "% ",
    };
    for (int i=0; i<n; ++i) {
        for (int j=0; j<3; ++j) {
            status = U_ZERO_ERROR;
            NumberFormat *nf;
            switch (j) {
            case 0:
                nf = NumberFormat::createInstance(avail[i], status);
                failure(status, "createInstance", avail[i]);
                break;
            case 1:
                nf = NumberFormat::createCurrencyInstance(avail[i], status);
                failure(status, "createCurrencyInstance", avail[i]);
                break;
            default:
                nf = NumberFormat::createPercentInstance(avail[i], status);
                failure(status, "createPercentInstance", avail[i]);
                break;
            }
            if (U_FAILURE(status)) {
                continue;
            }
            DecimalFormat *df = (DecimalFormat*) nf;

            // Test toPattern/applyPattern round trip
            UnicodeString pat;
            df->toPattern(pat);
            DecimalFormatSymbols symb(avail[i], status);
            failure(status, "Construct DecimalFormatSymbols", avail[i]);
            DecimalFormat f2(pat, symb, status);
            if (failure(status,
                        UnicodeString("Construct DecimalFormat(") + pat + ")")) {
                continue;
            }
            if (*df != f2) {
                UnicodeString l, p;
                errln(UnicodeString("FAIL: ") + type[j] + avail[i].getDisplayName(l) +
                      " -> \"" + pat +
                      "\" -> \"" + f2.toPattern(p) + "\"");
            } else {
                UnicodeString l, p;
                logln(UnicodeString("PASS: ") + type[j] + avail[i].getDisplayName(l) +
                      " -> \"" + pat +
                      "\"");
            }

            // Test toLocalizedPattern/applyLocalizedPattern round trip
            df->toLocalizedPattern(pat);
            f2.applyLocalizedPattern(pat, status);
            failure(status,
                    UnicodeString("applyLocalizedPattern(") + pat + ")", avail[i]);
            if (U_FAILURE(status)) {
                continue;
            }
            
            // Make sure we set the currency attributes appropriately
            if (j == 1) {   // Currency format
                f2.setCurrency(f2.getCurrency(), status);
            }
            failure(status,
                    UnicodeString("setCurrency() for (") + pat + ")", avail[i]);
            if (U_FAILURE(status)) {
                continue;
            }

            if (*df != f2) {
                UnicodeString l, p;
                errln(UnicodeString("FAIL: ") + type[j] + avail[i].getDisplayName(l) +
                      " -> localized \"" + pat +
                      "\" -> \"" + f2.toPattern(p) + "\"");
            }

            delete nf;
 
            // Test writeObject/readObject round trip
            // NOT ON ICU -- Java only
        }
    }
}

/**
 * May 17 1999 sync up - liu
 * DecimalFormat.parse() fails for mulipliers 2^n.
 */
void NumberFormatRegressionTest::Test4216742(void) {
    UErrorCode status = U_ZERO_ERROR;
    DecimalFormat *fmt = (DecimalFormat*) NumberFormat::createInstance(Locale::getUS(), status);
    if (failure(status, "createInstance", Locale::getUS(), TRUE)){
        delete fmt;
        return;
    };
    int32_t DATA[] = { INT32_MIN, INT32_MAX, -100000000, 100000000 };
    int DATA_length = (int)(sizeof(DATA) / sizeof(DATA[0]));
    for (int i=0; i<DATA_length; ++i) {
        UnicodeString str((UnicodeString)"" + DATA[i]);
        for (int m = 1; m <= 100; m++) {
            fmt->setMultiplier(m);
            Formattable num;
            fmt->parse(str, num, status);
            failure(status, "parse", Locale::getUS());
            if (num.getType() != Formattable::kLong &&
                num.getType() != Formattable::kDouble) {
                errln(UnicodeString("FAIL: Wanted number, got ") +
                      toString(num));
            } else {
                double d = num.getType() == Formattable::kDouble ?
                    num.getDouble() : (double) num.getLong();
                if ((d > 0) != (DATA[i] > 0)) {
                    errln(UnicodeString("\"") + str + "\" parse(x " +
                          fmt->getMultiplier() +
                          ") => " + toString(num));
                }
            }
        }
    }
    delete fmt;
}

/**
 * May 17 1999 sync up - liu
 * DecimalFormat formats 1.001 to "1.00" instead of "1" with 2 fraction
 * digits.
 */
void NumberFormatRegressionTest::Test4217661(void) {
    const double D[] = {  0.001, 1.001, 0.006,  1.006 };
    const char*  S[] = { "0",   "1",   "0.01", "1.01" };
    int D_length = (int)(sizeof(D) / sizeof(D[0]));
    UErrorCode status = U_ZERO_ERROR;
    NumberFormat *fmt = NumberFormat::createInstance(Locale::getUS(), status);
    if (failure(status, "createInstance", Locale::getUS(), TRUE)){
        delete fmt;
        return;
    };
    fmt->setMaximumFractionDigits(2);
    for (int i=0; i<D_length; i++) {
        UnicodeString s;
        fmt->format(D[i], s);
        if (s != UnicodeString(S[i])) {
            errln(UnicodeString("FAIL: Got ") + s + ", exp " + S[i]); 
        }
    }
    delete fmt;
}

/**
 * alphaWorks upgrade
 */
void NumberFormatRegressionTest::Test4161100(void) {
    UErrorCode status = U_ZERO_ERROR;
    NumberFormat *nf = NumberFormat::createInstance(Locale::getUS(), status);
    if (failure(status, "createInstance", Locale::getUS(), TRUE)){
        delete nf;
        return;
    };
    nf->setMinimumFractionDigits(1);
    nf->setMaximumFractionDigits(1);
    double a = -0.09;
    UnicodeString s;
    nf->format(a, s);
    UnicodeString pat;
    logln(UnicodeString() + a + " x " +
          ((DecimalFormat*) nf)->toPattern(pat) + " = " + s);
    if (s != UnicodeString("-0.1")) {
        errln("FAIL");
    }
    delete nf;
}

/**
 * June 16 1999 sync up - liu
 * Formatting .5 rounds to "1" instead of "0". (Regression in 1.2.2 RC1)
 */
void NumberFormatRegressionTest::Test4243011(void) {
    UErrorCode status = U_ZERO_ERROR;
    DecimalFormatSymbols sym(Locale::getUS(), status);
    failure(status, "DecimalFormatSymbols ct", Locale::getUS());
    DecimalFormat fmt(UnicodeString("0."), sym, status);
    
    if (!failure(status, "DecimalFormat ct", Locale::getUS())) {
        const double NUM[] = {  -2.5,  -1.5,  -0.5,  0.5,  1.5,  2.5,  3.5,  4.5 };
        const char*  STR[] = { "-2.", "-2.", "-0.", "0.", "2.", "2.", "4.", "4." };
        int32_t N = (int32_t)(sizeof(NUM) / sizeof(NUM[0]));

        for (int32_t i=0; i<N; ++i) {
            UnicodeString str;
            UnicodeString exp(STR[i]);
            FieldPosition pos;
            fmt.format(NUM[i], str, pos);
            if (str == exp) {
                logln(UnicodeString("Ok   ") + NUM[i] + " x 0. = " + str);
            } else {
                errln(UnicodeString("FAIL ") + NUM[i] + " x 0. = " + str +
                      ", want " + exp);
            }
        }
    }
}

/**
 * June 16 1999 sync up - liu
 * format(0.0) gives "0.1" if preceded by parse("99.99").
 * (Regression in 1.2.2 RC1)
 */
void NumberFormatRegressionTest::Test4243108(void) {
    UErrorCode status = U_ZERO_ERROR;
    DecimalFormatSymbols sym(Locale::getUS(), status);
    failure(status, "DecimalFormatSymbols ct", Locale::getUS());
    DecimalFormat fmt(UnicodeString("#.#"), sym, status);
    if (failure(status, "DecimalFormat ct", Locale::getUS())) {
        return;
    }

    UnicodeString str;
    FieldPosition pos;

    fmt.format(0.0, str, pos);
    UnicodeString exp("0");
    if (str == exp) {
        logln(UnicodeString("Ok   0.0 x #.# = ") + str);
    } else {
        errln(UnicodeString("FAIL 0.0 x #.# = ") + str +
              ", want " + exp);
    }

    str = "99.99";
    Formattable val;
    fmt.parse(str, val, status);
    failure(status, "DecimalFormat.parse(99.99)", Locale::getUS());
    if (val.getType() == Formattable::kDouble &&
        val.getDouble() == 99.99) {
        logln(UnicodeString("Ok   99.99 / #.# = ") + toString(val));
    } else {
        errln(UnicodeString("FAIL 99.99 / #.# = ") + toString(val) +
              ", want " + 99.99);
    }

    str.remove();
    fmt.format(0.0, str, pos);
    if (str == exp) {
        logln(UnicodeString("Ok   0.0 x #.# = ") + str);
    } else {
        errln(UnicodeString("FAIL 0.0 x #.# = ") + str +
              ", want " + exp);
    }
}


/**
 * DateFormat should call setIntegerParseOnly(TRUE) on adopted
 * NumberFormat objects.
 */
void NumberFormatRegressionTest::TestJ691(void) {
    UErrorCode status = U_ZERO_ERROR;
    Locale loc("fr", "CH");

    // set up the input date string & expected output
    UnicodeString udt("11.10.2000", "");
    UnicodeString exp("11.10.00", "");

    // create a Calendar for this locale
    Calendar *cal = Calendar::createInstance(loc, status);
    if (U_FAILURE(status)) {
        dataerrln("FAIL: Calendar::createInstance() returned " + (UnicodeString)u_errorName(status));
        return;
    }

    // create a NumberFormat for this locale
    NumberFormat *nf = NumberFormat::createInstance(loc, status);
    if (U_FAILURE(status)) {
        dataerrln("FAIL: NumberFormat::createInstance() returned " + (UnicodeString)u_errorName(status));
        return;
    }

    // *** Here's the key: We don't want to have to do THIS:
    // nf->setParseIntegerOnly(TRUE);

    // create the DateFormat
    DateFormat *df = DateFormat::createDateInstance(DateFormat::kShort, loc);
    if (U_FAILURE(status)) {
        errln("FAIL: DateFormat::createInstance() returned " + (UnicodeString)u_errorName(status));
        return;
    }

    df->adoptCalendar(cal);
    df->adoptNumberFormat(nf);

    // set parsing to lenient & parse
    df->setLenient(TRUE);
    UDate ulocdat = df->parse(udt, status);

    // format back to a string
    UnicodeString outString;
    df->format(ulocdat, outString);

    if (outString != exp) {
        errln("FAIL: " + udt + " => " + outString);
    }

    delete df;
}

//---------------------------------------------------------------------------
//
//   Error Checking / Reporting macros
//
//---------------------------------------------------------------------------
#define TEST_CHECK_STATUS(status) { \
    if (U_FAILURE(status)) { \
        if (status == U_MISSING_RESOURCE_ERROR) { \
            dataerrln("File %s, Line %d: status=%s", __FILE__, __LINE__, u_errorName(status)); \
        } else { \
            errln("File %s, Line %d: status=%s", __FILE__, __LINE__, u_errorName(status)); \
        } return; \
    }}

#define TEST_ASSERT(expr) \
    if ((expr)==FALSE) {\
        errln("File %s, line %d: Assertion Failed: " #expr "\n", __FILE__, __LINE__);\
    }


// Ticket 8199:  Parse failure for numbers in the range of 1E10 - 1E18

void NumberFormatRegressionTest::Test8199(void) {
    UErrorCode status = U_ZERO_ERROR;
    NumberFormat *nf = NumberFormat::createInstance(Locale::getEnglish(), status);
    if (nf == NULL) {
        dataerrln("Fail: NumberFormat::createInstance(Locale::getEnglish(), status)");
        return;
    }
    TEST_CHECK_STATUS(status);

    // Note:  Retrieving parsed values from a Formattable as a reduced-precision type
    //        should always truncate, no other rounding scheme.

    UnicodeString numStr = "1000000000.6";   // 9 zeroes
    Formattable val;
    nf->parse(numStr, val, status);
    TEST_CHECK_STATUS(status);
    TEST_ASSERT(Formattable::kDouble == val.getType());
    TEST_ASSERT(1000000000 == val.getInt64(status));
    TEST_CHECK_STATUS(status);
    TEST_ASSERT(1000000000.6 == val.getDouble(status));
    TEST_CHECK_STATUS(status);

    numStr = "100000000000000001.1";   // approx 1E17, parses as a double rather
                                       //   than int64 because of the fraction
                                       //   even though int64 is more precise.
    nf->parse(numStr, val, status);
    TEST_CHECK_STATUS(status);
    TEST_ASSERT(Formattable::kDouble == val.getType());
    TEST_ASSERT(100000000000000001LL == val.getInt64(status));
    TEST_CHECK_STATUS(status);
    TEST_ASSERT(100000000000000000.0 == val.getDouble(status));
    TEST_CHECK_STATUS(status);

    numStr = "1E17";  // Parses with the internal decimal number having non-zero exponent
    nf->parse(numStr, val, status);
    TEST_CHECK_STATUS(status);
    TEST_ASSERT(Formattable::kInt64 == val.getType());
    TEST_ASSERT(100000000000000000LL == val.getInt64());
    TEST_ASSERT(1.0E17 == val.getDouble(status));
    TEST_CHECK_STATUS(status);

    numStr = "9223372036854775807";  // largest int64_t
    nf->parse(numStr, val, status);
    TEST_CHECK_STATUS(status);
    TEST_ASSERT(Formattable::kInt64 == val.getType());
    TEST_ASSERT(9223372036854775807LL == val.getInt64());
    // In the following check, note that a substantial range of integers will
    //    convert to the same double value.  There are also platform variations
    //    in the rounding at compile time of double constants.
    TEST_ASSERT(9223372036854775808.0 >= val.getDouble(status));
    TEST_ASSERT(9223372036854774700.0 <= val.getDouble(status));
    TEST_CHECK_STATUS(status);

    numStr = "-9223372036854775808";  // smallest int64_t
    nf->parse(numStr, val, status);
    TEST_CHECK_STATUS(status);
    TEST_ASSERT(Formattable::kInt64 == val.getType());
    // TEST_ASSERT(-9223372036854775808LL == val.getInt64()); // Compiler chokes on constant.
    TEST_ASSERT((int64_t)0x8000000000000000LL == val.getInt64());
    TEST_ASSERT(-9223372036854775808.0 == val.getDouble(status));
    TEST_CHECK_STATUS(status);

    numStr = "9223372036854775808";  // largest int64_t + 1
    nf->parse(numStr, val, status);
    TEST_CHECK_STATUS(status);
    TEST_ASSERT(Formattable::kDouble == val.getType());
    TEST_ASSERT(9223372036854775807LL == val.getInt64(status));
    TEST_ASSERT(status == U_INVALID_FORMAT_ERROR);
    status = U_ZERO_ERROR;
    TEST_ASSERT(9223372036854775810.0 == val.getDouble(status));
    TEST_CHECK_STATUS(status);

    numStr = "-9223372036854775809";  // smallest int64_t - 1
    nf->parse(numStr, val, status);
    TEST_CHECK_STATUS(status);
    TEST_ASSERT(Formattable::kDouble == val.getType());
    // TEST_ASSERT(-9223372036854775808LL == val.getInt64(status));  // spurious compiler warnings
    TEST_ASSERT((int64_t)0x8000000000000000LL == val.getInt64(status));
    TEST_ASSERT(status == U_INVALID_FORMAT_ERROR);
    status = U_ZERO_ERROR;
    TEST_ASSERT(-9223372036854775810.0 == val.getDouble(status));
    TEST_CHECK_STATUS(status);

    // Test values near the limit of where doubles can represent all integers.
    // The implementation strategy of getInt64() changes at this boundary.
    // Strings to be parsed include a decimal fraction to force them to be
    //   parsed as doubles rather than ints.  The fraction is discarded
    //   from the parsed double value because it is beyond what can be represented.

    status = U_ZERO_ERROR;
    numStr = "9007199254740991.1";  // largest 53 bit int
    nf->parse(numStr, val, status);
    TEST_CHECK_STATUS(status);
    // printf("getInt64() returns %lld\n", val.getInt64(status));
    TEST_ASSERT(Formattable::kDouble == val.getType());
    TEST_ASSERT(9007199254740991LL == val.getInt64(status));
    TEST_ASSERT(9007199254740991.0 == val.getDouble(status));
    TEST_CHECK_STATUS(status);

    status = U_ZERO_ERROR;
    numStr = "9007199254740992.1";  // 54 bits for the int part.
    nf->parse(numStr, val, status);
    TEST_CHECK_STATUS(status);
    TEST_ASSERT(Formattable::kDouble == val.getType());
    TEST_ASSERT(9007199254740992LL == val.getInt64(status));
    TEST_ASSERT(9007199254740992.0 == val.getDouble(status));
    TEST_CHECK_STATUS(status);

    status = U_ZERO_ERROR;
    numStr = "9007199254740993.1";  // 54 bits for the int part.  Double will round
    nf->parse(numStr, val, status); //    the ones digit, putting it up to ...994
    TEST_CHECK_STATUS(status);
    TEST_ASSERT(Formattable::kDouble == val.getType());
    TEST_ASSERT(9007199254740993LL == val.getInt64(status));
    TEST_ASSERT(9007199254740994.0 == val.getDouble(status));
    TEST_CHECK_STATUS(status);

    delete nf;
}

void NumberFormatRegressionTest::Test9109(void) {
    UErrorCode status = U_ZERO_ERROR;
    Formattable val;
    ParsePosition pos;
    DecimalFormat fmt("+##", status);
    fmt.setLenient(TRUE);

    if (U_FAILURE(status)) {
        dataerrln("Failed to create DecimalFormat with pattern '+##' - %s", u_errorName(status));
    }

    UnicodeString text("123");
    int32_t expected = 123;
    int32_t expos = 3;

    fmt.parse(text, val, pos);
    if (pos.getErrorIndex() >= 0) {
        errln(UnicodeString("Parse failure at ") + pos.getErrorIndex());
    } else if (val.getLong() != 123) {
        errln(UnicodeString("Incorrect parse result: ") + val.getLong() + " expected: " + expected);
    } else if (pos.getIndex() != 3) {
        errln(UnicodeString("Incorrect parse position: ") + pos.getIndex() + " expected: " + expos);
    }
}


void NumberFormatRegressionTest::Test9780(void) {
    UErrorCode status = U_ZERO_ERROR;
    NumberFormat *nf = NumberFormat::createInstance(Locale::getUS(), status);
    if (failure(status, "NumberFormat::createInstance", TRUE)){
        delete nf;
        return;
    };
    DecimalFormat *df = dynamic_cast<DecimalFormat *>(nf);
    if(df == NULL) {
        errln("DecimalFormat needed to continue");
        return;
    }
    df->setParseIntegerOnly(TRUE);

    {
      Formattable n;
      ParsePosition pos(0);
      UnicodeString toParse("1,234","");
      df->parse(toParse, n, pos);
      if (n.getType() != Formattable::kLong
          || n.getLong() != 1234) {
        errln(UnicodeString("FAIL: parse(\"") + toParse + UnicodeString("\") returns ") + toString(n));
      }
    }
    // should still work in lenient mode, just won't get fastpath
    df->setLenient(TRUE);
    {
      Formattable n;
      ParsePosition pos(0);
      UnicodeString toParse("1,234","");
      df->parse(toParse, n, pos);
      if (n.getType() != Formattable::kLong
          || n.getLong() != 1234) {
        errln(UnicodeString("FAIL: parse(\"") + toParse + UnicodeString("\") returns ") + toString(n));
      }
    }
    delete nf;
}


void NumberFormatRegressionTest::Test9677(void) {
  static const UChar pattern[] = { 0x23,0x23,0x23,0x23,0x2E,0x23,0x23,0x23,0x23,0 }; // "####.####"
  static const UChar positivePrefix[] = { 0x40,0 }; // "@"
  static const UChar negativePrefix[] = { 0x6E,0 }; // "n"
  static const UChar text[] = { 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0 }; // 123456789
  static const UChar text2[] = { 0x6E, 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0 }; // n123456789
  
  UErrorCode status = U_ZERO_ERROR;
  LocalUNumberFormatPointer f(unum_open(UNUM_DEFAULT, NULL, 0, "en_US", NULL, &status));
  if (U_FAILURE(status)) {
      dataerrln("Failure opening unum_open");
      return;
  }

  if (U_SUCCESS(status)) {
    unum_applyPattern(f.getAlias(), FALSE, pattern, -1, NULL, &status);
    unum_setTextAttribute(f.getAlias(), UNUM_POSITIVE_PREFIX, positivePrefix, -1, &status);
    assertSuccess("setting attributes", status);
  }

  if(U_SUCCESS(status)) {
    int32_t n = unum_parse(f.getAlias(), text, -1, NULL, &status);
    logln("unum_parse status %s, result %d\n", u_errorName(status), n);

    if(U_FAILURE(status)) {
        logln("Got expected parse error %s\n", u_errorName(status));
        status = U_ZERO_ERROR;
    } else {
        errln("FAIL: unum_parse status %s, result %d - expected failure\n", u_errorName(status), n);
    }
  }

  if (U_SUCCESS(status)) {
    unum_setTextAttribute(f.getAlias(), UNUM_POSITIVE_PREFIX, NULL, 0, &status);
    assertSuccess("setting attributes", status);
    logln("removed positive prefix");
  }

  if(U_SUCCESS(status)) {
    int32_t n = unum_parse(f.getAlias(), text, -1, NULL, &status);
    logln("unum_parse status %s, result %d\n", u_errorName(status), n);

    if(U_FAILURE(status)) {
        errln("FAIL: with pos prefix removed, parse error %s\n", u_errorName(status));
        status = U_ZERO_ERROR;
    } else {
        if(n!=123456789) {
          errln("FAIL: with pos prefix removed , unum_parse status %s, result %d expected 123456789\n", u_errorName(status), n);
        } else {
          logln("PASS: with pos prefix removed , unum_parse status %s, result %d expected 123456789\n", u_errorName(status),n);
        }
    }
  }

  if(U_SUCCESS(status)) {
    int32_t n = unum_parse(f.getAlias(), text2, -1, NULL, &status);
    logln("unum_parse status %s, result %d\n", u_errorName(status), n);

    if(U_FAILURE(status)) {
        logln("text2: Got expected parse error %s\n", u_errorName(status));
        status = U_ZERO_ERROR;
    } else {
        errln("FAIL: text2: unum_parse status %s, result %d - expected failure\n", u_errorName(status), n);
    }
  }

  if (U_SUCCESS(status)) {
    unum_setTextAttribute(f.getAlias(), UNUM_NEGATIVE_PREFIX, negativePrefix, -1, &status);
    assertSuccess("setting attributes", status);
    logln("Set a different neg prefix prefix");
  }

  if(U_SUCCESS(status)) {
    int32_t n = unum_parse(f.getAlias(), text2, -1, NULL, &status);
    logln("unum_parse status %s, result %d\n", u_errorName(status), n);

    if(U_FAILURE(status)) {
        errln("FAIL: with different neg prefix , parse error %s\n", u_errorName(status));
        status = U_ZERO_ERROR;
    } else {
;
        if(n!=-123456789) {
          errln("FAIL: with different neg prefix , unum_parse status %s, result %d expected -123456789\n", u_errorName(status), n);
        } else {
          logln("PASS: with different neg prefix , unum_parse status %s, result %d expected -123456789\n", u_errorName(status), n);
        }
    }
  }
}

void NumberFormatRegressionTest::Test10361(void) {
    // DecimalFormat/NumberFormat were artificially limiting the number of digits,
    //    preventing formatting of big decimals.
    UErrorCode status = U_ZERO_ERROR;
    DecimalFormatSymbols symbols(Locale::getEnglish(), status);
    LocalPointer<DecimalFormat> df(new DecimalFormat("###.##", symbols, status));
    TEST_CHECK_STATUS(status);

    // Create a decimal number with a million digits.
    const int32_t NUMSIZE=1000000;
    char *num = new char[NUMSIZE];
    for (int32_t i=0; i<NUMSIZE; i++) {
        num[i] = '0' + (i+1) % 10;
    }
    num[NUMSIZE-3] = '.';
    num[NUMSIZE-1] = 0;

    UnicodeString    s;
    Formattable      fmtable;
    fmtable.setDecimalNumber(num, status);
    TEST_CHECK_STATUS(status);

    FieldPosition pos(UNUM_DECIMAL_SEPARATOR_FIELD);
    df->format(fmtable, s, pos, status);
    TEST_CHECK_STATUS(status);
    TEST_ASSERT(999999 == s.length());
    TEST_ASSERT(999997 == pos.getBeginIndex());
    TEST_ASSERT(999998 == pos.getEndIndex());

    UnicodeString expected(num, -1, US_INV);
    TEST_ASSERT(expected == s);
    delete [] num;
}

#endif /* #if !UCONFIG_NO_FORMATTING */
