Home | History | Annotate | Download | only in intltest
      1 /***********************************************************************
      2  * Copyright (c) 1997-2012, International Business Machines Corporation
      3  * and others. All Rights Reserved.
      4  ***********************************************************************/
      5 
      6 #include "unicode/utypes.h"
      7 
      8 #if !UCONFIG_NO_FORMATTING
      9 
     10 #include "numrgts.h"
     11 
     12 #include <float.h> // DBL_MIN, DBL_MAX
     13 #include <stdio.h>
     14 
     15 #include "unicode/dcfmtsym.h"
     16 #include "unicode/decimfmt.h"
     17 #include "unicode/locid.h"
     18 #include "unicode/resbund.h"
     19 #include "unicode/calendar.h"
     20 #include "unicode/datefmt.h"
     21 #include "unicode/ucurr.h"
     22 #include "putilimp.h"
     23 
     24 class MyNumberFormatTest : public NumberFormat
     25 {
     26 public:
     27 
     28     virtual UClassID getDynamicClassID(void) const;
     29 
     30     virtual UnicodeString& format(    double            number,
     31                     UnicodeString&        toAppendTo,
     32                     FieldPositionIterator* posIter,
     33                     UErrorCode& status) const
     34     {
     35         return NumberFormat::format(number, toAppendTo, posIter, status);
     36     }
     37 
     38     /* Just keep this here to make some of the compilers happy */
     39     virtual UnicodeString& format(const Formattable& obj,
     40                                   UnicodeString& toAppendTo,
     41                                   FieldPosition& pos,
     42                                   UErrorCode& status) const
     43     {
     44         return NumberFormat::format(obj, toAppendTo, pos, status);
     45     }
     46 
     47     /* Just use one of the format functions */
     48     virtual UnicodeString& format(    double            /* number */,
     49                     UnicodeString&        toAppendTo,
     50                     FieldPosition&        /* pos */) const
     51     {
     52         toAppendTo = "";
     53         return toAppendTo;
     54     }
     55 
     56     /*
     57     public Number parse(String text, ParsePosition parsePosition)
     58     { return new Integer(0); }
     59     */
     60 
     61     /* Just use one of the parse functions */
     62     virtual void parse(    const UnicodeString&    /* text */,
     63             Formattable&            result,
     64             ParsePosition&          /* parsePosition */) const
     65     {
     66         result.setLong((int32_t)0);
     67     }
     68 
     69     virtual void parse(    const UnicodeString&    text,
     70             Formattable&            result,
     71             UErrorCode&            status) const
     72     {
     73         NumberFormat::parse(text, result, status);
     74     }
     75     virtual Format* clone() const
     76     { return NULL; }
     77 
     78     virtual UnicodeString& format(int32_t,
     79                 UnicodeString& foo,
     80                 FieldPosition&) const
     81     { return foo.remove(); }
     82 
     83     virtual UnicodeString& format(int64_t,
     84                 UnicodeString& foo,
     85                 FieldPosition&) const
     86     { return foo.remove(); }
     87 
     88     virtual void applyPattern(const UnicodeString&, UParseError&, UErrorCode&){
     89     }
     90 };
     91 
     92 int32_t gMyNumberFormatTestClassID;
     93 UClassID MyNumberFormatTest::getDynamicClassID()  const
     94 {
     95     return (UClassID)&gMyNumberFormatTestClassID;
     96 }
     97 
     98 
     99 // *****************************************************************************
    100 // class NumberFormatRegressionTest
    101 // *****************************************************************************
    102 
    103 #define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break
    104 
    105 void
    106 NumberFormatRegressionTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
    107 {
    108     // if (exec) logln((UnicodeString)"TestSuite NumberFormatRegressionTest");
    109     switch (index) {
    110         CASE(0,Test4075713);
    111         CASE(1,Test4074620);
    112         CASE(2,Test4088161);
    113         CASE(3,Test4087245);
    114         CASE(4,Test4087535);
    115         CASE(5,Test4088503);
    116         CASE(6,Test4066646);
    117         CASE(7,Test4059870);
    118         CASE(8,Test4083018);
    119         CASE(9,Test4071492);
    120         CASE(10,Test4086575);
    121         CASE(11,Test4068693);
    122         CASE(12,Test4069754);
    123         CASE(13,Test4087251);
    124         CASE(14,Test4090489);
    125         CASE(15,Test4090504);
    126         CASE(16,Test4095713);
    127         CASE(17,Test4092561);
    128         CASE(18,Test4092480);
    129         CASE(19,Test4087244);
    130         CASE(20,Test4070798);
    131         CASE(21,Test4071005);
    132         CASE(22,Test4071014);
    133         CASE(23,Test4071859);
    134         CASE(24,Test4093610);
    135         CASE(25,Test4098741);
    136         CASE(26,Test4074454);
    137         CASE(27,Test4099404);
    138         CASE(28,Test4101481);
    139         CASE(29,Test4052223);
    140         CASE(30,Test4061302);
    141         CASE(31,Test4062486);
    142         CASE(32,Test4108738);
    143         CASE(33,Test4106658);
    144         CASE(34,Test4106662);
    145         CASE(35,Test4114639);
    146         CASE(36,Test4106664);
    147         CASE(37,Test4106667);
    148         CASE(38,Test4110936);
    149         CASE(39,Test4122840);
    150         CASE(40,Test4125885);
    151         CASE(41,Test4134034);
    152         CASE(42,Test4134300);
    153         CASE(43,Test4140009);
    154         CASE(44,Test4141750);
    155         CASE(45,Test4145457);
    156         CASE(46,Test4147295);
    157         CASE(47,Test4147706);
    158         CASE(48,Test4162198);
    159         CASE(49,Test4162852);
    160         CASE(50,Test4167494);
    161         CASE(51,Test4170798);
    162         CASE(52,Test4176114);
    163         CASE(53,Test4179818);
    164         CASE(54,Test4212072);
    165         CASE(55,Test4216742);
    166         CASE(56,Test4217661);
    167         CASE(57,Test4161100);
    168         CASE(58,Test4243011);
    169         CASE(59,Test4243108);
    170         CASE(60,TestJ691);
    171         CASE(61,Test8199);
    172         CASE(62,Test9109);
    173         CASE(63,Test9780);
    174         CASE(64,Test9677);
    175 
    176         default: name = ""; break;
    177     }
    178 }
    179 
    180 UBool
    181 NumberFormatRegressionTest::failure(UErrorCode status, const UnicodeString& msg, const Locale& l, UBool possibleDataError)
    182 {
    183     if(U_FAILURE(status)) {
    184         if (possibleDataError) {
    185             dataerrln(UnicodeString("FAIL: ", "") + msg
    186                   + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status), "") + UnicodeString(l.getName(),""));
    187         } else {
    188             errcheckln(status, UnicodeString("FAIL: ", "") + msg
    189                   + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status), "") + UnicodeString(l.getName(),""));
    190         }
    191         return TRUE;
    192     }
    193 
    194     return FALSE;
    195 }
    196 
    197 UBool
    198 NumberFormatRegressionTest::failure(UErrorCode status, const UnicodeString& msg, const char *l, UBool possibleDataError)
    199 {
    200     if(U_FAILURE(status)) {
    201         if (possibleDataError) {
    202             dataerrln(UnicodeString("FAIL: ", "") + msg
    203                   + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status), "") + UnicodeString(l, ""));
    204         } else {
    205             errcheckln(status, UnicodeString("FAIL: ", "") + msg
    206                   + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status), "") + UnicodeString(l, ""));
    207         }
    208         return TRUE;
    209     }
    210 
    211     return FALSE;
    212 }
    213 
    214 UBool
    215 NumberFormatRegressionTest::failure(UErrorCode status, const UnicodeString& msg, UBool possibleDataError)
    216 {
    217     if(U_FAILURE(status)) {
    218         if (possibleDataError) {
    219             dataerrln(UnicodeString("FAIL: ", "") + msg
    220                   + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status), ""));
    221         } else {
    222             errcheckln(status, UnicodeString("FAIL: ", "") + msg
    223                   + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status), ""));
    224         }
    225         return TRUE;
    226     }
    227 
    228     return FALSE;
    229 }
    230 
    231 /**
    232  * Convert Java-style strings with \u Unicode escapes into UnicodeString objects
    233  */
    234 inline UnicodeString str(const char *input)
    235 {
    236   return CharsToUnicodeString(input);
    237 }
    238 
    239 /* @bug 4075713
    240  * NumberFormat.equals comparing with null should always return false.
    241  */
    242 // {sfb} kind of silly in C++, just checking for new success
    243 void NumberFormatRegressionTest::Test4075713(void)
    244 {
    245     //try {
    246         MyNumberFormatTest *tmp = new MyNumberFormatTest();
    247         if(tmp != NULL)
    248             logln("NumberFormat.equals passed");
    249     /*} catch (NullPointerException e) {
    250         errln("(new MyNumberFormatTest()).equals(null) throws unexpected exception");
    251     }*/
    252 
    253     delete tmp;
    254 }
    255 
    256 /* @bug 4074620
    257  * NumberFormat.equals comparing two obj equal even the setGroupingUsed
    258  * flag is different.
    259  */
    260 void NumberFormatRegressionTest::Test4074620(void)
    261 {
    262 
    263     MyNumberFormatTest *nf1 = new MyNumberFormatTest();
    264     MyNumberFormatTest *nf2 = new MyNumberFormatTest();
    265 
    266     nf1->setGroupingUsed(FALSE);
    267     nf2->setGroupingUsed(TRUE);
    268 
    269     if(nf1 == nf2)
    270         errln("Test for bug 4074620 failed");
    271     else
    272         logln("Test for bug 4074620 passed.");
    273 
    274     delete nf1;
    275     delete nf2;
    276 }
    277 
    278 
    279 /* @bug 4088161
    280  * DecimalFormat.format() incorrectly uses maxFractionDigits setting.
    281  */
    282 
    283 void NumberFormatRegressionTest::Test4088161 (void)
    284 {
    285     UErrorCode status = U_ZERO_ERROR;
    286     DecimalFormat *df = new DecimalFormat(status);
    287     if (!failure(status, "new DecimalFormat", "")) {
    288         double d = 100;
    289         df->setMinimumFractionDigits(0);
    290         df->setMaximumFractionDigits(16);
    291         UnicodeString sBuf1;
    292         FieldPosition fp1(0);
    293         logln(UnicodeString("d = ") + d);
    294         logln(UnicodeString("maxFractionDigits = ") + df->getMaximumFractionDigits());
    295 
    296         logln(" format(d) = '" + df->format(d, sBuf1, fp1) + "'");
    297         df->setMaximumFractionDigits(17);
    298         UnicodeString sBuf2;
    299         FieldPosition fp2(0);
    300         logln(UnicodeString("maxFractionDigits = ") + df->getMaximumFractionDigits());
    301         sBuf2 = df->format(d, sBuf2, fp2);
    302         if(sBuf2 != "100")
    303             errln(" format(d) = '" + sBuf2 + "'");
    304     }
    305 
    306     delete df;
    307 }
    308 
    309 /* @bug 4087245
    310  * DecimalFormatSymbols should be cloned in the ctor DecimalFormat.
    311  * DecimalFormat(String, DecimalFormatSymbols).
    312  */
    313 void NumberFormatRegressionTest::Test4087245 (void)
    314 {
    315     UErrorCode status = U_ZERO_ERROR;
    316     DecimalFormatSymbols *symbols = new DecimalFormatSymbols(status);
    317     failure(status, "new DecimalFormatSymbols", "");
    318     // {sfb} One note about this test: if you pass in a pointer
    319     // to the symbols, they are adopted and this test will fail,
    320     // even though that is the correct behavior.  To test the cloning
    321     // of the symbols, it is necessary to pass in a reference to the symbols
    322     DecimalFormat *df = new DecimalFormat("#,##0.0", *symbols, status);
    323     failure(status, "new DecimalFormat with symbols", "");
    324     int32_t n = 123;
    325     UnicodeString buf1;
    326     UnicodeString buf2;
    327     FieldPosition pos(FieldPosition::DONT_CARE);
    328     logln(UnicodeString("format(") + n + ") = " +
    329         df->format(n, buf1, pos));
    330     symbols->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, UnicodeString((UChar)0x70)); // change value of field
    331     logln(UnicodeString("format(") + n + ") = " +
    332         df->format(n, buf2, pos));
    333     if(buf1 != buf2)
    334         errln("Test for bug 4087245 failed");
    335 
    336     delete df;
    337     delete symbols;
    338 }
    339 
    340 /* @bug 4087535
    341  * DecimalFormat.format() incorrectly formats 0.0
    342  */
    343 void NumberFormatRegressionTest::Test4087535 (void)
    344 {
    345     UErrorCode status = U_ZERO_ERROR;
    346     DecimalFormat *df = new DecimalFormat(status);
    347     failure(status, "new DecimalFormat", "");
    348     df->setMinimumIntegerDigits(0);
    349 
    350     double n = 0;
    351     UnicodeString buffer;
    352     FieldPosition pos(FieldPosition::DONT_CARE);
    353     buffer = df->format(n, buffer, pos);
    354     if (buffer.length() == 0)
    355         errln(/*n + */": '" + buffer + "'");
    356     n = 0.1;
    357     buffer = df->format(n, buffer, pos);
    358     if (buffer.length() == 0)
    359         errln(/*n + */": '" + buffer + "'");
    360 
    361     delete df;
    362 }
    363 
    364 /* @bug 4088503
    365  * DecimalFormat.format fails when groupingSize is set to 0.
    366  */
    367 // {sfb} how do I tell if this worked? --> FieldPosition doesn't change ??
    368 void NumberFormatRegressionTest::Test4088503 (void)
    369 {
    370     UErrorCode status = U_ZERO_ERROR;
    371     DecimalFormat *df = new DecimalFormat(status);
    372     failure(status, "new DecimalFormat", "");
    373     df->setGroupingSize(0);
    374     UnicodeString sBuf;
    375     FieldPosition fp(FieldPosition::DONT_CARE);
    376     //try {
    377         logln(df->format((int32_t)123, sBuf, fp));
    378         //if(fp == FieldPosition(0))
    379         //    errln("Test for bug 4088503 failed.");
    380     /*} catch (Exception foo) {
    381         errln("Test for bug 4088503 failed.");
    382     }*/
    383     delete df;
    384 
    385 }
    386 /* @bug 4066646
    387  * NumberFormat.getCurrencyInstance is wrong.
    388  */
    389 void NumberFormatRegressionTest::Test4066646 (void)
    390 {
    391     assignFloatValue(2.04f);
    392     assignFloatValue(2.03f);
    393     assignFloatValue(2.02f);
    394     assignFloatValue(0.0f);
    395 }
    396 
    397 float
    398 NumberFormatRegressionTest::assignFloatValue(float returnfloat)
    399 {
    400     logln(UnicodeString(" VALUE ") + returnfloat);
    401     UErrorCode status = U_ZERO_ERROR;
    402     NumberFormat *nfcommon =  NumberFormat::createCurrencyInstance(Locale::getUS(), status);
    403     if (failure(status, "NumberFormat::createCurrencyInstance", Locale::getUS(), TRUE)){
    404         delete nfcommon;
    405         return returnfloat;
    406     }
    407     nfcommon->setGroupingUsed(FALSE);
    408 
    409     UnicodeString stringValue;
    410     stringValue = nfcommon->format(returnfloat, stringValue);
    411     logln(" DISPLAYVALUE " + stringValue);
    412     Formattable result;
    413     nfcommon->parse(stringValue, result, status);
    414     failure(status, "nfcommon->parse", Locale::getUS());
    415     float floatResult = (float) (result.getType() == Formattable::kDouble
    416                                         ? result.getDouble() : result.getLong());
    417     if( uprv_fabs(floatResult - returnfloat) > 0.0001)
    418     //String stringValue = nfcommon.format(returnfloat).substring(1);
    419     //if (Float.valueOf(stringValue).floatValue() != returnfloat)
    420         errln(UnicodeString("FAIL: expected ") + returnfloat + ", got " + floatResult + " (" + stringValue+")");
    421 
    422     delete nfcommon;
    423     return returnfloat;
    424 } // End Of assignFloatValue()
    425 
    426 /* @bug 4059870
    427  * DecimalFormat throws exception when parsing "0"
    428  */
    429 void NumberFormatRegressionTest::Test4059870(void)
    430 {
    431     UErrorCode status = U_ZERO_ERROR;
    432     DecimalFormat *format = new DecimalFormat("00", status);
    433     failure(status, "new Decimalformat", Locale::getUS());
    434     //try {
    435         Formattable result;
    436         UnicodeString str;
    437         format->parse(UnicodeString("0"), result, status);
    438         failure(status, "format->parse", Locale::getUS());
    439 
    440     /*}
    441     catch (Exception e) {
    442         errln("Test for bug 4059870 failed : " + e);
    443     }*/
    444 
    445     delete format;
    446 }
    447 /* @bug 4083018
    448  * DecimalFormatSymbol.equals should always return false when
    449  * comparing with null.
    450  */
    451 // {sfb} this is silly in C++
    452 void NumberFormatRegressionTest::Test4083018 (void)
    453 {
    454     UErrorCode status = U_ZERO_ERROR;
    455     DecimalFormatSymbols *dfs = new DecimalFormatSymbols(status);
    456     failure(status, "new DecimalFormatSymbols", Locale::getUS());
    457     //try {
    458         if (dfs != NULL)
    459             logln("Test Passed!");
    460         else
    461             errln("Test for bug 4083018 failed");
    462     /*} catch (Exception foo) {
    463         errln("Test for bug 4083018 failed => Message : " + foo.getMessage());
    464     }*/
    465 
    466     delete dfs;
    467 }
    468 
    469 /* @bug 4071492
    470  * DecimalFormat does not round up correctly.
    471  */
    472 void NumberFormatRegressionTest::Test4071492 (void)
    473 {
    474     double x = 0.00159999;
    475     UErrorCode status = U_ZERO_ERROR;
    476     NumberFormat *nf = NumberFormat::createInstance(status);
    477     if (failure(status, "NumberFormat::createInstance", Locale::getUS(), TRUE)) {
    478         delete nf;
    479         return;
    480     }
    481     nf->setMaximumFractionDigits(4);
    482     UnicodeString out;
    483     FieldPosition pos(FieldPosition::DONT_CARE);
    484     out = nf->format(x, out, pos);
    485     logln("0.00159999 formats with 4 fractional digits to " + out);
    486     UnicodeString expected("0.0016");
    487     if (out != expected)
    488         errln("FAIL: Expected " + expected);
    489 
    490     delete nf;
    491 }
    492 
    493 /* @bug 4086575
    494  * A space as a group separator for localized pattern causes
    495  * wrong format.  WorkAround : use non-breaking space.
    496  */
    497 void NumberFormatRegressionTest::Test4086575(void)
    498 {
    499     UErrorCode status = U_ZERO_ERROR;
    500     NumberFormat *nf1 = NumberFormat::createInstance(Locale::getFrance(), status);
    501 
    502     // TODO: There is not a good way to find out that the creation of this number format has
    503     // failed. Major rewiring of format construction proposed.
    504     if(U_FAILURE(status)) {
    505       dataerrln("Something is wrong with French number format - it should not fallback. Exitting - %s", u_errorName(status));
    506       delete nf1;
    507       return;
    508     }
    509     failure(status, "NumberFormat::createInstance", Locale::getFrance());
    510 
    511     // C++ workaround to make sure cast works
    512     DecimalFormat *nf = dynamic_cast<DecimalFormat *>(nf1);
    513     if(nf == NULL) {
    514         errln("NumberFormat::createInstance returned incorrect type.");
    515         return;
    516     }
    517 
    518     UnicodeString temp;
    519     logln("nf toPattern1: " + nf->toPattern(temp));
    520     logln("nf toLocPattern1: " + nf->toLocalizedPattern(temp));
    521 
    522     // No group separator
    523     logln("...applyLocalizedPattern ###,00;(###,00) ");
    524     nf->applyLocalizedPattern(UnicodeString("###,00;(###,00)"), status);
    525     failure(status, "nf->applyLocalizedPattern", Locale::getFrance());
    526     logln("nf toPattern2: " + nf->toPattern(temp));
    527     logln("nf toLocPattern2: " + nf->toLocalizedPattern(temp));
    528 
    529     FieldPosition pos(FieldPosition::DONT_CARE);
    530     logln("nf: " + nf->format((int32_t)1234, temp, pos)); // 1234,00
    531     logln("nf: " + nf->format((int32_t)-1234, temp, pos)); // (1234,00)
    532 
    533     // Space as group separator
    534 
    535     logln("...applyLocalizedPattern # ###,00;(# ###,00) ");
    536     // nbsp = \u00a0
    537     //nf->applyLocalizedPattern("#\u00a0###,00;(#\u00a0###,00)");
    538     UChar patChars[] = {
    539              0x23, 0x00a0, 0x23, 0x23, 0x23, 0x2c, 0x30, 0x30, 0x3b,
    540         0x28, 0x23, 0x00a0, 0x23, 0x23, 0x23, 0x2c, 0x30, 0x30, 0x29
    541     };
    542     UnicodeString pat(patChars, 19, 19);
    543     nf->applyLocalizedPattern(pat, status);
    544     failure(status, "nf->applyLocalizedPattern", Locale::getFrance());
    545     logln("nf toPattern2: " + nf->toPattern(temp));
    546     logln("nf toLocPattern2: " + nf->toLocalizedPattern(temp));
    547     UnicodeString buffer;
    548     buffer = nf->format((int32_t)1234, buffer, pos);
    549     //if (buffer != UnicodeString("1\u00a0234,00"))
    550     UChar c[] = {
    551         0x31, 0x00a0, 0x32, 0x33, 0x34, 0x2c, 0x30, 0x30
    552     };
    553     UnicodeString cc(c, 8, 8);
    554     if (buffer != cc)
    555         errln("nf : " + buffer); // Expect 1 234,00
    556 
    557     buffer.remove();
    558     buffer = nf->format((int32_t)-1234, buffer, pos);
    559     UChar c1[] = {
    560         0x28, 0x31, 0x00a0, 0x32, 0x33, 0x34, 0x2c, 0x30, 0x30, 0x29
    561     };
    562     UnicodeString cc1(c1, 10, 10);
    563     if (buffer != cc1)
    564         errln("nf : " + buffer); // Expect (1 234,00)
    565 
    566     // Erroneously prints:
    567     // 1234,00 ,
    568     // (1234,00 ,)
    569 
    570     delete nf1;
    571 }
    572 /* @bug 4068693
    573  * DecimalFormat.parse returns wrong value
    574  */
    575 // {sfb} slightly converted into a round-trip test, since in C++
    576 // there is no Double.toString()
    577 void NumberFormatRegressionTest::Test4068693(void)
    578 {
    579     logln("----- Test Application -----");
    580     ParsePosition pos(0);
    581     UErrorCode status = U_ZERO_ERROR;
    582     DecimalFormat *df = new DecimalFormat(status);
    583     if(U_FAILURE(status)) {
    584       errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
    585       delete df;
    586       return;
    587     }
    588     failure(status, "new DecimalFormat");
    589     Formattable d;
    590     //Double d = (Double)df.parse("123.55456", pos=new ParsePosition(0));
    591     df->parse(UnicodeString("123.55456"), d, pos);
    592     //if (!d.toString().equals("123.55456")) {
    593     UnicodeString dstr;
    594     df->setMaximumFractionDigits(999);
    595     df->setMaximumIntegerDigits(999);
    596     FieldPosition fp(FieldPosition::DONT_CARE);
    597     dstr = df->format(d.getDouble(), dstr, fp);
    598     if (dstr != UnicodeString("123.55456")) {
    599         errln(UnicodeString("Result -> ") + d.getDouble());
    600     }
    601 
    602     delete df;
    603 }
    604 
    605 /* @bug 4069754, 4067878
    606  * null pointer thrown when accessing a deserialized DecimalFormat
    607  * object.
    608  */
    609 // {sfb} doesn't apply in C++
    610 void NumberFormatRegressionTest::Test4069754(void)
    611 {
    612 /*    try {
    613         myformat it = new myformat();
    614         logln(it.Now());
    615         FileOutputStream ostream = new FileOutputStream("t.tmp");
    616         ObjectOutputStream p = new ObjectOutputStream(ostream);
    617         p.writeObject(it);
    618         ostream.close();
    619         logln("Saved ok.");
    620 
    621         FileInputStream istream = new FileInputStream("t.tmp");
    622         ObjectInputStream p2 = new ObjectInputStream(istream);
    623         myformat it2 = (myformat)p2.readObject();
    624         logln(it2.Now());
    625         istream.close();
    626         logln("Loaded ok.");
    627     } catch (Exception foo) {
    628         errln("Test for bug 4069754 or 4057878 failed => Exception: " + foo.getMessage());
    629     }
    630 */}
    631 
    632 /* @bug 4087251
    633  * DecimalFormat.applyPattern(String) allows illegal patterns
    634  */
    635 void NumberFormatRegressionTest::Test4087251 (void)
    636 {
    637     UErrorCode status = U_ZERO_ERROR;
    638     DecimalFormat *df = new DecimalFormat(status);
    639     if(U_FAILURE(status)) {
    640       errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
    641       delete df;
    642       return;
    643     }
    644     failure(status, "new DecimalFormat");
    645     //try {
    646         df->applyPattern(UnicodeString("#.#.#"), status);
    647         if( ! U_FAILURE(status))
    648             errln("df->applyPattern with illegal pattern didn't fail");
    649         UnicodeString temp;
    650         logln("toPattern() returns \"" + df->toPattern(temp) + "\"");
    651         //errln("applyPattern(\"#.#.#\") doesn't throw IllegalArgumentException");
    652     /*} catch (IllegalArgumentException e) {
    653         logln("Caught Illegal Argument Error !");
    654     }*/
    655     // Second test; added 5/11/98 when reported to fail on 1.2b3
    656     //try {
    657         df->applyPattern("#0.0#0#0", status);
    658         if( ! U_FAILURE(status))
    659             errln("df->applyPattern with illegal pattern didn't fail");
    660         logln("toPattern() returns \"" + df->toPattern(temp) + "\"");
    661         //errln("applyPattern(\"#0.0#0#0\") doesn't throw IllegalArgumentException");
    662     /*} catch (IllegalArgumentException e) {
    663         logln("Ok - IllegalArgumentException for #0.0#0#0");
    664     }*/
    665 
    666     delete df;
    667 }
    668 
    669 /* @bug 4090489
    670  * DecimalFormat.format() loses precision
    671  */
    672 void NumberFormatRegressionTest::Test4090489 (void)
    673 {
    674 // {sfb} sprintf doesn't correctly handle the double, so there is nothing
    675 // that NumberFormat can do.  For some reason, it does not format the last 1.
    676 
    677 /*    UErrorCode status = U_ZERO_ERROR;
    678     DecimalFormat *df = new DecimalFormat(status);
    679     failure(status, "new DecimalFormat");
    680     df->setMinimumFractionDigits(10);
    681     df->setMaximumFractionDigits(999);
    682     df->setGroupingUsed(FALSE);
    683     double d = 1.000000000000001E7;
    684     //BigDecimal bd = new BigDecimal(d);
    685     UnicodeString sb;
    686     FieldPosition fp(0);
    687     logln(UnicodeString("d = ") + d);
    688     //logln("BigDecimal.toString():  " + bd.toString());
    689     df->format(d, sb, fp);
    690     if (sb != "10000000.0000000100") {
    691         errln("DecimalFormat.format(): " + sb);
    692     }
    693 */
    694 }
    695 
    696 /* @bug 4090504
    697  * DecimalFormat.format() loses precision
    698  */
    699 void NumberFormatRegressionTest::Test4090504 (void)
    700 {
    701     double d = 1;
    702     logln(UnicodeString("d = ") + d);
    703     UErrorCode status = U_ZERO_ERROR;
    704     DecimalFormat *df = new DecimalFormat(status);
    705     if(U_FAILURE(status)) {
    706       errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
    707       delete df;
    708       return;
    709     }
    710     failure(status, "new DecimalFormat");
    711     UnicodeString sb;
    712     FieldPosition fp(FieldPosition::DONT_CARE);
    713     //try {
    714         for (int i = 17; i <= 20; i++) {
    715             df->setMaximumFractionDigits(i);
    716             //sb = new StringBuffer("");
    717             fp.setField(0);
    718             logln(UnicodeString("  getMaximumFractionDigits() = ") + i);
    719             logln(UnicodeString("  formated: ") + df->format(d, sb, fp));
    720         }
    721     /*} catch (Exception foo) {
    722         errln("Bug 4090504 regression test failed. Message : " + foo.getMessage());
    723     }*/
    724 
    725     delete df;
    726 }
    727 /* @bug 4095713
    728  * DecimalFormat.parse(String str, ParsePosition pp) loses precision
    729  */
    730 void NumberFormatRegressionTest::Test4095713 (void)
    731 {
    732     UErrorCode status = U_ZERO_ERROR;
    733     DecimalFormat *df = new DecimalFormat(status);
    734     if(U_FAILURE(status)) {
    735       errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
    736       delete df;
    737       return;
    738     }
    739     failure(status, "new DecimalFormat");
    740     UnicodeString str("0.1234");
    741     double d1 = 0.1234;
    742     //Double d1 = new Double(str);
    743     //Double d2 = (Double) df.parse(str, new ParsePosition(0));
    744     Formattable d2;
    745     ParsePosition pp(0);
    746     df->parse(str, d2, pp);
    747     logln(UnicodeString("") + d1);
    748     if (d2.getDouble() != d1)
    749         errln(UnicodeString("Bug 4095713 test failed, new double value : ") + d2.getDouble());
    750     delete df;
    751 }
    752 
    753 /* @bug 4092561
    754  * DecimalFormat.parse() fails when multiplier is not set to 1
    755  */
    756 // {sfb} not sure what to do with this one
    757 void NumberFormatRegressionTest::Test4092561 (void)
    758 {
    759     UErrorCode status = U_ZERO_ERROR;
    760     DecimalFormat *df = new DecimalFormat(status);
    761     if(U_FAILURE(status)) {
    762       errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
    763       delete df;
    764       return;
    765     }
    766     failure(status, "new DecimalFormat");
    767 
    768     // {sfb} going to cheat here and use sprintf ??
    769 
    770     /*UnicodeString str = Long.toString(Long.MIN_VALUE);
    771     logln("Long.MIN_VALUE : " + df.parse(str, new ParsePosition(0)).toString());
    772     df.setMultiplier(100);
    773     Number num = df.parse(str, new ParsePosition(0));
    774     if (num.doubleValue() != -9.223372036854776E16)
    775         errln("Bug 4092561 test failed when multiplier is set to not 1.");
    776 */
    777     delete df;
    778 }
    779 
    780 /* @bug 4092480
    781  * DecimalFormat: Negative format ignored.
    782  */
    783 void NumberFormatRegressionTest::Test4092480 (void)
    784 {
    785     UErrorCode status = U_ZERO_ERROR;
    786     DecimalFormat *dfFoo = new DecimalFormat(UnicodeString("000"), status);
    787     if(U_FAILURE(status)) {
    788       errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
    789       delete dfFoo;
    790       return;
    791     }
    792     failure(status, "new DecimalFormat");
    793 
    794     //try {
    795         dfFoo->applyPattern("0000;-000", status);
    796         failure(status, "dfFoo->applyPattern");
    797         UnicodeString temp;
    798         if (dfFoo->toPattern(temp) != UnicodeString("#0000"))
    799             errln("dfFoo.toPattern : " + dfFoo->toPattern(temp));
    800         FieldPosition pos(FieldPosition::DONT_CARE);
    801         logln(dfFoo->format((int32_t)42, temp, pos));
    802         logln(dfFoo->format((int32_t)-42, temp, pos));
    803         dfFoo->applyPattern("000;-000", status);
    804         failure(status, "dfFoo->applyPattern");
    805         if (dfFoo->toPattern(temp) != UnicodeString("#000"))
    806             errln("dfFoo.toPattern : " + dfFoo->toPattern(temp));
    807         logln(dfFoo->format((int32_t)42,temp, pos));
    808         logln(dfFoo->format((int32_t)-42, temp, pos));
    809 
    810         dfFoo->applyPattern("000;-0000", status);
    811         failure(status, "dfFoo->applyPattern");
    812         if (dfFoo->toPattern(temp) != UnicodeString("#000"))
    813             errln("dfFoo.toPattern : " + dfFoo->toPattern(temp));
    814         logln(dfFoo->format((int32_t)42, temp, pos));
    815         logln(dfFoo->format((int32_t)-42, temp, pos));
    816 
    817         dfFoo->applyPattern("0000;-000", status);
    818         failure(status, "dfFoo->applyPattern");
    819         if (dfFoo->toPattern(temp) != UnicodeString("#0000"))
    820             errln("dfFoo.toPattern : " + dfFoo->toPattern(temp));
    821         logln(dfFoo->format((int32_t)42, temp, pos));
    822         logln(dfFoo->format((int32_t)-42, temp, pos));
    823     /*} catch (Exception foo) {
    824         errln("Message " + foo.getMessage());
    825     }*/
    826 
    827     delete dfFoo;
    828 }
    829 /* @bug 4087244
    830  * NumberFormat.getCurrencyInstance() produces format that uses
    831  * decimal separator instead of monetary decimal separator.
    832  *
    833  * Rewrote this test not to depend on the actual pattern.  Pattern should
    834  * never contain the monetary separator!  Decimal separator in pattern is
    835  * interpreted as monetary separator if currency symbol is seen!
    836  */
    837 void NumberFormatRegressionTest::Test4087244 (void) {
    838     UErrorCode status = U_ZERO_ERROR;
    839     char loc[256] = {0};
    840     uloc_canonicalize("pt_PT_PREEURO", loc, 256, &status);
    841     Locale *de = new Locale(loc);
    842     NumberFormat *nf = NumberFormat::createCurrencyInstance(*de, status);
    843     if(U_FAILURE(status)) {
    844       dataerrln("Error creating DecimalFormat: %s", u_errorName(status));
    845       delete nf;
    846       return;
    847     }
    848     DecimalFormat *df = dynamic_cast<DecimalFormat *>(nf);
    849     if(df == NULL) {
    850         errln("expected DecimalFormat!");
    851         return;
    852     }
    853     const DecimalFormatSymbols *sym = df->getDecimalFormatSymbols();
    854     UnicodeString decSep = sym->getSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol);
    855     UnicodeString monSep = sym->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol);
    856     if (decSep == monSep) {
    857         errln("ERROR in test: want decimal sep != monetary sep");
    858         return;
    859     }
    860     df->setMinimumIntegerDigits(1);
    861     df->setMinimumFractionDigits(2);
    862     UnicodeString str;
    863     FieldPosition pos;
    864     df->format(1.23, str, pos);
    865     UnicodeString monStr("1x23");
    866     monStr.replace((int32_t)1, 1, monSep);
    867     UnicodeString decStr("1x23");
    868     decStr.replace((int32_t)1, 1, decSep);
    869     if (str.indexOf(monStr) >= 0 && str.indexOf(decStr) < 0) {
    870         logln(UnicodeString("OK: 1.23 -> \"") + str + "\" contains \"" +
    871               monStr + "\" and not \"" + decStr + '"');
    872     } else {
    873         errln(UnicodeString("FAIL: 1.23 -> \"") + str + "\", should contain \"" +
    874               monStr +
    875               "\" and not \"" + decStr + '"');
    876     }
    877     delete de;
    878     delete nf;
    879 }
    880 /* @bug 4070798
    881  * Number format data rounding errors for locale FR
    882  */
    883 void NumberFormatRegressionTest::Test4070798 (void)
    884 {
    885     NumberFormat *formatter;
    886     UnicodeString tempString;
    887 
    888     /* User error :
    889     String expectedDefault = "-5\u00a0789,987";
    890     String expectedCurrency = "5\u00a0789,98\u00a0F";
    891     String expectedPercent = "-578\u00a0998%";
    892     */
    893     UChar chars1 [] = {
    894         0x2d, 0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x38, 0x38
    895     };
    896     UChar chars2 [] = {
    897         0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x39, 0x00a0, 0x46
    898     };
    899     UChar chars3 [] = {
    900         0x2d, 0x35, 0x37, 0x38, 0x00a0, 0x39, 0x39, 0x39, 0x00a0, 0x25
    901     };
    902     UnicodeString expectedDefault(chars1, 10, 10);
    903     UnicodeString expectedCurrency(chars2, 10, 10);
    904     UnicodeString expectedPercent(chars3, 10, 10);
    905 
    906     UErrorCode status = U_ZERO_ERROR;
    907     char loc[256]={0};
    908     int len = uloc_canonicalize("fr_FR_PREEURO", loc, 256, &status);
    909     formatter = NumberFormat::createInstance(Locale(loc), status);
    910     if(U_FAILURE(status)) {
    911       dataerrln("Error creating DecimalFormat: %s", u_errorName(status));
    912       delete formatter;
    913       return;
    914     }
    915     failure(status, "NumberFormat::createNumberInstance", loc);
    916     tempString = formatter->format (-5789.9876, tempString);
    917 
    918     if (tempString == expectedDefault) {
    919         logln ("Bug 4070798 default test passed.");
    920     } else {
    921         errln(UnicodeString("Failed:") +
    922         " Expected " + expectedDefault +
    923         " Received " + tempString );
    924     }
    925     delete formatter;
    926     len = uloc_canonicalize("fr_FR_PREEURO", loc, 256, &status);
    927     formatter = NumberFormat::createCurrencyInstance(loc, status);
    928     failure(status, "NumberFormat::createCurrencyInstance", loc);
    929     tempString.remove();
    930     tempString = formatter->format( 5789.9876, tempString );
    931 
    932     if (tempString == expectedCurrency) {
    933         logln ("Bug 4070798 currency test passed.");
    934     } else {
    935         errln(UnicodeString("Failed:") +
    936         " Expected " + expectedCurrency +
    937         " Received " + tempString );
    938     }
    939     delete formatter;
    940 
    941     uloc_canonicalize("fr_FR_PREEURO", loc, 256, &status);
    942     formatter = NumberFormat::createPercentInstance(Locale(loc), status);
    943     failure(status, "NumberFormat::createPercentInstance", loc);
    944     tempString.remove();
    945     tempString = formatter->format (-5789.9876, tempString);
    946 
    947     if (tempString == expectedPercent) {
    948         logln ("Bug 4070798 percentage test passed.");
    949     } else {
    950         errln(UnicodeString("Failed:") +
    951         " Expected " + expectedPercent +
    952         " Received " + tempString );
    953     }
    954 
    955     delete formatter;
    956 }
    957 /* @bug 4071005
    958  * Data rounding errors for French (Canada) locale
    959  */
    960 void NumberFormatRegressionTest::Test4071005 (void)
    961 {
    962     NumberFormat *formatter;
    963     UnicodeString tempString;
    964     /* User error :
    965     String expectedDefault = "-5\u00a0789,987";
    966     String expectedCurrency = "5\u00a0789,98\u00a0$";
    967     String expectedPercent = "-578\u00a0998%";
    968     */
    969     UChar chars1 [] = {
    970         0x2d, 0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x38, 0x38
    971     };
    972     UChar chars2 [] = {
    973         0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x39, 0x00a0, 0x24
    974     };
    975     UChar chars3 [] = {
    976         0x2d, 0x35, 0x37, 0x38, 0x00a0, 0x39, 0x39, 0x39, 0x00a0, 0x25
    977     };
    978     UnicodeString expectedDefault(chars1, 10, 10);
    979     UnicodeString expectedCurrency(chars2, 10, 10);
    980     UnicodeString expectedPercent(chars3, 10, 10);
    981 
    982     UErrorCode status = U_ZERO_ERROR;
    983     formatter = NumberFormat::createInstance(Locale::getCanadaFrench(), status);
    984     if (failure(status, "NumberFormat::createNumberInstance", Locale::getCanadaFrench(), TRUE)){
    985         delete formatter;
    986         return;
    987     };
    988     tempString = formatter->format (-5789.9876, tempString);
    989 
    990     if (tempString == expectedDefault) {
    991         logln ("Bug 4071005 default test passed.");
    992     } else {
    993         errln(UnicodeString("Failed:") +
    994         " Expected " + expectedDefault +
    995         " Received " + tempString );
    996     }
    997     delete formatter;
    998 
    999     formatter = NumberFormat::createCurrencyInstance(Locale::getCanadaFrench(), status);
   1000     failure(status, "NumberFormat::createCurrencyInstance", Locale::getCanadaFrench());
   1001     tempString.remove();
   1002     tempString = formatter->format( 5789.9876, tempString );
   1003 
   1004     if (tempString == expectedCurrency) {
   1005         logln ("Bug 4071005 currency test assed.");
   1006     } else {
   1007         errln(UnicodeString("Failed:") +
   1008         " Expected " + expectedCurrency +
   1009         " Received " + tempString );
   1010     }
   1011     delete formatter;
   1012 
   1013     formatter = NumberFormat::createPercentInstance(Locale::getCanadaFrench(), status);
   1014     failure(status, "NumberFormat::createPercentInstance", Locale::getCanadaFrench());
   1015     tempString.remove();
   1016     tempString = formatter->format (-5789.9876, tempString);
   1017 
   1018     if (tempString == expectedPercent) {
   1019         logln ("Bug 4071005 percentage test passed.");
   1020     } else {
   1021         errln(UnicodeString("Failed:") +
   1022         " Expected " + expectedPercent +
   1023         " Received " + tempString );
   1024     }
   1025 
   1026     delete formatter;
   1027 }
   1028 
   1029 /* @bug 4071014
   1030  * Data rounding errors for German (Germany) locale
   1031  */
   1032 void NumberFormatRegressionTest::Test4071014 (void)
   1033 {
   1034     NumberFormat *formatter;
   1035     UnicodeString tempString;
   1036     /* user error :
   1037     String expectedDefault = "-5.789,987";
   1038     String expectedCurrency = "5.789,98 DEM";
   1039     String expectedPercent = "-578.998%";
   1040     */
   1041     UnicodeString expectedDefault("-5.789,988");
   1042     UnicodeString expectedCurrency("5.789,99\\u00A0DEM");
   1043     UnicodeString expectedPercent("-578.999\\u00A0%");
   1044 
   1045     expectedCurrency = expectedCurrency.unescape();
   1046     expectedPercent = expectedPercent.unescape();
   1047 
   1048     UErrorCode status = U_ZERO_ERROR;
   1049     char loc[256]={0};
   1050     uloc_canonicalize("de_DE_PREEURO", loc, 256, &status);
   1051     formatter = NumberFormat::createInstance(Locale(loc), status);
   1052     if (failure(status, "NumberFormat::createNumberInstance", loc, TRUE)){
   1053         delete formatter;
   1054         return;
   1055     }
   1056     tempString.remove();
   1057     tempString = formatter->format (-5789.9876, tempString);
   1058 
   1059     if (tempString == expectedDefault) {
   1060         logln ("Bug 4071014 default test passed.");
   1061     } else {
   1062         errln(UnicodeString("Failed:") +
   1063         " Expected " + expectedDefault +
   1064         " Received " + tempString );
   1065     }
   1066     delete formatter;
   1067     uloc_canonicalize("de_DE_PREEURO", loc, 256, &status);
   1068     formatter = NumberFormat::createCurrencyInstance(Locale(loc), status);
   1069     failure(status, "NumberFormat::createCurrencyInstance", loc);
   1070     tempString.remove();
   1071     tempString = formatter->format( 5789.9876, tempString );
   1072 
   1073     if (tempString == expectedCurrency) {
   1074         logln ("Bug 4071014 currency test assed.");
   1075     } else {
   1076         errln(UnicodeString("Failed:") +
   1077         " Expected " + expectedCurrency +
   1078         " Received " + tempString );
   1079     }
   1080     delete formatter;
   1081 
   1082     formatter = NumberFormat::createPercentInstance(Locale::getGermany(), status);
   1083     failure(status, "NumberFormat::createPercentInstance", Locale::getGermany());
   1084     tempString.remove();
   1085     tempString = formatter->format (-5789.9876, tempString);
   1086 
   1087     if (tempString == expectedPercent) {
   1088         logln ("Bug 4071014 percentage test passed.");
   1089     } else {
   1090         errln(UnicodeString("Failed:") +
   1091         " Expected " + expectedPercent +
   1092         " Received " + tempString );
   1093     }
   1094 
   1095     delete formatter;
   1096 }
   1097 /* @bug 4071859
   1098  * Data rounding errors for Italian locale number formats
   1099  */
   1100 void NumberFormatRegressionTest::Test4071859 (void)
   1101 {
   1102     NumberFormat *formatter;
   1103     UnicodeString tempString;
   1104     /* user error :
   1105     String expectedDefault = "-5.789,987";
   1106     String expectedCurrency = "-L.\\u00A05.789,98";
   1107     String expectedPercent = "-578.998%";
   1108     */
   1109     UnicodeString expectedDefault("-5.789,988");
   1110     UnicodeString expectedCurrency("-ITL\\u00A05.790", -1, US_INV);
   1111     UnicodeString expectedPercent("-578.999%");
   1112     expectedCurrency = expectedCurrency.unescape();
   1113 
   1114     UErrorCode status = U_ZERO_ERROR;
   1115     char loc[256]={0};
   1116     uloc_canonicalize("it_IT_PREEURO", loc, 256, &status);
   1117     formatter = NumberFormat::createInstance(Locale(loc), status);
   1118     if (failure(status, "NumberFormat::createNumberInstance", TRUE)){
   1119         delete formatter;
   1120         return;
   1121     };
   1122     tempString = formatter->format (-5789.9876, tempString);
   1123 
   1124     if (tempString == expectedDefault) {
   1125         logln ("Bug 4071859 default test passed.");
   1126     } else {
   1127         errln(UnicodeString("Failed:") +
   1128         " Expected " + expectedDefault +
   1129         " Received " + tempString );
   1130     }
   1131     delete formatter;
   1132     uloc_canonicalize("it_IT_PREEURO", loc, 256, &status);
   1133     formatter = NumberFormat::createCurrencyInstance(Locale(loc), status);
   1134     failure(status, "NumberFormat::createCurrencyInstance");
   1135     tempString.remove();
   1136     tempString = formatter->format( -5789.9876, tempString );
   1137 
   1138     if (tempString == expectedCurrency) {
   1139         logln ("Bug 4071859 currency test assed.");
   1140     } else {
   1141         errln(UnicodeString("Failed:") +
   1142         " Expected " + expectedCurrency +
   1143         " Received " + tempString );
   1144     }
   1145     delete formatter;
   1146     uloc_canonicalize("it_IT_PREEURO", loc, 256, &status);
   1147     formatter = NumberFormat::createPercentInstance(Locale(loc), status);
   1148     failure(status, "NumberFormat::createPercentInstance");
   1149     tempString.remove();
   1150     tempString = formatter->format (-5789.9876, tempString);
   1151 
   1152     if (tempString == expectedPercent) {
   1153         logln ("Bug 4071859 percentage test passed.");
   1154     } else {
   1155         errln(UnicodeString("Failed:") +
   1156         " Expected " + expectedPercent +
   1157         " Received " + tempString );
   1158     }
   1159 
   1160     delete formatter;
   1161 }
   1162 /* @bug 4071859
   1163  * Test rounding for nearest even.
   1164  */
   1165 void NumberFormatRegressionTest::Test4093610(void)
   1166 {
   1167     UErrorCode status = U_ZERO_ERROR;
   1168     DecimalFormat *df = new DecimalFormat("#0.#", status);
   1169     if (!failure(status, "new DecimalFormat")) {
   1170         UnicodeString s("12.4");
   1171         roundingTest(df, 12.35, s);
   1172         roundingTest(df, 12.45, s);
   1173         s = "12.5";
   1174         roundingTest(df, 12.452,s);
   1175         s = "12.6";
   1176         roundingTest(df, 12.55, s);
   1177         roundingTest(df, 12.65, s);
   1178         s = "12.7";
   1179         roundingTest(df, 12.652,s);
   1180         s = "12.8";
   1181         roundingTest(df, 12.75, s);
   1182         roundingTest(df, 12.752,s);
   1183         roundingTest(df, 12.85, s);
   1184         s = "12.9";
   1185         roundingTest(df, 12.852,s);
   1186         s = "13";
   1187         roundingTest(df, 12.95, s);
   1188         roundingTest(df, 12.952,s);
   1189     }
   1190 
   1191     delete df;
   1192 }
   1193 
   1194 void NumberFormatRegressionTest::roundingTest(DecimalFormat *df, double x, UnicodeString& expected)
   1195 {
   1196     UnicodeString out;
   1197     FieldPosition pos(FieldPosition::DONT_CARE);
   1198     out = df->format(x, out, pos);
   1199     logln(UnicodeString("") + x + " formats with 1 fractional digits to " + out);
   1200     if (out != expected)
   1201         errln("FAIL: Expected " + expected);
   1202 }
   1203 /* @bug 4098741
   1204  * Tests the setMaximumFractionDigits limit.
   1205  */
   1206 void NumberFormatRegressionTest::Test4098741(void)
   1207 {
   1208     //try {
   1209     UErrorCode status = U_ZERO_ERROR;
   1210     NumberFormat *fmt = NumberFormat::createPercentInstance(status);
   1211     if (U_FAILURE(status)) {
   1212         dataerrln("Error calling NumberFormat::createPercentInstance");
   1213         delete fmt;
   1214         return;
   1215     }
   1216 
   1217         fmt->setMaximumFractionDigits(20);
   1218         UnicodeString temp;
   1219         logln(fmt->format(.001, temp));
   1220     /*} catch (Exception foo) {
   1221         errln("Bug 4098471 failed with exception thrown : " + foo.getMessage());
   1222     }*/
   1223     delete fmt;
   1224 }
   1225 /* @bug 4074454
   1226  * Tests illegal pattern exception.
   1227  * Fix comment : HShih A31 Part1 will not be fixed and javadoc needs to be updated.
   1228  * Part2 has been fixed.
   1229  */
   1230 void NumberFormatRegressionTest::Test4074454(void)
   1231 {
   1232     //try {
   1233     UErrorCode status = U_ZERO_ERROR;
   1234     DecimalFormat *fmt = new DecimalFormat("#,#00.00;-#.#", status);
   1235     if(U_FAILURE(status)) {
   1236       errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
   1237       delete fmt;
   1238       return;
   1239     }
   1240     failure(status, "new DecimalFormat");
   1241       logln("Inconsistent negative pattern is fine.");
   1242         DecimalFormat *newFmt = new DecimalFormat("#,#00.00 p''ieces;-#,#00.00 p''ieces", status);
   1243         failure(status, "new DecimalFormat");
   1244         UnicodeString tempString;
   1245         FieldPosition pos(FieldPosition::DONT_CARE);
   1246         tempString = newFmt->format(3456.78, tempString, pos);
   1247         if (tempString != UnicodeString("3,456.78 p'ieces"))
   1248             dataerrln("Failed!  3456.78 p'ieces expected, but got : " + tempString);
   1249     /*} catch (Exception foo) {
   1250         errln("An exception was thrown for any inconsistent negative pattern.");
   1251     }*/
   1252 
   1253     delete fmt;
   1254     delete newFmt;
   1255 }
   1256 /* @bug 4099404
   1257  * Tests all different comments.
   1258  * Response to some comments :
   1259  * [1] DecimalFormat.parse API documentation is more than just one line.
   1260  * This is not a reproducable doc error in 116 source code.
   1261  * [2] See updated javadoc.
   1262  * [3] Fixed.
   1263  * [4] NumberFormat.parse(String, ParsePosition) : If parsing fails,
   1264  * a null object will be returned.  The unchanged parse position also
   1265  * reflects an error.
   1266  * NumberFormat.parse(String) : If parsing fails, an ParseException
   1267  * will be thrown.
   1268  * See updated javadoc for more details.
   1269  * [5] See updated javadoc.
   1270  * [6] See updated javadoc.
   1271  * [7] This is a correct behavior if the DateFormat object is linient.
   1272  * Otherwise, an IllegalArgumentException will be thrown when formatting
   1273  * "January 35".  See GregorianCalendar class javadoc for more details.
   1274  */
   1275 void NumberFormatRegressionTest::Test4099404(void)
   1276 {
   1277     //try {
   1278         UErrorCode status = U_ZERO_ERROR;
   1279         DecimalFormat *fmt = new DecimalFormat(UnicodeString("000.0#0"), status);
   1280         if(! U_FAILURE(status))
   1281             errln(UnicodeString("Bug 4099404 failed applying illegal pattern \"000.0#0\""));
   1282     /*} catch (Exception foo) {
   1283         logln("Bug 4099404 pattern \"000.0#0\" passed");
   1284     }*/
   1285     delete fmt;
   1286     fmt = 0;
   1287         //try {
   1288         fmt = new DecimalFormat(UnicodeString("0#0.000"), status);
   1289         if( !U_FAILURE(status))
   1290            errln("Bug 4099404 failed applying illegal pattern \"0#0.000\"");
   1291     /*} catch (Exception foo) {
   1292         logln("Bug 4099404 pattern \"0#0.000\" passed");
   1293     }*/
   1294 
   1295     delete fmt;
   1296 }
   1297 /* @bug 4101481
   1298  * DecimalFormat.applyPattern doesn't set minimum integer digits
   1299  */
   1300 void NumberFormatRegressionTest::Test4101481(void)
   1301 {
   1302     UErrorCode status = U_ZERO_ERROR;
   1303     DecimalFormat *sdf = new DecimalFormat(UnicodeString("#,##0"), status);
   1304     if(U_FAILURE(status)) {
   1305       errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
   1306       delete sdf;
   1307       return;
   1308     }
   1309     failure(status, "new DecimalFormat");
   1310     if (sdf->getMinimumIntegerDigits() != 1)
   1311         errln(UnicodeString("Minimum integer digits : ") + sdf->getMinimumIntegerDigits());
   1312     delete sdf;
   1313 }
   1314 /* @bug 4052223 (API addition request A27)
   1315  * Tests ParsePosition.setErrorPosition() and ParsePosition.getErrorPosition().
   1316  */
   1317 void NumberFormatRegressionTest::Test4052223(void)
   1318 {
   1319     //try {
   1320     UErrorCode status = U_ZERO_ERROR;
   1321         DecimalFormat *fmt = new DecimalFormat(UnicodeString("#,#00.00"), status);
   1322         if(U_FAILURE(status)) {
   1323           errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
   1324           delete fmt;
   1325           return;
   1326         }
   1327         failure(status, "new DecimalFormat");
   1328         Formattable num;
   1329         fmt->parse(UnicodeString("abc3"), num, status);
   1330         if(! U_FAILURE(status))
   1331             errln(UnicodeString("Bug 4052223 failed : can't parse string \"a\".  Got ") /*+ num*/);
   1332     /*} catch (ParseException foo) {
   1333         logln("Caught expected ParseException : " + foo.getMessage() + " at index : " + foo.getErrorOffset());
   1334     }*/
   1335     delete fmt;
   1336 }
   1337 /* @bug 4061302
   1338  * API tests for API addition request A9.
   1339  */
   1340 void NumberFormatRegressionTest::Test4061302(void)
   1341 {
   1342     UErrorCode status = U_ZERO_ERROR;
   1343     DecimalFormatSymbols *fmt = new DecimalFormatSymbols(status);
   1344     failure(status, "new DecimalFormatSymbols");
   1345     UnicodeString currency(fmt->getSymbol(DecimalFormatSymbols::kCurrencySymbol));
   1346     UnicodeString intlCurrency(fmt->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol));
   1347     UnicodeString monDecSeparator(fmt->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol));
   1348     if (currency == UnicodeString("") ||
   1349         intlCurrency == UnicodeString("") ||
   1350         monDecSeparator == UnicodeString(""))
   1351     {
   1352         errln("getCurrencySymbols failed, got empty string.");
   1353     }
   1354     UnicodeString monDecSeparatorStr;
   1355     monDecSeparatorStr.append(monDecSeparator);
   1356     logln((UnicodeString)"Before set ==> Currency : " + currency +(UnicodeString)" Intl Currency : " + intlCurrency + (UnicodeString)" Monetary Decimal Separator : " + monDecSeparatorStr);
   1357     fmt->setSymbol(DecimalFormatSymbols::kCurrencySymbol, UnicodeString("XYZ"));
   1358     fmt->setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol, UnicodeString("ABC"));
   1359     fmt->setSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol, UnicodeString((UChar)0x002A/*'*'*/));
   1360     currency = fmt->getSymbol(DecimalFormatSymbols::kCurrencySymbol);
   1361     intlCurrency = fmt->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol);
   1362     monDecSeparator = fmt->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol);
   1363     if (currency != UnicodeString("XYZ") ||
   1364         intlCurrency != UnicodeString("ABC") ||
   1365         monDecSeparator != UnicodeString((UChar)0x002A/*'*'*/)) {
   1366         errln("setCurrencySymbols failed.");
   1367     }
   1368     monDecSeparatorStr.remove();
   1369     monDecSeparatorStr.append(monDecSeparator);
   1370     logln("After set ==> Currency : " + currency + " Intl Currency : " + intlCurrency + " Monetary Decimal Separator : " + monDecSeparatorStr);
   1371 
   1372     delete fmt;
   1373 }
   1374 /* @bug 4062486
   1375  * API tests for API addition request A23. FieldPosition.getBeginIndex and
   1376  * FieldPosition.getEndIndex.
   1377  */
   1378 void NumberFormatRegressionTest::Test4062486(void)
   1379 {
   1380     UErrorCode status = U_ZERO_ERROR;
   1381     DecimalFormat *fmt = new DecimalFormat(UnicodeString("#,##0.00"), status);
   1382     failure(status, "new DecimalFormat");
   1383     UnicodeString formatted;
   1384     FieldPosition field(0);
   1385     double num = 1234.5;
   1386     fmt->format(num, formatted, field);
   1387     if (field.getBeginIndex() != 0 && field.getEndIndex() != 5)
   1388         errln(UnicodeString("Format 1234.5 failed. Begin index: ") /*+ field.getBeginIndex() + " End index: " + field.getEndIndex()*/);
   1389     field.setBeginIndex(7);
   1390     field.setEndIndex(4);
   1391     if (field.getBeginIndex() != 7 && field.getEndIndex() != 4)
   1392         errln("Set begin/end field indexes failed. Begin index: " /*+ field.getBeginIndex() + " End index: " + field.getEndIndex()*/);
   1393 
   1394     delete fmt;
   1395 }
   1396 
   1397 /* @bug 4108738
   1398  * DecimalFormat.parse incorrectly works with a group separator.
   1399  */
   1400 void NumberFormatRegressionTest::Test4108738(void)
   1401 {
   1402     UErrorCode status = U_ZERO_ERROR;
   1403     DecimalFormatSymbols *syms = new DecimalFormatSymbols(Locale::getUS(), status);
   1404     failure(status, "new DecimalFormatSymbols");
   1405     DecimalFormat *df = new DecimalFormat("#,##0.###", syms, status);
   1406     if(U_FAILURE(status)) {
   1407       errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
   1408       delete df;
   1409       return;
   1410     }
   1411     failure(status, "new DecimalFormat");
   1412     UnicodeString text("1.222,111");
   1413     Formattable num;
   1414     ParsePosition pp(0);
   1415     df->parse(text, num, pp);
   1416 
   1417     // {sfb} how to do this (again) ?
   1418     // shouldn't just be another round-trip test, should it?
   1419     UnicodeString temp;
   1420     FieldPosition pos(FieldPosition::DONT_CARE);
   1421     temp = df->format(num.getDouble(), temp, pos);
   1422     //if (!num.toString().equals("1.222"))
   1423     if (temp != UnicodeString("1.222"))
   1424         //errln("\"" + text + "\"  is parsed as " + num);
   1425         errln("\"" + text + "\"  is parsed as " + temp);
   1426     text = UnicodeString("1.222x111");
   1427     pp = ParsePosition(0);
   1428     df->parse(text, num, pp);
   1429     temp.remove();
   1430     temp = df->format(num.getDouble(), temp, pos);
   1431     //if (!num.toString().equals("1.222"))
   1432     if (temp != UnicodeString("1.222"))
   1433         errln("\"" + text + "\"  is parsed as " + temp);
   1434 
   1435     delete df;
   1436 }
   1437 
   1438 /* @bug 4106658
   1439  * DecimalFormat.format() incorrectly formats negative doubles.
   1440  */
   1441 void NumberFormatRegressionTest::Test4106658(void)
   1442 {
   1443     UErrorCode status = U_ZERO_ERROR;
   1444     DecimalFormat *df = new DecimalFormat(status); // Corrected; see 4147706
   1445     if(U_FAILURE(status)) {
   1446       errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
   1447       delete df;
   1448       return;
   1449     }
   1450     failure(status, "new DecimalFormat");
   1451     volatile double d1 = 0.0;   // volatile to prevent code optimization
   1452     double d2 = -0.0001;
   1453     UnicodeString buffer;
   1454     UnicodeString temp;
   1455     FieldPosition pos(FieldPosition::DONT_CARE);
   1456 
   1457 #if U_PLATFORM == U_PF_HPUX
   1458     d1 = 0.0 * -1.0;    // old HPUX compiler ignores volatile keyword
   1459 #else
   1460     d1 *= -1.0; // Some compilers have a problem with defining -0.0
   1461 #endif
   1462     logln("pattern: \"" + df->toPattern(temp) + "\"");
   1463     df->format(d1, buffer, pos);
   1464     if (buffer != UnicodeString("-0")) // Corrected; see 4147706
   1465         errln(UnicodeString("") + d1 + "      is formatted as " + buffer);
   1466     buffer.remove();
   1467     df->format(d2, buffer, pos);
   1468     if (buffer != UnicodeString("-0")) // Corrected; see 4147706
   1469         errln(UnicodeString("") + d2 + "      is formatted as " + buffer);
   1470 
   1471     delete df;
   1472 }
   1473 
   1474 /* @bug 4106662
   1475  * DecimalFormat.parse returns 0 if string parameter is incorrect.
   1476  */
   1477 void NumberFormatRegressionTest::Test4106662(void)
   1478 {
   1479     UErrorCode status = U_ZERO_ERROR;
   1480     DecimalFormat *df = new DecimalFormat(status);
   1481     if(U_FAILURE(status)) {
   1482       errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
   1483       delete df;
   1484       return;
   1485     }
   1486     failure(status, "new DecimalFormat");
   1487     UnicodeString text("x");
   1488     ParsePosition pos1(0), pos2(0);
   1489 
   1490     UnicodeString temp;
   1491     logln("pattern: \"" + df->toPattern(temp) + "\"");
   1492     Formattable num;
   1493     df->parse(text, num, pos1);
   1494     if (pos1 == ParsePosition(0)/*num != null*/) {
   1495         errln(UnicodeString("Test Failed: \"") + text + "\" is parsed as " /*+ num*/);
   1496     }
   1497     delete df;
   1498     df = new DecimalFormat(UnicodeString("$###.00"), status);
   1499     failure(status, "new DecimalFormat");
   1500     df->parse(UnicodeString("$"), num, pos2);
   1501     if (pos2 == ParsePosition(0) /*num != null*/){
   1502         errln(UnicodeString("Test Failed: \"$\" is parsed as ") /*+ num*/);
   1503     }
   1504 
   1505     delete df;
   1506 }
   1507 
   1508 /* @bug 4114639 (duplicate of 4106662)
   1509  * NumberFormat.parse doesn't return null
   1510  */
   1511 void NumberFormatRegressionTest::Test4114639(void)
   1512 {
   1513     UErrorCode status = U_ZERO_ERROR;
   1514     NumberFormat *format = NumberFormat::createInstance(status);
   1515     if(U_FAILURE(status)) {
   1516       dataerrln("Error creating DecimalFormat: %s", u_errorName(status));
   1517       delete format;
   1518       return;
   1519     }
   1520     failure(status, "NumberFormat::createInstance");
   1521     UnicodeString text("time 10:x");
   1522     ParsePosition pos(8);
   1523     Formattable result;
   1524     format->parse(text, result, pos);
   1525     if (/*result != null*/pos.getErrorIndex() != 8)
   1526         errln(UnicodeString("Should return null but got : ") /*+ result*/); // Should be null; it isn't
   1527 
   1528     delete format;
   1529 }
   1530 
   1531 /* @bug 4106664
   1532  * TODO: this test does not work because we need to use a 64 bit number and a
   1533  * a double only MAY only have 52 bits of precision.
   1534  * DecimalFormat.format(long n) fails if n * multiplier > MAX_LONG.
   1535  */
   1536 void NumberFormatRegressionTest::Test4106664(void)
   1537 {
   1538     UErrorCode status = U_ZERO_ERROR;
   1539     DecimalFormat *df = new DecimalFormat(status);
   1540     if(U_FAILURE(status)) {
   1541       errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
   1542       delete df;
   1543       return;
   1544     }
   1545     failure(status, "new DecimalFormat");
   1546     // {sfb} long in java is 64 bits
   1547     /*long*/double n = 1234567890123456.0;
   1548     /*int*/int32_t m = 12345678;
   1549     // {sfb} will this work?
   1550     //BigInteger bigN = BigInteger.valueOf(n);
   1551     //bigN = bigN.multiply(BigInteger.valueOf(m));
   1552     double bigN = n * m;
   1553     df->setMultiplier(m);
   1554     df->setGroupingUsed(FALSE);
   1555     UnicodeString temp;
   1556     FieldPosition pos(FieldPosition::DONT_CARE);
   1557     logln("formated: " +
   1558         df->format(n, temp, pos));
   1559 
   1560     char buf [128];
   1561     sprintf(buf, "%g", bigN);
   1562     //logln("expected: " + bigN.toString());
   1563     logln(UnicodeString("expected: ") + buf);
   1564 
   1565     delete df;
   1566 }
   1567 /* @bug 4106667 (duplicate of 4106658)
   1568  * DecimalFormat.format incorrectly formats -0.0.
   1569  */
   1570 void NumberFormatRegressionTest::Test4106667(void)
   1571 {
   1572     UErrorCode status = U_ZERO_ERROR;
   1573     DecimalFormat *df = new DecimalFormat(status);
   1574     if(U_FAILURE(status)) {
   1575       errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
   1576       delete df;
   1577       return;
   1578     }
   1579     failure(status, "new DecimalFormat");
   1580     UChar foo [] = { 0x002B };
   1581     UnicodeString bar(foo, 1, 1);
   1582     volatile double d = 0.0;   // volatile to prevent code optimization
   1583     UnicodeString temp;
   1584     UnicodeString buffer;
   1585     FieldPosition pos(FieldPosition::DONT_CARE);
   1586 
   1587     logln("pattern: \"" + df->toPattern(temp) + "\"");
   1588 #if U_PLATFORM == U_PF_HPUX
   1589     d = 0.0 * -1.0;    // old HPUX compiler ignores volatile keyword
   1590 #else
   1591     d *= -1.0; // Some compilers have a problem with defining -0.0
   1592 #endif
   1593     df->setPositivePrefix(/*"+"*/bar);
   1594     df->format(d, buffer, pos);
   1595     if (buffer != UnicodeString("-0")) // Corrected; see 4147706
   1596         errln(/*d + */UnicodeString("  is formatted as ") + buffer);
   1597 
   1598     delete df;
   1599 }
   1600 
   1601 /* @bug 4110936
   1602  * DecimalFormat.setMaximumIntegerDigits() works incorrectly.
   1603  */
   1604 #if U_PLATFORM == U_PF_OS390
   1605 #   define MAX_INT_DIGITS 70
   1606 #else
   1607 #   define MAX_INT_DIGITS 128
   1608 #endif
   1609 
   1610 void NumberFormatRegressionTest::Test4110936(void)
   1611 {
   1612     UErrorCode status = U_ZERO_ERROR;
   1613     NumberFormat *nf = NumberFormat::createInstance(status);
   1614     if(U_FAILURE(status)) {
   1615       dataerrln("Error creating DecimalFormat: %s", u_errorName(status));
   1616       delete nf;
   1617       return;
   1618     }
   1619     failure(status, "NumberFormat::createInstance");
   1620     nf->setMaximumIntegerDigits(MAX_INT_DIGITS);
   1621     logln("setMaximumIntegerDigits(MAX_INT_DIGITS)");
   1622     if (nf->getMaximumIntegerDigits() != MAX_INT_DIGITS)
   1623         errln(UnicodeString("getMaximumIntegerDigits() returns ") +
   1624             nf->getMaximumIntegerDigits());
   1625 
   1626     delete nf;
   1627 }
   1628 
   1629 /* @bug 4122840
   1630  * Locale data should use generic currency symbol
   1631  *
   1632  * 1) Make sure that all currency formats use the generic currency symbol.
   1633  * 2) Make sure we get the same results using the generic symbol or a
   1634  *    hard-coded one.
   1635  */
   1636 void NumberFormatRegressionTest::Test4122840(void)
   1637 {
   1638     int32_t count = 0;
   1639     const Locale *locales = Locale::getAvailableLocales(count);
   1640 
   1641     for (int i = 0; i < count; i++) {
   1642         UErrorCode status = U_ZERO_ERROR;
   1643         ResourceBundle *rb = new ResourceBundle(
   1644             NULL/*"java.text.resources.LocaleElements"*/,
   1645             locales[i], status);
   1646         failure(status, "new ResourceBundle");
   1647         ResourceBundle numPat = rb->getWithFallback("NumberElements", status);
   1648         failure(status, "rb.get(NumberElements)");
   1649         numPat = numPat.getWithFallback("latn",status);
   1650         failure(status, "rb.get(latn)");
   1651         numPat = numPat.getWithFallback("patterns",status);
   1652         failure(status, "rb.get(patterns)");
   1653         numPat = numPat.getWithFallback("currencyFormat",status);
   1654         failure(status, "rb.get(currencyFormat)");
   1655        //
   1656         // Get the currency pattern for this locale.  We have to fish it
   1657         // out of the ResourceBundle directly, since DecimalFormat.toPattern
   1658         // will return the localized symbol, not \00a4
   1659         //
   1660         UnicodeString pattern = numPat.getString(status);
   1661         failure(status, "rb->getString()");
   1662 
   1663         UChar fo[] = { 0x00A4 };
   1664         UnicodeString foo(fo, 1, 1);
   1665 
   1666         //if (pattern.indexOf("\u00A4") == -1 ) {
   1667         if (pattern.indexOf(foo) == -1 ) {
   1668             errln(UnicodeString("Currency format for ") + UnicodeString(locales[i].getName()) +
   1669                     " does not contain generic currency symbol:" +
   1670                     pattern );
   1671         }
   1672 
   1673         // Create a DecimalFormat using the pattern we got and format a number
   1674         DecimalFormatSymbols *symbols = new DecimalFormatSymbols(locales[i], status);
   1675         failure(status, "new DecimalFormatSymbols");
   1676         DecimalFormat *fmt1 = new DecimalFormat(pattern, *symbols, status);
   1677         failure(status, "new DecimalFormat");
   1678 
   1679         UnicodeString result1;
   1680         FieldPosition pos(FieldPosition::DONT_CARE);
   1681         result1 = fmt1->format(1.111, result1, pos);
   1682 
   1683         //
   1684         // Now substitute in the locale's currency symbol and create another
   1685         // pattern.  We have to skip locales where the currency symbol
   1686         // contains decimal separators, because that confuses things
   1687         //
   1688         UChar ba[] = { 0x002E/*'.'*/ };
   1689         UnicodeString bar(ba, 1, 1);
   1690 
   1691         if (symbols->getSymbol(DecimalFormatSymbols::kCurrencySymbol).indexOf(bar) == -1) {
   1692             // {sfb} Also, switch the decimal separator to the monetary decimal
   1693             // separator to mimic the behavior of a currency format
   1694             symbols->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol,
   1695                 symbols->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol));
   1696 
   1697             UnicodeString buf(pattern);
   1698             for (int j = 0; j < buf.length(); j++) {
   1699                 if (buf[j] == 0x00a4 ) {
   1700                     if(buf[j + 1] == 0x00a4) {
   1701                         // {sfb} added to support double currency marker (intl currency sign)
   1702                         buf.replace(j, /*j+*/2, symbols->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol));
   1703                         j += symbols->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol).length();
   1704                     }
   1705                     else {
   1706                         buf.replace(j, /*j+*/1, symbols->getSymbol(DecimalFormatSymbols::kCurrencySymbol));
   1707                         j += symbols->getSymbol(DecimalFormatSymbols::kCurrencySymbol).length() - 1;
   1708                     }
   1709                 }
   1710             }
   1711 
   1712             DecimalFormat *fmt2 = new DecimalFormat(buf, *symbols, status);
   1713             failure(status, "new DecimalFormat");
   1714 
   1715             // Get the currency (if there is one) so we can set the rounding and fraction
   1716             const UChar *currency = fmt1->getCurrency();
   1717             if (*currency != 0) {
   1718                 double rounding = ucurr_getRoundingIncrement(currency, &status);
   1719                 int32_t frac = ucurr_getDefaultFractionDigits(currency, &status);
   1720                 if (U_SUCCESS(status)) {
   1721                     fmt2->setRoundingIncrement(rounding);
   1722                     fmt2->setMinimumFractionDigits(frac);
   1723                     fmt2->setMaximumFractionDigits(frac);
   1724                 }
   1725                 else {
   1726                     failure(status, "Fetching currency rounding/fractions");
   1727                 }
   1728             }
   1729 
   1730             UnicodeString result2;
   1731             fmt2->format(1.111, result2, pos);
   1732 
   1733             if (result1 != result2) {
   1734                 errln("Results for " + (UnicodeString)(locales[i].getName()) + " differ: " +
   1735                         result1 + " vs " + result2);
   1736             }
   1737 
   1738             delete fmt2;
   1739         }
   1740 
   1741         delete rb;
   1742         delete fmt1;
   1743         delete symbols;
   1744     }
   1745 }
   1746 
   1747 /* @bug 4125885
   1748  * DecimalFormat.format() delivers wrong string.
   1749  */
   1750 void NumberFormatRegressionTest::Test4125885(void)
   1751 {
   1752     UErrorCode status = U_ZERO_ERROR;
   1753     double rate = 12.34;
   1754     DecimalFormat *formatDec = new DecimalFormat ("000.00", status);
   1755     if(U_FAILURE(status)) {
   1756       errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
   1757       delete formatDec;
   1758       return;
   1759     }
   1760     failure(status, "new DecimalFormat");
   1761     UnicodeString temp;
   1762     logln("toPattern: " + formatDec->toPattern(temp));
   1763     UnicodeString rateString;
   1764     FieldPosition pos(FieldPosition::DONT_CARE);
   1765     rateString = formatDec->format(rate, rateString, pos);
   1766     if (rateString != UnicodeString("012.34"))
   1767         errln("result : " + rateString + " expected : 012.34");
   1768     rate = 0.1234;
   1769     delete formatDec;// = null;
   1770     formatDec = new DecimalFormat ("+000.00%;-000.00%", status);
   1771     failure(status, "new DecimalFormat");
   1772     logln("toPattern: " + formatDec->toPattern(temp));
   1773     rateString.remove();
   1774     rateString = formatDec->format(rate, rateString, pos);
   1775     if (rateString != UnicodeString("+012.34%"))
   1776         errln("result : " + rateString + " expected : +012.34%");
   1777 
   1778     delete formatDec;
   1779 }
   1780 
   1781 /**
   1782  * @bug 4134034
   1783  * DecimalFormat produces extra zeros when formatting numbers.
   1784  */
   1785 void NumberFormatRegressionTest::Test4134034(void)
   1786 {
   1787     UErrorCode status = U_ZERO_ERROR;
   1788     DecimalFormat *nf = new DecimalFormat("##,###,###.00", status);
   1789     if (!failure(status, "new DecimalFormat")) {
   1790         UnicodeString f;
   1791         FieldPosition pos(FieldPosition::DONT_CARE);
   1792         f = nf->format(9.02, f, pos);
   1793         if (f == UnicodeString("9.02"))
   1794             logln(f + " ok");
   1795         else
   1796             errln("9.02 -> " + f + "; want 9.02");
   1797 
   1798         f.remove();
   1799         f = nf->format((int32_t)0, f, pos);
   1800         if (f == UnicodeString(".00"))
   1801             logln(f + " ok");
   1802         else
   1803             errln("0 -> " + f + "; want .00");
   1804     }
   1805 
   1806     delete nf;
   1807 }
   1808 
   1809 /**
   1810  * @bug 4134300
   1811  * CANNOT REPRODUCE - This bug could not be reproduced.  It may be
   1812  * a duplicate of 4134034.
   1813  *
   1814  * JDK 1.1.6 Bug, did NOT occur in 1.1.5
   1815  * Possibly related to bug 4125885.
   1816  *
   1817  * This class demonstrates a regression in version 1.1.6
   1818  * of DecimalFormat class.
   1819  *
   1820  * 1.1.6 Results
   1821  * Value 1.2 Format #.00 Result '01.20' !!!wrong
   1822  * Value 1.2 Format 0.00 Result '001.20' !!!wrong
   1823  * Value 1.2 Format 00.00 Result '0001.20' !!!wrong
   1824  * Value 1.2 Format #0.0# Result '1.2'
   1825  * Value 1.2 Format #0.00 Result '001.20' !!!wrong
   1826  *
   1827  * 1.1.5 Results
   1828  * Value 1.2 Format #.00 Result '1.20'
   1829  * Value 1.2 Format 0.00 Result '1.20'
   1830  * Value 1.2 Format 00.00 Result '01.20'
   1831  * Value 1.2 Format #0.0# Result '1.2'
   1832  * Value 1.2 Format #0.00 Result '1.20'
   1833  */
   1834 void NumberFormatRegressionTest::Test4134300(void) {
   1835     UnicodeString DATA [] = {
   1836      // Pattern      Expected string
   1837         UnicodeString("#.00"),      UnicodeString("1.20"),
   1838         UnicodeString("0.00"),      UnicodeString("1.20"),
   1839         UnicodeString("00.00"),     UnicodeString("01.20"),
   1840         UnicodeString("#0.0#"),     UnicodeString("1.2"),
   1841         UnicodeString("#0.00"),     UnicodeString("1.20")
   1842     };
   1843 
   1844     for (int i=0; i< 10; i+=2) {
   1845         UnicodeString result;
   1846         UErrorCode status = U_ZERO_ERROR;
   1847         DecimalFormat *df = new DecimalFormat(DATA[i], status);
   1848         if (!failure(status, "new DecimalFormat")) {
   1849             FieldPosition pos(FieldPosition::DONT_CARE);
   1850             result = df->format(1.2, result, pos);
   1851             if (result != DATA[i+1]) {
   1852                 errln("Fail: 1.2 x " + DATA[i] + " = " + result +
   1853                       "; want " + DATA[i+1]);
   1854             }
   1855             else {
   1856                 logln("Ok: 1.2 x " + DATA[i] + " = " + result);
   1857             }
   1858         }
   1859 
   1860         delete df;
   1861     }
   1862 }
   1863 
   1864 /**
   1865  * @bug 4140009
   1866  * Empty pattern produces double negative prefix.
   1867  */
   1868 void NumberFormatRegressionTest::Test4140009(void)
   1869 {
   1870     UErrorCode status = U_ZERO_ERROR;
   1871     DecimalFormatSymbols *syms = new DecimalFormatSymbols(Locale::getEnglish(), status);
   1872     failure(status, "new DecimalFormatSymbols");
   1873     DecimalFormat *f = new DecimalFormat(UnicodeString(""), syms, status);
   1874     if (!failure(status, "new DecimalFormat")) {
   1875         UnicodeString s;
   1876         FieldPosition pos(FieldPosition::DONT_CARE);
   1877         s = f->format(123.456, s, pos);
   1878         if (s != UnicodeString("123.456"))
   1879             errln("Fail: Format empty pattern x 123.456 => " + s);
   1880         s.remove();
   1881         s = f->format(-123.456, s, pos);
   1882         if (s != UnicodeString("-123.456"))
   1883             errln("Fail: Format empty pattern x -123.456 => " + s);
   1884     }
   1885     delete f;
   1886 }
   1887 
   1888 /**
   1889  * @bug 4141750
   1890  * BigDecimal numbers get their fractions truncated by NumberFormat.
   1891  */
   1892 // {sfb} not pertinent in C++ ??
   1893 void NumberFormatRegressionTest::Test4141750(void) {
   1894     /*try {
   1895         UnicodeString str("12345.67");
   1896         BigDecimal bd = new BigDecimal(str);
   1897         String sd = NumberFormat.getInstance(Locale.US).format(bd);
   1898         if (!sd.endsWith("67")) errln("Fail: " + str + " x format -> " + sd);
   1899     }
   1900     catch (Exception e) {
   1901         errln(e.toString());
   1902         e.printStackTrace();
   1903     }*/
   1904 }
   1905 
   1906 /**
   1907  * @bug 4145457
   1908  * DecimalFormat toPattern() doesn't quote special characters or handle
   1909  * single quotes.
   1910  */
   1911 void NumberFormatRegressionTest::Test4145457() {
   1912     //try {
   1913     UErrorCode status = U_ZERO_ERROR;
   1914     NumberFormat *nff = NumberFormat::createInstance(status);
   1915     if (failure(status, "NumberFormat::createInstance", TRUE)){
   1916         delete nff;
   1917         return;
   1918     };
   1919     DecimalFormat *nf = dynamic_cast<DecimalFormat *>(nff);
   1920     if(nf == NULL) {
   1921         errln("DecimalFormat needed to continue");
   1922         return;
   1923     }
   1924 
   1925     DecimalFormatSymbols *sym = (DecimalFormatSymbols*) nf->getDecimalFormatSymbols();
   1926     sym->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, (UChar)/*'\''*/0x0027);
   1927     nf->setDecimalFormatSymbols(*sym);
   1928     double pi = 3.14159;
   1929 
   1930     UnicodeString PATS [] = {
   1931         UnicodeString("#.00 'num''ber'"), UnicodeString("''#.00''")
   1932     };
   1933 
   1934     for (int32_t i=0; i<2; ++i) {
   1935         nf->applyPattern(PATS[i], status);
   1936         failure(status, "nf->applyPattern");
   1937         UnicodeString out;
   1938         FieldPosition pos(FieldPosition::DONT_CARE);
   1939         out = nf->format(pi, out, pos);
   1940         UnicodeString pat;
   1941         pat = nf->toPattern(pat);
   1942         Formattable num;
   1943         ParsePosition pp(0);
   1944         nf->parse(out, num, pp);
   1945         double val = num.getDouble();
   1946 
   1947         nf->applyPattern(pat, status);
   1948         failure(status, "nf->applyPattern");
   1949         UnicodeString out2;
   1950         out2 = nf->format(pi, out2, pos);
   1951         UnicodeString pat2;
   1952         pat2 = nf->toPattern(pat2);
   1953         pp.setIndex(0);
   1954         nf->parse(out2, num, pp);
   1955         double val2 = num.getDouble();
   1956 
   1957         if (pat != pat2)
   1958             errln("Fail with \"" + PATS[i] + "\": Patterns should concur, \"" +
   1959                 pat + "\" vs. \"" + pat2 + "\"");
   1960         else
   1961             logln("Ok \"" + PATS[i] + "\" toPattern() -> \"" + pat + '"');
   1962 
   1963         if (val == val2 && out == out2) {
   1964             logln(UnicodeString("Ok ") + pi + " x \"" + PATS[i] + "\" -> \"" +
   1965                 out + "\" -> " + val + " -> \"" +
   1966                 out2 + "\" -> " + val2);
   1967         }
   1968         else {
   1969             errln(UnicodeString("Fail ") + pi + " x \"" + PATS[i] + "\" -> \"" +
   1970                 out + "\" -> " + val + " -> \"" +
   1971                 out2 + "\" -> " + val2);
   1972         }
   1973     }
   1974     /*}
   1975     catch (ParseException e) {
   1976         errln("Fail: " + e);
   1977         e.printStackTrace();
   1978     }*/
   1979 
   1980     delete nff;
   1981 }
   1982 
   1983 /**
   1984  * @bug 4147295
   1985  * DecimalFormat.applyPattern() sets minimum integer digits incorrectly.
   1986  * CANNOT REPRODUCE
   1987  * This bug is a duplicate of 4139344, which is a duplicate of 4134300
   1988  */
   1989 void NumberFormatRegressionTest::Test4147295(void)
   1990 {
   1991     UErrorCode status = U_ZERO_ERROR;
   1992     DecimalFormat *sdf = new DecimalFormat(status);
   1993     UnicodeString pattern("#,###");
   1994     logln("Applying pattern \"" + pattern + "\"");
   1995     sdf->applyPattern(pattern, status);
   1996     if (!failure(status, "sdf->applyPattern")) {
   1997         int minIntDig = sdf->getMinimumIntegerDigits();
   1998         if (minIntDig != 0) {
   1999             errln("Test failed");
   2000             errln(UnicodeString(" Minimum integer digits : ") + minIntDig);
   2001             UnicodeString temp;
   2002             errln(UnicodeString(" new pattern: ") + sdf->toPattern(temp));
   2003         } else {
   2004             logln("Test passed");
   2005             logln(UnicodeString(" Minimum integer digits : ") + minIntDig);
   2006         }
   2007     }
   2008     delete sdf;
   2009 }
   2010 
   2011 /**
   2012  * @bug 4147706
   2013  * DecimalFormat formats -0.0 as +0.0
   2014  * See also older related bug 4106658, 4106667
   2015  */
   2016 void NumberFormatRegressionTest::Test4147706(void)
   2017 {
   2018     UErrorCode status = U_ZERO_ERROR;
   2019     DecimalFormat *df = new DecimalFormat("#,##0.0##", status);
   2020     failure(status, "new DecimalFormat");
   2021     DecimalFormatSymbols *syms = new DecimalFormatSymbols(Locale::getEnglish(), status);
   2022     if (!failure(status, "new DecimalFormatSymbols")) {
   2023         UnicodeString f1;
   2024         UnicodeString f2, temp;
   2025         FieldPosition pos(FieldPosition::DONT_CARE);
   2026         volatile double d1 = 0.0;   // volatile to prevent code optimization
   2027         double d2 = -0.0001;
   2028 
   2029 #if U_PLATFORM == U_PF_HPUX
   2030         d1 = 0.0 * -1.0;    // old HPUX compiler ignores volatile keyword
   2031 #else
   2032         d1 *= -1.0; // Some compilers have a problem with defining -0.0
   2033 #endif
   2034         df->adoptDecimalFormatSymbols(syms);
   2035         f1 = df->format(d1, f1, pos);
   2036         f2 = df->format(d2, f2, pos);
   2037         if (f1 != UnicodeString("-0.0")) {
   2038             errln(UnicodeString("") + d1 + UnicodeString(" x \"") + df->toPattern(temp) + "\" is formatted as \"" + f1 + '"');
   2039         }
   2040         if (f2 != UnicodeString("-0.0")) {
   2041             errln(UnicodeString("") + d2 + UnicodeString(" x \"") + df->toPattern(temp) + "\" is formatted as \"" + f2 + '"');
   2042         }
   2043     }
   2044 
   2045     delete df;
   2046 }
   2047 
   2048 
   2049 // Not applicable, since no serialization in C++
   2050 /*class myformat implements Serializable
   2051 {
   2052 DateFormat _dateFormat = DateFormat.getDateInstance();
   2053 
   2054 public String Now()
   2055 {
   2056     GregorianCalendar calendar = new GregorianCalendar();
   2057     Date t = calendar.getTime();
   2058     String nowStr = _dateFormat.format(t);
   2059     return nowStr;
   2060 }
   2061 }*/
   2062 
   2063 /**
   2064  * @bug 4162198
   2065  * NumberFormat cannot format Double.MAX_VALUE
   2066  */
   2067 // TODO: make this test actually test something
   2068 void
   2069 NumberFormatRegressionTest::Test4162198(void)
   2070 {
   2071     // for some reason, DBL_MAX will not round trip. (bug in sprintf/atof)
   2072     double dbl = INT32_MAX * 1000.0;
   2073     UErrorCode status = U_ZERO_ERROR;
   2074     NumberFormat *f = NumberFormat::createInstance(status);
   2075     if(U_FAILURE(status)) {
   2076         dataerrln("Couldn't create number format - %s", u_errorName(status));
   2077         return;
   2078     }
   2079     f->setMaximumFractionDigits(INT32_MAX);
   2080     f->setMaximumIntegerDigits(INT32_MAX);
   2081     UnicodeString s;
   2082     f->format(dbl,s);
   2083     logln(UnicodeString("The number ") + dbl + " formatted to " + s);
   2084     Formattable n;
   2085     //try {
   2086     f->parse(s, n, status);
   2087     if(U_FAILURE(status))
   2088         errln("Couldn't parse!");
   2089     //} catch (java.text.ParseException e) {
   2090     //    errln("Caught a ParseException:");
   2091     //    e.printStackTrace();
   2092     //}
   2093 
   2094     //logln("The string " + s + " parsed as " + n);
   2095 
   2096     // {dlf} The old code assumes n is a double, but it isn't any more...
   2097     // Formattable apparently does not and never did interconvert... too bad.
   2098     //if(n.getDouble() != dbl) {
   2099     //    errln("Round trip failure");
   2100     //}
   2101     if (n.getInt64() != dbl) {
   2102         errln("Round trip failure");
   2103     }
   2104 
   2105     delete f;
   2106 }
   2107 
   2108 /**
   2109  * @bug 4162852
   2110  * NumberFormat does not parse negative zero.
   2111  */
   2112 void
   2113 NumberFormatRegressionTest::Test4162852(void)
   2114 {
   2115     UErrorCode status = U_ZERO_ERROR;
   2116     for(int32_t i=0; i < 2; ++i) {
   2117         NumberFormat *f = (i == 0) ? NumberFormat::createInstance(status)
   2118             : NumberFormat::createPercentInstance(status);
   2119         if(U_FAILURE(status)) {
   2120             dataerrln("Couldn't create number format - %s", u_errorName(status));
   2121             return;
   2122         }
   2123         double d = 0.0;
   2124         d *= -1.0;
   2125         UnicodeString s;
   2126         f->format(d, s);
   2127         Formattable n;
   2128         f->parse(s, n, status);
   2129         if(U_FAILURE(status))
   2130             errln("Couldn't parse!");
   2131         double e = n.getDouble();
   2132         logln(UnicodeString("") +
   2133               d + " -> " +
   2134               '"' + s + '"' + " -> " + e);
   2135 #if (U_PLATFORM == U_PF_OS390 && !defined(IEEE_754)) || U_PLATFORM == U_PF_OS400
   2136         if (e != 0.0) {
   2137 #else
   2138         if (e != 0.0 || 1.0/e > 0.0) {
   2139 #endif
   2140             logln("Failed to parse negative zero");
   2141         }
   2142         delete f;
   2143     }
   2144 }
   2145 
   2146 static double _u_abs(double a) { return a<0?-a:a; }
   2147 
   2148 /**
   2149  * May 17 1999 sync up - liu
   2150  * @bug 4167494
   2151  * NumberFormat truncates data
   2152  */
   2153 void NumberFormatRegressionTest::Test4167494(void) {
   2154     UErrorCode status = U_ZERO_ERROR;
   2155     NumberFormat *fmt = NumberFormat::createInstance(Locale::getUS(), status);
   2156     if (failure(status, "NumberFormat::createInstance", TRUE)){
   2157         delete fmt;
   2158         return;
   2159     };
   2160 
   2161     double a = DBL_MAX * 0.99; // DBL_MAX itself overflows to +Inf
   2162     UnicodeString s;
   2163     fmt->format(a, s);
   2164     Formattable num;
   2165     fmt->parse(s, num, status);
   2166     failure(status, "Parse");
   2167     if (num.getType() == Formattable::kDouble &&
   2168         _u_abs(num.getDouble() - a) / a < 0.01) { // RT within 1%
   2169         logln(UnicodeString("") + a + " -> \"" + s + "\" -> " +
   2170               toString(num) + " ok");
   2171     } else {
   2172         errln(UnicodeString("") + a + " -> \"" + s + "\" -> " +
   2173               toString(num) + " FAIL");
   2174     }
   2175 
   2176     // We don't test Double.MIN_VALUE because the locale data for the US
   2177     // currently doesn't specify enough digits to display Double.MIN_VALUE.
   2178     // This is correct for now; however, we leave this here as a reminder
   2179     // in case we want to address this later.
   2180 
   2181     delete fmt;
   2182 }
   2183 
   2184 /**
   2185  * May 17 1999 sync up - liu
   2186  * @bug 4170798
   2187  * DecimalFormat.parse() fails when ParseIntegerOnly set to true
   2188  */
   2189 void NumberFormatRegressionTest::Test4170798(void) {
   2190     UErrorCode status = U_ZERO_ERROR;
   2191     NumberFormat *nf = NumberFormat::createInstance(Locale::getUS(), status);
   2192     if (failure(status, "NumberFormat::createInstance", TRUE)){
   2193         delete nf;
   2194         return;
   2195     };
   2196     DecimalFormat *df = dynamic_cast<DecimalFormat *>(nf);
   2197     if(df == NULL) {
   2198         errln("DecimalFormat needed to continue");
   2199         return;
   2200     }
   2201     df->setParseIntegerOnly(TRUE);
   2202     Formattable n;
   2203     ParsePosition pos(0);
   2204     df->parse("-0.0", n, pos);
   2205     if (n.getType() != Formattable::kLong
   2206         || n.getLong() != 0) {
   2207         errln(UnicodeString("FAIL: parse(\"-0.0\") returns ") + toString(n));
   2208     }
   2209     delete nf;
   2210 }
   2211 
   2212 /**
   2213  * May 17 1999 sync up - liu
   2214  * toPattern only puts the first grouping separator in.
   2215  */
   2216 void NumberFormatRegressionTest::Test4176114(void) {
   2217     const char* DATA[] = {
   2218         "00", "#00",
   2219         "000", "#000", // No grouping
   2220         "#000", "#000", // No grouping
   2221         "#,##0", "#,##0",
   2222         "#,000", "#,000",
   2223         "0,000", "#0,000",
   2224         "00,000", "#00,000",
   2225         "000,000", "#,000,000",
   2226         "0,000,000,000,000.0000", "#0,000,000,000,000.0000", // Reported
   2227     };
   2228     int DATA_length = (int)(sizeof(DATA) / sizeof(DATA[0]));
   2229     UErrorCode status = U_ZERO_ERROR;
   2230     UnicodeString s;
   2231     for (int i=0; i<DATA_length; i+=2) {
   2232         DecimalFormat df(DATA[i], status);
   2233         if (!failure(status, "DecimalFormat constructor")) {
   2234             df.toPattern(s);
   2235             UnicodeString exp(DATA[i+1]);
   2236             if (s != exp) {
   2237                 errln(UnicodeString("FAIL: ") + DATA[i] + " -> " +
   2238                       s + ", want " + exp);
   2239             }
   2240         }
   2241     }
   2242 }
   2243 
   2244 /**
   2245  * May 17 1999 sync up - liu
   2246  * @bug 4179818
   2247  * DecimalFormat is incorrectly rounding numbers like 1.2501 to 1.2
   2248  */
   2249 void NumberFormatRegressionTest::Test4179818(void) {
   2250     const char* DATA[] = {
   2251         // Input  Pattern  Expected output
   2252         "1.2511", "#.#",   "1.3",
   2253         "1.2501", "#.#",   "1.3",
   2254         "0.9999", "#",     "1",
   2255     };
   2256     int DATA_length = (int)(sizeof(DATA) / sizeof(DATA[0]));
   2257     double DOUBLE[] = {
   2258         1.2511,
   2259         1.2501,
   2260         0.9999,
   2261     };
   2262     UErrorCode status = U_ZERO_ERROR;
   2263     DecimalFormatSymbols sym(Locale::getUS(), status);
   2264     failure(status, "Construct DecimalFormatSymbols");
   2265     DecimalFormat fmt("#", sym, status);
   2266     if (!failure(status, "Construct DecimalFormat")) {
   2267         for (int i=0; i<DATA_length; i+=3) {
   2268             double in = DOUBLE[i/3];
   2269             UnicodeString pat(DATA[i+1]);
   2270             UnicodeString exp(DATA[i+2]);
   2271             fmt.applyPattern(pat, status);
   2272             failure(status, "applyPattern");
   2273             UnicodeString out;
   2274             FieldPosition pos;
   2275             fmt.format(in, out, pos);
   2276             if (out == exp) {
   2277                 logln(UnicodeString("Ok: ") + in + " x " + pat + " = " + out);
   2278             } else {
   2279                 errln(UnicodeString("FAIL: ") + in + " x  " + pat + " = " + out +
   2280                       ", expected " + exp);
   2281             }
   2282         }
   2283     }
   2284 }
   2285 
   2286 /**
   2287  * May 17 1999 sync up - liu
   2288  * Some DecimalFormatSymbols changes are not picked up by DecimalFormat.
   2289  * This includes the minus sign, currency symbol, international currency
   2290  * symbol, percent, and permille.  This is filed as bugs 4212072 and
   2291  * 4212073.
   2292  */
   2293 void NumberFormatRegressionTest::Test4212072(void) {
   2294     UErrorCode status = U_ZERO_ERROR;
   2295     DecimalFormatSymbols sym(Locale::getUS(), status);
   2296 
   2297     failure(status, "DecimalFormatSymbols ct", Locale::getUS());
   2298     DecimalFormat fmt(UnicodeString("#"), sym, status);
   2299     if(failure(status, "DecimalFormat ct", Locale::getUS())) {
   2300         return;
   2301     }
   2302 
   2303     UnicodeString s;
   2304     FieldPosition pos;
   2305 
   2306     sym.setSymbol(DecimalFormatSymbols::kMinusSignSymbol, (UChar)0x5e);
   2307     fmt.setDecimalFormatSymbols(sym);
   2308     s.remove();
   2309     if (fmt.format((int32_t)-1, s, pos) != UNICODE_STRING("^1", 2)) {
   2310         errln(UnicodeString("FAIL: -1 x (minus=^) -> ") + s +
   2311               ", exp ^1");
   2312     }
   2313     s.remove();
   2314     if (fmt.getNegativePrefix(s) != UnicodeString((UChar)0x5e)) {
   2315         errln(UnicodeString("FAIL: (minus=^).getNegativePrefix -> ") +
   2316               s + ", exp ^");
   2317     }
   2318     sym.setSymbol(DecimalFormatSymbols::kMinusSignSymbol, (UChar)0x2d);
   2319 
   2320     fmt.applyPattern(UnicodeString("#%"), status);
   2321     failure(status, "applyPattern percent");
   2322     sym.setSymbol(DecimalFormatSymbols::kPercentSymbol, (UChar)0x5e);
   2323     fmt.setDecimalFormatSymbols(sym);
   2324     s.remove();
   2325     if (fmt.format(0.25, s, pos) != UNICODE_STRING("25^", 3)) {
   2326         errln(UnicodeString("FAIL: 0.25 x (percent=^) -> ") + s +
   2327               ", exp 25^");
   2328     }
   2329     s.remove();
   2330     if (fmt.getPositiveSuffix(s) != UnicodeString((UChar)0x5e)) {
   2331         errln(UnicodeString("FAIL: (percent=^).getPositiveSuffix -> ") +
   2332               s + ", exp ^");
   2333     }
   2334     sym.setSymbol(DecimalFormatSymbols::kPercentSymbol, (UChar)0x25);
   2335 
   2336     fmt.applyPattern(str("#\\u2030"), status);
   2337     failure(status, "applyPattern permill");
   2338     sym.setSymbol(DecimalFormatSymbols::kPerMillSymbol, (UChar)0x5e);
   2339     fmt.setDecimalFormatSymbols(sym);
   2340     s.remove();
   2341     if (fmt.format(0.25, s, pos) != UNICODE_STRING("250^", 4)) {
   2342         errln(UnicodeString("FAIL: 0.25 x (permill=^) -> ") + s +
   2343               ", exp 250^");
   2344     }
   2345     s.remove();
   2346     if (fmt.getPositiveSuffix(s) != UnicodeString((UChar)0x5e)) {
   2347         errln(UnicodeString("FAIL: (permill=^).getPositiveSuffix -> ") +
   2348               s + ", exp ^");
   2349     }
   2350     sym.setSymbol(DecimalFormatSymbols::kPerMillSymbol, (UChar)0x2030);
   2351 
   2352     fmt.applyPattern(str("\\u00A4#.00"), status);
   2353     failure(status, "applyPattern currency");
   2354     sym.setSymbol(DecimalFormatSymbols::kCurrencySymbol, "usd");
   2355     fmt.setDecimalFormatSymbols(sym);
   2356     s.remove();
   2357     if (fmt.format(12.5, s, pos) != UnicodeString("usd12.50")) {
   2358         errln(UnicodeString("FAIL: 12.5 x (currency=usd) -> ") + s +
   2359               ", exp usd12.50");
   2360     }
   2361     s.remove();
   2362     if (fmt.getPositivePrefix(s) != UnicodeString("usd")) {
   2363         errln(UnicodeString("FAIL: (currency=usd).getPositivePrefix -> ") +
   2364               s + ", exp usd");
   2365     }
   2366     sym.setSymbol(DecimalFormatSymbols::kCurrencySymbol, "$");
   2367 
   2368     fmt.applyPattern(str("\\u00A4\\u00A4#.00"), status);
   2369     failure(status, "applyPattern intl currency");
   2370     sym.setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol, "DOL");
   2371     fmt.setDecimalFormatSymbols(sym);
   2372     s.remove();
   2373     if (fmt.format(12.5, s, pos) != UnicodeString("DOL12.50")) {
   2374         errln(UnicodeString("FAIL: 12.5 x (intlcurrency=DOL) -> ") + s +
   2375               ", exp DOL12.50");
   2376     }
   2377     s.remove();
   2378     if (fmt.getPositivePrefix(s) != UnicodeString("DOL")) {
   2379         errln(UnicodeString("FAIL: (intlcurrency=DOL).getPositivePrefix -> ") +
   2380               s + ", exp DOL");
   2381     }
   2382     sym.setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol, "USD");
   2383 
   2384     // Since the pattern logic has changed, make sure that patterns round
   2385     // trip properly.  Test stream in/out integrity too.
   2386     int32_t n;
   2387     const Locale* avail = NumberFormat::getAvailableLocales(n);
   2388     static const char* type[] = {
   2389         "",
   2390         "$ ",
   2391         "% ",
   2392     };
   2393     for (int i=0; i<n; ++i) {
   2394         for (int j=0; j<3; ++j) {
   2395             status = U_ZERO_ERROR;
   2396             NumberFormat *nf;
   2397             switch (j) {
   2398             case 0:
   2399                 nf = NumberFormat::createInstance(avail[i], status);
   2400                 failure(status, "createInstance", avail[i]);
   2401                 break;
   2402             case 1:
   2403                 nf = NumberFormat::createCurrencyInstance(avail[i], status);
   2404                 failure(status, "createCurrencyInstance", avail[i]);
   2405                 break;
   2406             default:
   2407                 nf = NumberFormat::createPercentInstance(avail[i], status);
   2408                 failure(status, "createPercentInstance", avail[i]);
   2409                 break;
   2410             }
   2411             if (U_FAILURE(status)) {
   2412                 continue;
   2413             }
   2414             DecimalFormat *df = (DecimalFormat*) nf;
   2415 
   2416             // Test toPattern/applyPattern round trip
   2417             UnicodeString pat;
   2418             df->toPattern(pat);
   2419             DecimalFormatSymbols symb(avail[i], status);
   2420             failure(status, "Construct DecimalFormatSymbols", avail[i]);
   2421             DecimalFormat f2(pat, symb, status);
   2422             if (failure(status,
   2423                         UnicodeString("Construct DecimalFormat(") + pat + ")")) {
   2424                 continue;
   2425             }
   2426             if (*df != f2) {
   2427                 UnicodeString l, p;
   2428                 errln(UnicodeString("FAIL: ") + type[j] + avail[i].getDisplayName(l) +
   2429                       " -> \"" + pat +
   2430                       "\" -> \"" + f2.toPattern(p) + "\"");
   2431             } else {
   2432                 UnicodeString l, p;
   2433                 logln(UnicodeString("PASS: ") + type[j] + avail[i].getDisplayName(l) +
   2434                       " -> \"" + pat +
   2435                       "\"");
   2436             }
   2437 
   2438             // Test toLocalizedPattern/applyLocalizedPattern round trip
   2439             df->toLocalizedPattern(pat);
   2440             f2.applyLocalizedPattern(pat, status);
   2441             failure(status,
   2442                     UnicodeString("applyLocalizedPattern(") + pat + ")", avail[i]);
   2443             if (U_FAILURE(status)) {
   2444                 continue;
   2445             }
   2446 
   2447             // Make sure we set the currency attributes appropriately
   2448             if (j == 1) {   // Currency format
   2449                 f2.setCurrency(f2.getCurrency(), status);
   2450             }
   2451             failure(status,
   2452                     UnicodeString("setCurrency() for (") + pat + ")", avail[i]);
   2453             if (U_FAILURE(status)) {
   2454                 continue;
   2455             }
   2456 
   2457             if (*df != f2) {
   2458                 UnicodeString l, p;
   2459                 errln(UnicodeString("FAIL: ") + type[j] + avail[i].getDisplayName(l) +
   2460                       " -> localized \"" + pat +
   2461                       "\" -> \"" + f2.toPattern(p) + "\"");
   2462             }
   2463 
   2464             delete nf;
   2465 
   2466             // Test writeObject/readObject round trip
   2467             // NOT ON ICU -- Java only
   2468         }
   2469     }
   2470 }
   2471 
   2472 /**
   2473  * May 17 1999 sync up - liu
   2474  * DecimalFormat.parse() fails for mulipliers 2^n.
   2475  */
   2476 void NumberFormatRegressionTest::Test4216742(void) {
   2477     UErrorCode status = U_ZERO_ERROR;
   2478     DecimalFormat *fmt = (DecimalFormat*) NumberFormat::createInstance(Locale::getUS(), status);
   2479     if (failure(status, "createInstance", Locale::getUS(), TRUE)){
   2480         delete fmt;
   2481         return;
   2482     };
   2483     int32_t DATA[] = { INT32_MIN, INT32_MAX, -100000000, 100000000 };
   2484     int DATA_length = (int)(sizeof(DATA) / sizeof(DATA[0]));
   2485     for (int i=0; i<DATA_length; ++i) {
   2486         UnicodeString str((UnicodeString)"" + DATA[i]);
   2487         for (int m = 1; m <= 100; m++) {
   2488             fmt->setMultiplier(m);
   2489             Formattable num;
   2490             fmt->parse(str, num, status);
   2491             failure(status, "parse", Locale::getUS());
   2492             if (num.getType() != Formattable::kLong &&
   2493                 num.getType() != Formattable::kDouble) {
   2494                 errln(UnicodeString("FAIL: Wanted number, got ") +
   2495                       toString(num));
   2496             } else {
   2497                 double d = num.getType() == Formattable::kDouble ?
   2498                     num.getDouble() : (double) num.getLong();
   2499                 if ((d > 0) != (DATA[i] > 0)) {
   2500                     errln(UnicodeString("\"") + str + "\" parse(x " +
   2501                           fmt->getMultiplier() +
   2502                           ") => " + toString(num));
   2503                 }
   2504             }
   2505         }
   2506     }
   2507     delete fmt;
   2508 }
   2509 
   2510 /**
   2511  * May 17 1999 sync up - liu
   2512  * DecimalFormat formats 1.001 to "1.00" instead of "1" with 2 fraction
   2513  * digits.
   2514  */
   2515 void NumberFormatRegressionTest::Test4217661(void) {
   2516     const double D[] = {  0.001, 1.001, 0.006,  1.006 };
   2517     const char*  S[] = { "0",   "1",   "0.01", "1.01" };
   2518     int D_length = (int)(sizeof(D) / sizeof(D[0]));
   2519     UErrorCode status = U_ZERO_ERROR;
   2520     NumberFormat *fmt = NumberFormat::createInstance(Locale::getUS(), status);
   2521     if (failure(status, "createInstance", Locale::getUS(), TRUE)){
   2522         delete fmt;
   2523         return;
   2524     };
   2525     fmt->setMaximumFractionDigits(2);
   2526     for (int i=0; i<D_length; i++) {
   2527         UnicodeString s;
   2528         fmt->format(D[i], s);
   2529         if (s != UnicodeString(S[i])) {
   2530             errln(UnicodeString("FAIL: Got ") + s + ", exp " + S[i]);
   2531         }
   2532     }
   2533     delete fmt;
   2534 }
   2535 
   2536 /**
   2537  * alphaWorks upgrade
   2538  */
   2539 void NumberFormatRegressionTest::Test4161100(void) {
   2540     UErrorCode status = U_ZERO_ERROR;
   2541     NumberFormat *nf = NumberFormat::createInstance(Locale::getUS(), status);
   2542     if (failure(status, "createInstance", Locale::getUS(), TRUE)){
   2543         delete nf;
   2544         return;
   2545     };
   2546     nf->setMinimumFractionDigits(1);
   2547     nf->setMaximumFractionDigits(1);
   2548     double a = -0.09;
   2549     UnicodeString s;
   2550     nf->format(a, s);
   2551     UnicodeString pat;
   2552     logln(UnicodeString() + a + " x " +
   2553           ((DecimalFormat*) nf)->toPattern(pat) + " = " + s);
   2554     if (s != UnicodeString("-0.1")) {
   2555         errln("FAIL");
   2556     }
   2557     delete nf;
   2558 }
   2559 
   2560 /**
   2561  * June 16 1999 sync up - liu
   2562  * Formatting .5 rounds to "1" instead of "0". (Regression in 1.2.2 RC1)
   2563  */
   2564 void NumberFormatRegressionTest::Test4243011(void) {
   2565     UErrorCode status = U_ZERO_ERROR;
   2566     DecimalFormatSymbols sym(Locale::getUS(), status);
   2567     failure(status, "DecimalFormatSymbols ct", Locale::getUS());
   2568     DecimalFormat fmt(UnicodeString("0."), sym, status);
   2569 
   2570     if (!failure(status, "DecimalFormat ct", Locale::getUS())) {
   2571         const double NUM[] = {  -2.5,  -1.5,  -0.5,  0.5,  1.5,  2.5,  3.5,  4.5 };
   2572         const char*  STR[] = { "-2.", "-2.", "-0.", "0.", "2.", "2.", "4.", "4." };
   2573         int32_t N = (int32_t)(sizeof(NUM) / sizeof(NUM[0]));
   2574 
   2575         for (int32_t i=0; i<N; ++i) {
   2576             UnicodeString str;
   2577             UnicodeString exp(STR[i]);
   2578             FieldPosition pos;
   2579             fmt.format(NUM[i], str, pos);
   2580             if (str == exp) {
   2581                 logln(UnicodeString("Ok   ") + NUM[i] + " x 0. = " + str);
   2582             } else {
   2583                 errln(UnicodeString("FAIL ") + NUM[i] + " x 0. = " + str +
   2584                       ", want " + exp);
   2585             }
   2586         }
   2587     }
   2588 }
   2589 
   2590 /**
   2591  * June 16 1999 sync up - liu
   2592  * format(0.0) gives "0.1" if preceded by parse("99.99").
   2593  * (Regression in 1.2.2 RC1)
   2594  */
   2595 void NumberFormatRegressionTest::Test4243108(void) {
   2596     UErrorCode status = U_ZERO_ERROR;
   2597     DecimalFormatSymbols sym(Locale::getUS(), status);
   2598     failure(status, "DecimalFormatSymbols ct", Locale::getUS());
   2599     DecimalFormat fmt(UnicodeString("#.#"), sym, status);
   2600     if (failure(status, "DecimalFormat ct", Locale::getUS())) {
   2601         return;
   2602     }
   2603 
   2604     UnicodeString str;
   2605     FieldPosition pos;
   2606 
   2607     fmt.format(0.0, str, pos);
   2608     UnicodeString exp("0");
   2609     if (str == exp) {
   2610         logln(UnicodeString("Ok   0.0 x #.# = ") + str);
   2611     } else {
   2612         errln(UnicodeString("FAIL 0.0 x #.# = ") + str +
   2613               ", want " + exp);
   2614     }
   2615 
   2616     str = "99.99";
   2617     Formattable val;
   2618     fmt.parse(str, val, status);
   2619     failure(status, "DecimalFormat.parse(99.99)", Locale::getUS());
   2620     if (val.getType() == Formattable::kDouble &&
   2621         val.getDouble() == 99.99) {
   2622         logln(UnicodeString("Ok   99.99 / #.# = ") + toString(val));
   2623     } else {
   2624         errln(UnicodeString("FAIL 99.99 / #.# = ") + toString(val) +
   2625               ", want " + 99.99);
   2626     }
   2627 
   2628     str.remove();
   2629     fmt.format(0.0, str, pos);
   2630     if (str == exp) {
   2631         logln(UnicodeString("Ok   0.0 x #.# = ") + str);
   2632     } else {
   2633         errln(UnicodeString("FAIL 0.0 x #.# = ") + str +
   2634               ", want " + exp);
   2635     }
   2636 }
   2637 
   2638 
   2639 /**
   2640  * DateFormat should call setIntegerParseOnly(TRUE) on adopted
   2641  * NumberFormat objects.
   2642  */
   2643 void NumberFormatRegressionTest::TestJ691(void) {
   2644     UErrorCode status = U_ZERO_ERROR;
   2645     Locale loc("fr", "CH");
   2646 
   2647     // set up the input date string & expected output
   2648     UnicodeString udt("11.10.2000", "");
   2649     UnicodeString exp("11.10.00", "");
   2650 
   2651     // create a Calendar for this locale
   2652     Calendar *cal = Calendar::createInstance(loc, status);
   2653     if (U_FAILURE(status)) {
   2654         dataerrln("FAIL: Calendar::createInstance() returned " + (UnicodeString)u_errorName(status));
   2655         return;
   2656     }
   2657 
   2658     // create a NumberFormat for this locale
   2659     NumberFormat *nf = NumberFormat::createInstance(loc, status);
   2660     if (U_FAILURE(status)) {
   2661         dataerrln("FAIL: NumberFormat::createInstance() returned " + (UnicodeString)u_errorName(status));
   2662         return;
   2663     }
   2664 
   2665     // *** Here's the key: We don't want to have to do THIS:
   2666     // nf->setParseIntegerOnly(TRUE);
   2667 
   2668     // create the DateFormat
   2669     DateFormat *df = DateFormat::createDateInstance(DateFormat::kShort, loc);
   2670     if (U_FAILURE(status)) {
   2671         errln("FAIL: DateFormat::createInstance() returned " + (UnicodeString)u_errorName(status));
   2672         return;
   2673     }
   2674 
   2675     df->adoptCalendar(cal);
   2676     df->adoptNumberFormat(nf);
   2677 
   2678     // set parsing to lenient & parse
   2679     df->setLenient(TRUE);
   2680     UDate ulocdat = df->parse(udt, status);
   2681 
   2682     // format back to a string
   2683     UnicodeString outString;
   2684     df->format(ulocdat, outString);
   2685 
   2686     if (outString != exp) {
   2687         errln("FAIL: " + udt + " => " + outString);
   2688     }
   2689 
   2690     delete df;
   2691 }
   2692 
   2693 //---------------------------------------------------------------------------
   2694 //
   2695 //   Error Checking / Reporting macros
   2696 //
   2697 //---------------------------------------------------------------------------
   2698 #define TEST_CHECK_STATUS(status) \
   2699     if (U_FAILURE(status)) {\
   2700         errln("File %s, Line %d.  status=%s\n", __FILE__, __LINE__, u_errorName(status));\
   2701         return;\
   2702     }
   2703 
   2704 #define TEST_ASSERT(expr) \
   2705     if ((expr)==FALSE) {\
   2706         errln("File %s, line %d: Assertion Failed: " #expr "\n", __FILE__, __LINE__);\
   2707     }
   2708 
   2709 
   2710 // Ticket 8199:  Parse failure for numbers in the range of 1E10 - 1E18
   2711 
   2712 void NumberFormatRegressionTest::Test8199(void) {
   2713     UErrorCode status = U_ZERO_ERROR;
   2714     NumberFormat *nf = NumberFormat::createInstance(Locale::getEnglish(), status);
   2715     if (nf == NULL) {
   2716         dataerrln("Fail: NumberFormat::createInstance(Locale::getEnglish(), status)");
   2717         return;
   2718     }
   2719     TEST_CHECK_STATUS(status);
   2720 
   2721     // Note:  Retrieving parsed values from a Formattable as a reduced-precision type
   2722     //        should always truncate, no other rounding scheme.
   2723 
   2724     UnicodeString numStr = "1000000000.6";   // 9 zeroes
   2725     Formattable val;
   2726     nf->parse(numStr, val, status);
   2727     TEST_CHECK_STATUS(status);
   2728     TEST_ASSERT(Formattable::kDouble == val.getType());
   2729     TEST_ASSERT(1000000000 == val.getInt64(status));
   2730     TEST_CHECK_STATUS(status);
   2731     TEST_ASSERT(1000000000.6 == val.getDouble(status));
   2732     TEST_CHECK_STATUS(status);
   2733 
   2734     numStr = "100000000000000001.1";   // approx 1E17, parses as a double rather
   2735                                        //   than int64 because of the fraction
   2736                                        //   even though int64 is more precise.
   2737     nf->parse(numStr, val, status);
   2738     TEST_CHECK_STATUS(status);
   2739     TEST_ASSERT(Formattable::kDouble == val.getType());
   2740     TEST_ASSERT(100000000000000001LL == val.getInt64(status));
   2741     TEST_CHECK_STATUS(status);
   2742     TEST_ASSERT(100000000000000000.0 == val.getDouble(status));
   2743     TEST_CHECK_STATUS(status);
   2744 
   2745     numStr = "1E17";  // Parses with the internal decimal number having non-zero exponent
   2746     nf->parse(numStr, val, status);
   2747     TEST_CHECK_STATUS(status);
   2748     TEST_ASSERT(Formattable::kInt64 == val.getType());
   2749     TEST_ASSERT(100000000000000000LL == val.getInt64());
   2750     TEST_ASSERT(1.0E17 == val.getDouble(status));
   2751     TEST_CHECK_STATUS(status);
   2752 
   2753     numStr = "9223372036854775807";  // largest int64_t
   2754     nf->parse(numStr, val, status);
   2755     TEST_CHECK_STATUS(status);
   2756     TEST_ASSERT(Formattable::kInt64 == val.getType());
   2757     TEST_ASSERT(9223372036854775807LL == val.getInt64());
   2758     // In the following check, note that a substantial range of integers will
   2759     //    convert to the same double value.  There are also platform variations
   2760     //    in the rounding at compile time of double constants.
   2761     TEST_ASSERT(9223372036854775808.0 >= val.getDouble(status));
   2762     TEST_ASSERT(9223372036854774700.0 <= val.getDouble(status));
   2763     TEST_CHECK_STATUS(status);
   2764 
   2765     numStr = "-9223372036854775808";  // smallest int64_t
   2766     nf->parse(numStr, val, status);
   2767     TEST_CHECK_STATUS(status);
   2768     TEST_ASSERT(Formattable::kInt64 == val.getType());
   2769     // TEST_ASSERT(-9223372036854775808LL == val.getInt64()); // Compiler chokes on constant.
   2770     TEST_ASSERT((int64_t)0x8000000000000000LL == val.getInt64());
   2771     TEST_ASSERT(-9223372036854775808.0 == val.getDouble(status));
   2772     TEST_CHECK_STATUS(status);
   2773 
   2774     numStr = "9223372036854775808";  // largest int64_t + 1
   2775     nf->parse(numStr, val, status);
   2776     TEST_CHECK_STATUS(status);
   2777     TEST_ASSERT(Formattable::kDouble == val.getType());
   2778     TEST_ASSERT(9223372036854775807LL == val.getInt64(status));
   2779     TEST_ASSERT(status == U_INVALID_FORMAT_ERROR);
   2780     status = U_ZERO_ERROR;
   2781     TEST_ASSERT(9223372036854775810.0 == val.getDouble(status));
   2782     TEST_CHECK_STATUS(status);
   2783 
   2784     numStr = "-9223372036854775809";  // smallest int64_t - 1
   2785     nf->parse(numStr, val, status);
   2786     TEST_CHECK_STATUS(status);
   2787     TEST_ASSERT(Formattable::kDouble == val.getType());
   2788     // TEST_ASSERT(-9223372036854775808LL == val.getInt64(status));  // spurious compiler warnings
   2789     TEST_ASSERT((int64_t)0x8000000000000000LL == val.getInt64(status));
   2790     TEST_ASSERT(status == U_INVALID_FORMAT_ERROR);
   2791     status = U_ZERO_ERROR;
   2792     TEST_ASSERT(-9223372036854775810.0 == val.getDouble(status));
   2793     TEST_CHECK_STATUS(status);
   2794 
   2795     // Test values near the limit of where doubles can represent all integers.
   2796     // The implementation strategy of getInt64() changes at this boundary.
   2797     // Strings to be parsed include a decimal fraction to force them to be
   2798     //   parsed as doubles rather than ints.  The fraction is discarded
   2799     //   from the parsed double value because it is beyond what can be represented.
   2800 
   2801     status = U_ZERO_ERROR;
   2802     numStr = "9007199254740991.1";  // largest 53 bit int
   2803     nf->parse(numStr, val, status);
   2804     TEST_CHECK_STATUS(status);
   2805     // printf("getInt64() returns %lld\n", val.getInt64(status));
   2806     TEST_ASSERT(Formattable::kDouble == val.getType());
   2807     TEST_ASSERT(9007199254740991LL == val.getInt64(status));
   2808     TEST_ASSERT(9007199254740991.0 == val.getDouble(status));
   2809     TEST_CHECK_STATUS(status);
   2810 
   2811     status = U_ZERO_ERROR;
   2812     numStr = "9007199254740992.1";  // 54 bits for the int part.
   2813     nf->parse(numStr, val, status);
   2814     TEST_CHECK_STATUS(status);
   2815     TEST_ASSERT(Formattable::kDouble == val.getType());
   2816     TEST_ASSERT(9007199254740992LL == val.getInt64(status));
   2817     TEST_ASSERT(9007199254740992.0 == val.getDouble(status));
   2818     TEST_CHECK_STATUS(status);
   2819 
   2820     status = U_ZERO_ERROR;
   2821     numStr = "9007199254740993.1";  // 54 bits for the int part.  Double will round
   2822     nf->parse(numStr, val, status); //    the ones digit, putting it up to ...994
   2823     TEST_CHECK_STATUS(status);
   2824     TEST_ASSERT(Formattable::kDouble == val.getType());
   2825     TEST_ASSERT(9007199254740993LL == val.getInt64(status));
   2826     TEST_ASSERT(9007199254740994.0 == val.getDouble(status));
   2827     TEST_CHECK_STATUS(status);
   2828 
   2829     delete nf;
   2830 }
   2831 
   2832 void NumberFormatRegressionTest::Test9109(void) {
   2833     UErrorCode status = U_ZERO_ERROR;
   2834     Formattable val;
   2835     ParsePosition pos;
   2836     DecimalFormat fmt("+##", status);
   2837     fmt.setLenient(TRUE);
   2838 
   2839     if (U_FAILURE(status)) {
   2840         dataerrln("Failed to create DecimalFormat with pattern '+##' - %s", u_errorName(status));
   2841     }
   2842 
   2843     UnicodeString text("123");
   2844     int32_t expected = 123;
   2845     int32_t expos = 3;
   2846 
   2847     fmt.parse(text, val, pos);
   2848     if (pos.getErrorIndex() >= 0) {
   2849         errln(UnicodeString("Parse failure at ") + pos.getErrorIndex());
   2850     } else if (val.getLong() != 123) {
   2851         errln(UnicodeString("Incorrect parse result: ") + val.getLong() + " expected: " + expected);
   2852     } else if (pos.getIndex() != 3) {
   2853         errln(UnicodeString("Incorrect parse position: ") + pos.getIndex() + " expected: " + expos);
   2854     }
   2855 }
   2856 
   2857 
   2858 void NumberFormatRegressionTest::Test9780(void) {
   2859     UErrorCode status = U_ZERO_ERROR;
   2860     NumberFormat *nf = NumberFormat::createInstance(Locale::getUS(), status);
   2861     if (failure(status, "NumberFormat::createInstance", TRUE)){
   2862         delete nf;
   2863         return;
   2864     };
   2865     DecimalFormat *df = dynamic_cast<DecimalFormat *>(nf);
   2866     if(df == NULL) {
   2867         errln("DecimalFormat needed to continue");
   2868         return;
   2869     }
   2870     df->setParseIntegerOnly(TRUE);
   2871 
   2872     {
   2873       Formattable n;
   2874       ParsePosition pos(0);
   2875       UnicodeString toParse("1,234","");
   2876       df->parse(toParse, n, pos);
   2877       if (n.getType() != Formattable::kLong
   2878           || n.getLong() != 1234) {
   2879         errln(UnicodeString("FAIL: parse(\"") + toParse + UnicodeString("\") returns ") + toString(n));
   2880       }
   2881     }
   2882     // should still work in lenient mode, just won't get fastpath
   2883     df->setLenient(TRUE);
   2884     {
   2885       Formattable n;
   2886       ParsePosition pos(0);
   2887       UnicodeString toParse("1,234","");
   2888       df->parse(toParse, n, pos);
   2889       if (n.getType() != Formattable::kLong
   2890           || n.getLong() != 1234) {
   2891         errln(UnicodeString("FAIL: parse(\"") + toParse + UnicodeString("\") returns ") + toString(n));
   2892       }
   2893     }
   2894     delete nf;
   2895 }
   2896 
   2897 
   2898 void NumberFormatRegressionTest::Test9677(void) {
   2899   static const UChar pattern[] = { 0x23,0x23,0x23,0x23,0x2E,0x23,0x23,0x23,0x23,0 }; // "####.####"
   2900   static const UChar positivePrefix[] = { 0x40,0 }; // "@"
   2901   static const UChar negativePrefix[] = { 0x6E,0 }; // "n"
   2902   static const UChar text[] = { 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0 }; // 123456789
   2903   static const UChar text2[] = { 0x6E, 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0 }; // n123456789
   2904 
   2905   UErrorCode status = U_ZERO_ERROR;
   2906   LocalUNumberFormatPointer f(unum_open(UNUM_DEFAULT, NULL, 0, "en_US", NULL, &status));
   2907   if (U_FAILURE(status)) {
   2908       dataerrln("Failure opening unum_open");
   2909       return;
   2910   }
   2911 
   2912   if (U_SUCCESS(status)) {
   2913     unum_applyPattern(f.getAlias(), FALSE, pattern, -1, NULL, &status);
   2914     unum_setTextAttribute(f.getAlias(), UNUM_POSITIVE_PREFIX, positivePrefix, -1, &status);
   2915     assertSuccess("setting attributes", status);
   2916   }
   2917 
   2918   if(U_SUCCESS(status)) {
   2919     int32_t n = unum_parse(f.getAlias(), text, -1, NULL, &status);
   2920     logln("unum_parse status %s, result %d\n", u_errorName(status), n);
   2921 
   2922     if(U_FAILURE(status)) {
   2923         logln("Got expected parse error %s\n", u_errorName(status));
   2924         status = U_ZERO_ERROR;
   2925     } else {
   2926         errln("FAIL: unum_parse status %s, result %d - expected failure\n", u_errorName(status), n);
   2927     }
   2928   }
   2929 
   2930   if (U_SUCCESS(status)) {
   2931     unum_setTextAttribute(f.getAlias(), UNUM_POSITIVE_PREFIX, NULL, 0, &status);
   2932     assertSuccess("setting attributes", status);
   2933     logln("removed positive prefix");
   2934   }
   2935 
   2936   if(U_SUCCESS(status)) {
   2937     int32_t n = unum_parse(f.getAlias(), text, -1, NULL, &status);
   2938     logln("unum_parse status %s, result %d\n", u_errorName(status), n);
   2939 
   2940     if(U_FAILURE(status)) {
   2941         errln("FAIL: with pos prefix removed, parse error %s\n", u_errorName(status));
   2942         status = U_ZERO_ERROR;
   2943     } else {
   2944         if(n!=123456789) {
   2945           errln("FAIL: with pos prefix removed , unum_parse status %s, result %d expected 123456789\n", u_errorName(status), n);
   2946         } else {
   2947           logln("PASS: with pos prefix removed , unum_parse status %s, result %d expected 123456789\n", u_errorName(status),n);
   2948         }
   2949     }
   2950   }
   2951 
   2952   if(U_SUCCESS(status)) {
   2953     int32_t n = unum_parse(f.getAlias(), text2, -1, NULL, &status);
   2954     logln("unum_parse status %s, result %d\n", u_errorName(status), n);
   2955 
   2956     if(U_FAILURE(status)) {
   2957         logln("text2: Got expected parse error %s\n", u_errorName(status));
   2958         status = U_ZERO_ERROR;
   2959     } else {
   2960         errln("FAIL: text2: unum_parse status %s, result %d - expected failure\n", u_errorName(status), n);
   2961     }
   2962   }
   2963 
   2964   if (U_SUCCESS(status)) {
   2965     unum_setTextAttribute(f.getAlias(), UNUM_NEGATIVE_PREFIX, negativePrefix, -1, &status);
   2966     assertSuccess("setting attributes", status);
   2967     logln("Set a different neg prefix prefix");
   2968   }
   2969 
   2970   if(U_SUCCESS(status)) {
   2971     int32_t n = unum_parse(f.getAlias(), text2, -1, NULL, &status);
   2972     logln("unum_parse status %s, result %d\n", u_errorName(status), n);
   2973 
   2974     if(U_FAILURE(status)) {
   2975         errln("FAIL: with different neg prefix , parse error %s\n", u_errorName(status));
   2976         status = U_ZERO_ERROR;
   2977     } else {
   2978 ;
   2979         if(n!=-123456789) {
   2980           errln("FAIL: with different neg prefix , unum_parse status %s, result %d expected -123456789\n", u_errorName(status), n);
   2981         } else {
   2982           logln("PASS: with different neg prefix , unum_parse status %s, result %d expected -123456789\n", u_errorName(status), n);
   2983         }
   2984     }
   2985   }
   2986 }
   2987 
   2988 
   2989 #endif /* #if !UCONFIG_NO_FORMATTING */
   2990