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