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