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