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