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