1 /*********************************************************************** 
   2  * Copyright (c) 1997-2012, International Business Machines Corporation 
   3  * and others. All Rights Reserved. 
   4  ***********************************************************************/ 
   6 #include "unicode/utypes.h" 
   8 #if !UCONFIG_NO_FORMATTING 
  12 #include <float.h> // DBL_MIN, DBL_MAX 
  15 #include "unicode/dcfmtsym.h" 
  16 #include "unicode/decimfmt.h" 
  17 #include "unicode/locid.h" 
  18 #include "unicode/resbund.h" 
  19 #include "unicode/calendar.h" 
  20 #include "unicode/datefmt.h" 
  21 #include "unicode/ucurr.h" 
  24 class MyNumberFormatTest 
: public NumberFormat 
 
  28     virtual UClassID 
getDynamicClassID(void) const; 
  30     virtual UnicodeString
& format(    double            number
,  
  31                     UnicodeString
&        toAppendTo
,  
  32                     FieldPositionIterator
* posIter
, 
  33                     UErrorCode
& status
) const 
  35         return NumberFormat::format(number
, toAppendTo
, posIter
, status
); 
  38     /* Just keep this here to make some of the compilers happy */ 
  39     virtual UnicodeString
& format(const Formattable
& obj
, 
  40                                   UnicodeString
& toAppendTo
, 
  42                                   UErrorCode
& status
) const 
  44         return NumberFormat::format(obj
, toAppendTo
, pos
, status
); 
  47     /* Just use one of the format functions */ 
  48     virtual UnicodeString
& format(    double            /* number */,  
  49                     UnicodeString
&        toAppendTo
,  
  50                     FieldPosition
&        /* pos */) const 
  57     public Number parse(String text, ParsePosition parsePosition)  
  58     { return new Integer(0); } 
  61     /* Just use one of the parse functions */ 
  62     virtual void parse(    const UnicodeString
&    /* text */,  
  64             ParsePosition
&          /* parsePosition */) const 
  66         result
.setLong((int32_t)0); 
  69     virtual void parse(    const UnicodeString
&    text
,  
  71             UErrorCode
&            status
) const  
  73         NumberFormat::parse(text
, result
, status
); 
  75     virtual Format
* clone() const  
  78     virtual UnicodeString
& format(int32_t,  
  81     { return foo
.remove(); } 
  83     virtual UnicodeString
& format(int64_t,  
  86     { return foo
.remove(); } 
  88     virtual void applyPattern(const UnicodeString
&, UParseError
&, UErrorCode
&){ 
  92 int32_t gMyNumberFormatTestClassID
; 
  93 UClassID 
MyNumberFormatTest::getDynamicClassID()  const 
  95     return (UClassID
)&gMyNumberFormatTestClassID
; 
  99 // ***************************************************************************** 
 100 // class NumberFormatRegressionTest 
 101 // ***************************************************************************** 
 103 #define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break 
 106 NumberFormatRegressionTest::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* /*par*/ ) 
 108     // if (exec) logln((UnicodeString)"TestSuite NumberFormatRegressionTest"); 
 120         CASE(10,Test4086575
); 
 121         CASE(11,Test4068693
); 
 122         CASE(12,Test4069754
); 
 123         CASE(13,Test4087251
); 
 124         CASE(14,Test4090489
); 
 125         CASE(15,Test4090504
); 
 126         CASE(16,Test4095713
); 
 127         CASE(17,Test4092561
); 
 128         CASE(18,Test4092480
); 
 129         CASE(19,Test4087244
); 
 130         CASE(20,Test4070798
); 
 131         CASE(21,Test4071005
); 
 132         CASE(22,Test4071014
); 
 133         CASE(23,Test4071859
); 
 134         CASE(24,Test4093610
); 
 135         CASE(25,Test4098741
); 
 136         CASE(26,Test4074454
); 
 137         CASE(27,Test4099404
); 
 138         CASE(28,Test4101481
); 
 139         CASE(29,Test4052223
); 
 140         CASE(30,Test4061302
); 
 141         CASE(31,Test4062486
); 
 142         CASE(32,Test4108738
); 
 143         CASE(33,Test4106658
); 
 144         CASE(34,Test4106662
); 
 145         CASE(35,Test4114639
); 
 146         CASE(36,Test4106664
); 
 147         CASE(37,Test4106667
); 
 148         CASE(38,Test4110936
); 
 149         CASE(39,Test4122840
); 
 150         CASE(40,Test4125885
); 
 151         CASE(41,Test4134034
); 
 152         CASE(42,Test4134300
); 
 153         CASE(43,Test4140009
); 
 154         CASE(44,Test4141750
); 
 155         CASE(45,Test4145457
); 
 156         CASE(46,Test4147295
); 
 157         CASE(47,Test4147706
); 
 158         CASE(48,Test4162198
); 
 159         CASE(49,Test4162852
); 
 160         CASE(50,Test4167494
); 
 161         CASE(51,Test4170798
); 
 162         CASE(52,Test4176114
); 
 163         CASE(53,Test4179818
); 
 164         CASE(54,Test4212072
); 
 165         CASE(55,Test4216742
); 
 166         CASE(56,Test4217661
); 
 167         CASE(57,Test4161100
); 
 168         CASE(58,Test4243011
); 
 169         CASE(59,Test4243108
); 
 176         default: name 
= ""; break; 
 181 NumberFormatRegressionTest::failure(UErrorCode status
, const UnicodeString
& msg
, const Locale
& l
, UBool possibleDataError
) 
 183     if(U_FAILURE(status
)) { 
 184         if (possibleDataError
) { 
 185             dataerrln(UnicodeString("FAIL: ", "") + msg
 
 186                   + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status
), "") + UnicodeString(l
.getName(),"")); 
 188             errcheckln(status
, UnicodeString("FAIL: ", "") + msg
 
 189                   + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status
), "") + UnicodeString(l
.getName(),"")); 
 198 NumberFormatRegressionTest::failure(UErrorCode status
, const UnicodeString
& msg
, const char *l
, UBool possibleDataError
) 
 200     if(U_FAILURE(status
)) { 
 201         if (possibleDataError
) { 
 202             dataerrln(UnicodeString("FAIL: ", "") + msg
 
 203                   + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status
), "") + UnicodeString(l
, "")); 
 205             errcheckln(status
, UnicodeString("FAIL: ", "") + msg
 
 206                   + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status
), "") + UnicodeString(l
, "")); 
 215 NumberFormatRegressionTest::failure(UErrorCode status
, const UnicodeString
& msg
, UBool possibleDataError
) 
 217     if(U_FAILURE(status
)) { 
 218         if (possibleDataError
) { 
 219             dataerrln(UnicodeString("FAIL: ", "") + msg
 
 220                   + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status
), "")); 
 222             errcheckln(status
, UnicodeString("FAIL: ", "") + msg
 
 223                   + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status
), "")); 
 232  * Convert Java-style strings with \u Unicode escapes into UnicodeString objects 
 234 inline UnicodeString 
str(const char *input
) 
 236   return CharsToUnicodeString(input
); 
 240  * NumberFormat.equals comparing with null should always return false. 
 242 // {sfb} kind of silly in C++, just checking for new success 
 243 void NumberFormatRegressionTest::Test4075713(void) 
 246         MyNumberFormatTest 
*tmp 
= new MyNumberFormatTest(); 
 248             logln("NumberFormat.equals passed"); 
 249     /*} catch (NullPointerException e) { 
 250         errln("(new MyNumberFormatTest()).equals(null) throws unexpected exception"); 
 257  * NumberFormat.equals comparing two obj equal even the setGroupingUsed 
 260 void NumberFormatRegressionTest::Test4074620(void)  
 263     MyNumberFormatTest 
*nf1 
= new MyNumberFormatTest(); 
 264     MyNumberFormatTest 
*nf2 
= new MyNumberFormatTest(); 
 266     nf1
->setGroupingUsed(FALSE
); 
 267     nf2
->setGroupingUsed(TRUE
); 
 270         errln("Test for bug 4074620 failed"); 
 272         logln("Test for bug 4074620 passed."); 
 280  * DecimalFormat.format() incorrectly uses maxFractionDigits setting. 
 283 void NumberFormatRegressionTest::Test4088161 (void) 
 285     UErrorCode status 
= U_ZERO_ERROR
; 
 286     DecimalFormat 
*df 
= new DecimalFormat(status
); 
 287     if (!failure(status
, "new DecimalFormat", "")) { 
 289         df
->setMinimumFractionDigits(0); 
 290         df
->setMaximumFractionDigits(16); 
 292         FieldPosition 
fp1(0); 
 293         logln(UnicodeString("d = ") + d
); 
 294         logln(UnicodeString("maxFractionDigits = ") + df
->getMaximumFractionDigits()); 
 296         logln(" format(d) = '" + df
->format(d
, sBuf1
, fp1
) + "'"); 
 297         df
->setMaximumFractionDigits(17); 
 299         FieldPosition 
fp2(0); 
 300         logln(UnicodeString("maxFractionDigits = ") + df
->getMaximumFractionDigits()); 
 301         sBuf2 
= df
->format(d
, sBuf2
, fp2
); 
 303             errln(" format(d) = '" + sBuf2 
+ "'"); 
 310  * DecimalFormatSymbols should be cloned in the ctor DecimalFormat. 
 311  * DecimalFormat(String, DecimalFormatSymbols). 
 313 void NumberFormatRegressionTest::Test4087245 (void) 
 315     UErrorCode status 
= U_ZERO_ERROR
; 
 316     DecimalFormatSymbols 
*symbols 
= new DecimalFormatSymbols(status
); 
 317     failure(status
, "new DecimalFormatSymbols", ""); 
 318     // {sfb} One note about this test: if you pass in a pointer 
 319     // to the symbols, they are adopted and this test will fail, 
 320     // even though that is the correct behavior.  To test the cloning 
 321     // of the symbols, it is necessary to pass in a reference to the symbols 
 322     DecimalFormat 
*df 
= new DecimalFormat("#,##0.0", *symbols
, status
); 
 323     failure(status
, "new DecimalFormat with symbols", ""); 
 327     FieldPosition 
pos(FieldPosition::DONT_CARE
); 
 328     logln(UnicodeString("format(") + n 
+ ") = " +  
 329         df
->format(n
, buf1
, pos
)); 
 330     symbols
->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
, UnicodeString((UChar
)0x70)); // change value of field 
 331     logln(UnicodeString("format(") + n 
+ ") = " + 
 332         df
->format(n
, buf2
, pos
)); 
 334         errln("Test for bug 4087245 failed"); 
 341  * DecimalFormat.format() incorrectly formats 0.0 
 343 void NumberFormatRegressionTest::Test4087535 (void) 
 345     UErrorCode status 
= U_ZERO_ERROR
; 
 346     DecimalFormat 
*df 
= new DecimalFormat(status
); 
 347     failure(status
, "new DecimalFormat", ""); 
 348     df
->setMinimumIntegerDigits(0); 
 351     UnicodeString buffer
; 
 352     FieldPosition 
pos(FieldPosition::DONT_CARE
); 
 353     buffer 
= df
->format(n
, buffer
, pos
); 
 354     if (buffer
.length() == 0) 
 355         errln(/*n + */": '" + buffer 
+ "'"); 
 357     buffer 
= df
->format(n
, buffer
, pos
); 
 358     if (buffer
.length() == 0) 
 359         errln(/*n + */": '" + buffer 
+ "'"); 
 365  * DecimalFormat.format fails when groupingSize is set to 0. 
 367 // {sfb} how do I tell if this worked? --> FieldPosition doesn't change ?? 
 368 void NumberFormatRegressionTest::Test4088503 (void) 
 370     UErrorCode status 
= U_ZERO_ERROR
; 
 371     DecimalFormat 
*df 
= new DecimalFormat(status
); 
 372     failure(status
, "new DecimalFormat", ""); 
 373     df
->setGroupingSize(0); 
 375     FieldPosition 
fp(FieldPosition::DONT_CARE
); 
 377         logln(df
->format((int32_t)123, sBuf
, fp
)); 
 378         //if(fp == FieldPosition(0)) 
 379         //    errln("Test for bug 4088503 failed."); 
 380     /*} catch (Exception foo) { 
 381         errln("Test for bug 4088503 failed."); 
 387  * NumberFormat.getCurrencyInstance is wrong. 
 389 void NumberFormatRegressionTest::Test4066646 (void)  
 391     assignFloatValue(2.04f
); 
 392     assignFloatValue(2.03f
); 
 393     assignFloatValue(2.02f
); 
 394     assignFloatValue(0.0f
); 
 398 NumberFormatRegressionTest::assignFloatValue(float returnfloat
) 
 400     logln(UnicodeString(" VALUE ") + returnfloat
); 
 401     UErrorCode status 
= U_ZERO_ERROR
; 
 402     NumberFormat 
*nfcommon 
=  NumberFormat::createCurrencyInstance(Locale::getUS(), status
); 
 403     if (failure(status
, "NumberFormat::createCurrencyInstance", Locale::getUS(), TRUE
)){ 
 407     nfcommon
->setGroupingUsed(FALSE
); 
 409     UnicodeString stringValue
; 
 410     stringValue 
= nfcommon
->format(returnfloat
, stringValue
); 
 411     logln(" DISPLAYVALUE " + stringValue
); 
 413     nfcommon
->parse(stringValue
, result
, status
); 
 414     failure(status
, "nfcommon->parse", Locale::getUS()); 
 415     float floatResult 
= (float) (result
.getType() == Formattable::kDouble 
 
 416                                         ? result
.getDouble() : result
.getLong()); 
 417     if( uprv_fabs(floatResult 
- returnfloat
) > 0.0001) 
 418     //String stringValue = nfcommon.format(returnfloat).substring(1); 
 419     //if (Float.valueOf(stringValue).floatValue() != returnfloat) 
 420         errln(UnicodeString("FAIL: expected ") + returnfloat 
+ ", got " + floatResult 
+ " (" + stringValue
+")"); 
 424 } // End Of assignFloatValue() 
 427  * DecimalFormat throws exception when parsing "0" 
 429 void NumberFormatRegressionTest::Test4059870(void)  
 431     UErrorCode status 
= U_ZERO_ERROR
; 
 432     DecimalFormat 
*format 
= new DecimalFormat("00", status
); 
 433     failure(status
, "new Decimalformat", Locale::getUS()); 
 437         format
->parse(UnicodeString("0"), result
, status
); 
 438         failure(status
, "format->parse", Locale::getUS()); 
 441     catch (Exception e) {  
 442         errln("Test for bug 4059870 failed : " + e);  
 448  * DecimalFormatSymbol.equals should always return false when 
 449  * comparing with null. 
 451 // {sfb} this is silly in C++ 
 452 void NumberFormatRegressionTest::Test4083018 (void) 
 454     UErrorCode status 
= U_ZERO_ERROR
; 
 455     DecimalFormatSymbols 
*dfs 
= new DecimalFormatSymbols(status
); 
 456     failure(status
, "new DecimalFormatSymbols", Locale::getUS()); 
 459             logln("Test Passed!"); 
 461             errln("Test for bug 4083018 failed"); 
 462     /*} catch (Exception foo) { 
 463         errln("Test for bug 4083018 failed => Message : " + foo.getMessage()); 
 470  * DecimalFormat does not round up correctly. 
 472 void NumberFormatRegressionTest::Test4071492 (void) 
 474     double x 
= 0.00159999; 
 475     UErrorCode status 
= U_ZERO_ERROR
; 
 476     NumberFormat 
*nf 
= NumberFormat::createInstance(status
); 
 477     if (failure(status
, "NumberFormat::createInstance", Locale::getUS(), TRUE
)) { 
 481     nf
->setMaximumFractionDigits(4); 
 483     FieldPosition 
pos(FieldPosition::DONT_CARE
); 
 484     out 
= nf
->format(x
, out
, pos
); 
 485     logln("0.00159999 formats with 4 fractional digits to " + out
); 
 486     UnicodeString 
expected("0.0016"); 
 488         errln("FAIL: Expected " + expected
); 
 494  * A space as a group separator for localized pattern causes 
 495  * wrong format.  WorkAround : use non-breaking space. 
 497 void NumberFormatRegressionTest::Test4086575(void)  
 499     UErrorCode status 
= U_ZERO_ERROR
; 
 500     NumberFormat 
*nf1 
= NumberFormat::createInstance(Locale::getFrance(), status
); 
 502     // TODO: There is not a good way to find out that the creation of this number format has 
 503     // failed. Major rewiring of format construction proposed. 
 504     if(U_FAILURE(status
)) { 
 505       dataerrln("Something is wrong with French number format - it should not fallback. Exitting - %s", u_errorName(status
)); 
 509     failure(status
, "NumberFormat::createInstance", Locale::getFrance()); 
 511     // C++ workaround to make sure cast works 
 512     DecimalFormat 
*nf 
= dynamic_cast<DecimalFormat 
*>(nf1
); 
 514         errln("NumberFormat::createInstance returned incorrect type."); 
 519     logln("nf toPattern1: " + nf
->toPattern(temp
)); 
 520     logln("nf toLocPattern1: " + nf
->toLocalizedPattern(temp
)); 
 522     // No group separator 
 523     logln("...applyLocalizedPattern ###,00;(###,00) "); 
 524     nf
->applyLocalizedPattern(UnicodeString("###,00;(###,00)"), status
); 
 525     failure(status
, "nf->applyLocalizedPattern", Locale::getFrance()); 
 526     logln("nf toPattern2: " + nf
->toPattern(temp
)); 
 527     logln("nf toLocPattern2: " + nf
->toLocalizedPattern(temp
)); 
 529     FieldPosition 
pos(FieldPosition::DONT_CARE
); 
 530     logln("nf: " + nf
->format((int32_t)1234, temp
, pos
)); // 1234,00 
 531     logln("nf: " + nf
->format((int32_t)-1234, temp
, pos
)); // (1234,00) 
 533     // Space as group separator 
 535     logln("...applyLocalizedPattern # ###,00;(# ###,00) "); 
 537     //nf->applyLocalizedPattern("#\u00a0###,00;(#\u00a0###,00)"); 
 539              0x23, 0x00a0, 0x23, 0x23, 0x23, 0x2c, 0x30, 0x30, 0x3b,  
 540         0x28, 0x23, 0x00a0, 0x23, 0x23, 0x23, 0x2c, 0x30, 0x30, 0x29 
 542     UnicodeString 
pat(patChars
, 19, 19); 
 543     nf
->applyLocalizedPattern(pat
, status
); 
 544     failure(status
, "nf->applyLocalizedPattern", Locale::getFrance()); 
 545     logln("nf toPattern2: " + nf
->toPattern(temp
)); 
 546     logln("nf toLocPattern2: " + nf
->toLocalizedPattern(temp
)); 
 547     UnicodeString buffer
; 
 548     buffer 
= nf
->format((int32_t)1234, buffer
, pos
); 
 549     //if (buffer != UnicodeString("1\u00a0234,00")) 
 551         0x31, 0x00a0, 0x32, 0x33, 0x34, 0x2c, 0x30, 0x30 
 553     UnicodeString 
cc(c
, 8, 8); 
 555         errln("nf : " + buffer
); // Expect 1 234,00 
 558     buffer 
= nf
->format((int32_t)-1234, buffer
, pos
); 
 560         0x28, 0x31, 0x00a0, 0x32, 0x33, 0x34, 0x2c, 0x30, 0x30, 0x29 
 562     UnicodeString 
cc1(c1
, 10, 10); 
 564         errln("nf : " + buffer
); // Expect (1 234,00) 
 566     // Erroneously prints: 
 573  * DecimalFormat.parse returns wrong value 
 575 // {sfb} slightly converted into a round-trip test, since in C++ 
 576 // there is no Double.toString() 
 577 void NumberFormatRegressionTest::Test4068693(void) 
 579     logln("----- Test Application -----"); 
 580     ParsePosition 
pos(0); 
 581     UErrorCode status 
= U_ZERO_ERROR
; 
 582     DecimalFormat 
*df 
= new DecimalFormat(status
); 
 583     if(U_FAILURE(status
)) { 
 584       errcheckln(status
, "Error creating DecimalFormat: %s", u_errorName(status
)); 
 588     failure(status
, "new DecimalFormat"); 
 590     //Double d = (Double)df.parse("123.55456", pos=new ParsePosition(0)); 
 591     df
->parse(UnicodeString("123.55456"), d
, pos
); 
 592     //if (!d.toString().equals("123.55456")) { 
 594     df
->setMaximumFractionDigits(999); 
 595     df
->setMaximumIntegerDigits(999); 
 596     FieldPosition 
fp(FieldPosition::DONT_CARE
); 
 597     dstr 
= df
->format(d
.getDouble(), dstr
, fp
); 
 598     if (dstr 
!= UnicodeString("123.55456")) { 
 599         errln(UnicodeString("Result -> ") + d
.getDouble()); 
 605 /* @bug 4069754, 4067878 
 606  * null pointer thrown when accessing a deserialized DecimalFormat 
 609 // {sfb} doesn't apply in C++ 
 610 void NumberFormatRegressionTest::Test4069754(void) 
 613         myformat it = new myformat(); 
 615         FileOutputStream ostream = new FileOutputStream("t.tmp"); 
 616         ObjectOutputStream p = new ObjectOutputStream(ostream); 
 621         FileInputStream istream = new FileInputStream("t.tmp"); 
 622         ObjectInputStream p2 = new ObjectInputStream(istream); 
 623         myformat it2 = (myformat)p2.readObject(); 
 627     } catch (Exception foo) { 
 628         errln("Test for bug 4069754 or 4057878 failed => Exception: " + foo.getMessage()); 
 633  * DecimalFormat.applyPattern(String) allows illegal patterns 
 635 void NumberFormatRegressionTest::Test4087251 (void) 
 637     UErrorCode status 
= U_ZERO_ERROR
; 
 638     DecimalFormat 
*df 
= new DecimalFormat(status
); 
 639     if(U_FAILURE(status
)) { 
 640       errcheckln(status
, "Error creating DecimalFormat: %s", u_errorName(status
)); 
 644     failure(status
, "new DecimalFormat"); 
 646         df
->applyPattern(UnicodeString("#.#.#"), status
); 
 647         if( ! U_FAILURE(status
)) 
 648             errln("df->applyPattern with illegal pattern didn't fail"); 
 650         logln("toPattern() returns \"" + df
->toPattern(temp
) + "\""); 
 651         //errln("applyPattern(\"#.#.#\") doesn't throw IllegalArgumentException"); 
 652     /*} catch (IllegalArgumentException e) { 
 653         logln("Caught Illegal Argument Error !"); 
 655     // Second test; added 5/11/98 when reported to fail on 1.2b3 
 657         df
->applyPattern("#0.0#0#0", status
); 
 658         if( ! U_FAILURE(status
)) 
 659             errln("df->applyPattern with illegal pattern didn't fail"); 
 660         logln("toPattern() returns \"" + df
->toPattern(temp
) + "\""); 
 661         //errln("applyPattern(\"#0.0#0#0\") doesn't throw IllegalArgumentException"); 
 662     /*} catch (IllegalArgumentException e) { 
 663         logln("Ok - IllegalArgumentException for #0.0#0#0"); 
 670  * DecimalFormat.format() loses precision 
 672 void NumberFormatRegressionTest::Test4090489 (void) 
 674 // {sfb} sprintf doesn't correctly handle the double, so there is nothing 
 675 // that NumberFormat can do.  For some reason, it does not format the last 1. 
 677 /*    UErrorCode status = U_ZERO_ERROR; 
 678     DecimalFormat *df = new DecimalFormat(status); 
 679     failure(status, "new DecimalFormat"); 
 680     df->setMinimumFractionDigits(10); 
 681     df->setMaximumFractionDigits(999); 
 682     df->setGroupingUsed(FALSE); 
 683     double d = 1.000000000000001E7; 
 684     //BigDecimal bd = new BigDecimal(d); 
 687     logln(UnicodeString("d = ") + d); 
 688     //logln("BigDecimal.toString():  " + bd.toString()); 
 689     df->format(d, sb, fp); 
 690     if (sb != "10000000.0000000100") { 
 691         errln("DecimalFormat.format(): " + sb); 
 697  * DecimalFormat.format() loses precision 
 699 void NumberFormatRegressionTest::Test4090504 (void) 
 702     logln(UnicodeString("d = ") + d
); 
 703     UErrorCode status 
= U_ZERO_ERROR
; 
 704     DecimalFormat 
*df 
= new DecimalFormat(status
); 
 705     if(U_FAILURE(status
)) { 
 706       errcheckln(status
, "Error creating DecimalFormat: %s", u_errorName(status
)); 
 710     failure(status
, "new DecimalFormat"); 
 712     FieldPosition 
fp(FieldPosition::DONT_CARE
); 
 714         for (int i 
= 17; i 
<= 20; i
++) { 
 715             df
->setMaximumFractionDigits(i
); 
 716             //sb = new StringBuffer(""); 
 718             logln(UnicodeString("  getMaximumFractionDigits() = ") + i
); 
 719             logln(UnicodeString("  formated: ") + df
->format(d
, sb
, fp
)); 
 721     /*} catch (Exception foo) { 
 722         errln("Bug 4090504 regression test failed. Message : " + foo.getMessage()); 
 728  * DecimalFormat.parse(String str, ParsePosition pp) loses precision 
 730 void NumberFormatRegressionTest::Test4095713 (void) 
 732     UErrorCode status 
= U_ZERO_ERROR
; 
 733     DecimalFormat 
*df 
= new DecimalFormat(status
); 
 734     if(U_FAILURE(status
)) { 
 735       errcheckln(status
, "Error creating DecimalFormat: %s", u_errorName(status
)); 
 739     failure(status
, "new DecimalFormat"); 
 740     UnicodeString 
str("0.1234"); 
 742     //Double d1 = new Double(str); 
 743     //Double d2 = (Double) df.parse(str, new ParsePosition(0)); 
 746     df
->parse(str
, d2
, pp
); 
 747     logln(UnicodeString("") + d1
); 
 748     if (d2
.getDouble() != d1
) 
 749         errln(UnicodeString("Bug 4095713 test failed, new double value : ") + d2
.getDouble()); 
 754  * DecimalFormat.parse() fails when multiplier is not set to 1 
 756 // {sfb} not sure what to do with this one 
 757 void NumberFormatRegressionTest::Test4092561 (void) 
 759     UErrorCode status 
= U_ZERO_ERROR
; 
 760     DecimalFormat 
*df 
= new DecimalFormat(status
); 
 761     if(U_FAILURE(status
)) { 
 762       errcheckln(status
, "Error creating DecimalFormat: %s", u_errorName(status
)); 
 766     failure(status
, "new DecimalFormat"); 
 768     // {sfb} going to cheat here and use sprintf ?? 
 770     /*UnicodeString str = Long.toString(Long.MIN_VALUE); 
 771     logln("Long.MIN_VALUE : " + df.parse(str, new ParsePosition(0)).toString()); 
 772     df.setMultiplier(100); 
 773     Number num = df.parse(str, new ParsePosition(0)); 
 774     if (num.doubleValue() != -9.223372036854776E16) 
 775         errln("Bug 4092561 test failed when multiplier is set to not 1."); 
 781  * DecimalFormat: Negative format ignored. 
 783 void NumberFormatRegressionTest::Test4092480 (void) 
 785     UErrorCode status 
= U_ZERO_ERROR
; 
 786     DecimalFormat 
*dfFoo 
= new DecimalFormat(UnicodeString("000"), status
); 
 787     if(U_FAILURE(status
)) { 
 788       errcheckln(status
, "Error creating DecimalFormat: %s", u_errorName(status
)); 
 792     failure(status
, "new DecimalFormat"); 
 795         dfFoo
->applyPattern("0000;-000", status
); 
 796         failure(status
, "dfFoo->applyPattern"); 
 798         if (dfFoo
->toPattern(temp
) != UnicodeString("#0000")) 
 799             errln("dfFoo.toPattern : " + dfFoo
->toPattern(temp
)); 
 800         FieldPosition 
pos(FieldPosition::DONT_CARE
); 
 801         logln(dfFoo
->format((int32_t)42, temp
, pos
)); 
 802         logln(dfFoo
->format((int32_t)-42, temp
, pos
)); 
 803         dfFoo
->applyPattern("000;-000", status
); 
 804         failure(status
, "dfFoo->applyPattern"); 
 805         if (dfFoo
->toPattern(temp
) != UnicodeString("#000")) 
 806             errln("dfFoo.toPattern : " + dfFoo
->toPattern(temp
)); 
 807         logln(dfFoo
->format((int32_t)42,temp
, pos
)); 
 808         logln(dfFoo
->format((int32_t)-42, temp
, pos
)); 
 810         dfFoo
->applyPattern("000;-0000", status
); 
 811         failure(status
, "dfFoo->applyPattern"); 
 812         if (dfFoo
->toPattern(temp
) != UnicodeString("#000")) 
 813             errln("dfFoo.toPattern : " + dfFoo
->toPattern(temp
)); 
 814         logln(dfFoo
->format((int32_t)42, temp
, pos
)); 
 815         logln(dfFoo
->format((int32_t)-42, temp
, pos
)); 
 817         dfFoo
->applyPattern("0000;-000", status
); 
 818         failure(status
, "dfFoo->applyPattern"); 
 819         if (dfFoo
->toPattern(temp
) != UnicodeString("#0000")) 
 820             errln("dfFoo.toPattern : " + dfFoo
->toPattern(temp
)); 
 821         logln(dfFoo
->format((int32_t)42, temp
, pos
)); 
 822         logln(dfFoo
->format((int32_t)-42, temp
, pos
)); 
 823     /*} catch (Exception foo) { 
 824         errln("Message " + foo.getMessage()); 
 830  * NumberFormat.getCurrencyInstance() produces format that uses 
 831  * decimal separator instead of monetary decimal separator. 
 833  * Rewrote this test not to depend on the actual pattern.  Pattern should 
 834  * never contain the monetary separator!  Decimal separator in pattern is 
 835  * interpreted as monetary separator if currency symbol is seen! 
 837 void NumberFormatRegressionTest::Test4087244 (void) { 
 838     UErrorCode status 
= U_ZERO_ERROR
; 
 840     uloc_canonicalize("pt_PT_PREEURO", loc
, 256, &status
); 
 841     Locale 
*de 
= new Locale(loc
); 
 842     NumberFormat 
*nf 
= NumberFormat::createCurrencyInstance(*de
, status
); 
 843     if(U_FAILURE(status
)) { 
 844       dataerrln("Error creating DecimalFormat: %s", u_errorName(status
)); 
 848     DecimalFormat 
*df 
= dynamic_cast<DecimalFormat 
*>(nf
); 
 850         errln("expected DecimalFormat!"); 
 853     const DecimalFormatSymbols 
*sym 
= df
->getDecimalFormatSymbols(); 
 854     UnicodeString decSep 
= sym
->getSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
); 
 855     UnicodeString monSep 
= sym
->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
); 
 856     if (decSep 
== monSep
) { 
 857         errln("ERROR in test: want decimal sep != monetary sep"); 
 860     df
->setMinimumIntegerDigits(1); 
 861     df
->setMinimumFractionDigits(2); 
 864     df
->format(1.23, str
, pos
); 
 865     UnicodeString 
monStr("1x23"); 
 866     monStr
.replace((int32_t)1, 1, monSep
); 
 867     UnicodeString 
decStr("1x23"); 
 868     decStr
.replace((int32_t)1, 1, decSep
); 
 869     if (str
.indexOf(monStr
) >= 0 && str
.indexOf(decStr
) < 0) { 
 870         logln(UnicodeString("OK: 1.23 -> \"") + str 
+ "\" contains \"" + 
 871               monStr 
+ "\" and not \"" + decStr 
+ '"'); 
 873         errln(UnicodeString("FAIL: 1.23 -> \"") + str 
+ "\", should contain \"" + 
 875               "\" and not \"" + decStr 
+ '"'); 
 881  * Number format data rounding errors for locale FR 
 883 void NumberFormatRegressionTest::Test4070798 (void)  
 885     NumberFormat 
*formatter
; 
 886     UnicodeString tempString
; 
 889     String expectedDefault = "-5\u00a0789,987"; 
 890     String expectedCurrency = "5\u00a0789,98\u00a0F"; 
 891     String expectedPercent = "-578\u00a0998%"; 
 894         0x2d, 0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x38, 0x38 
 897         0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x39, 0x00a0, 0x46 
 900         0x2d, 0x35, 0x37, 0x38, 0x00a0, 0x39, 0x39, 0x39, 0x00a0, 0x25 
 902     UnicodeString 
expectedDefault(chars1
, 10, 10); 
 903     UnicodeString 
expectedCurrency(chars2
, 10, 10); 
 904     UnicodeString 
expectedPercent(chars3
, 10, 10); 
 906     UErrorCode status 
= U_ZERO_ERROR
; 
 908     int len 
= uloc_canonicalize("fr_FR_PREEURO", loc
, 256, &status
); 
 909     formatter 
= NumberFormat::createInstance(Locale(loc
), status
); 
 910     if(U_FAILURE(status
)) { 
 911       dataerrln("Error creating DecimalFormat: %s", u_errorName(status
)); 
 915     failure(status
, "NumberFormat::createNumberInstance", loc
); 
 916     tempString 
= formatter
->format (-5789.9876, tempString
); 
 918     if (tempString 
== expectedDefault
) { 
 919         logln ("Bug 4070798 default test passed."); 
 921         errln(UnicodeString("Failed:") + 
 922         " Expected " + expectedDefault 
+ 
 923         " Received " + tempString 
); 
 926     len 
= uloc_canonicalize("fr_FR_PREEURO", loc
, 256, &status
); 
 927     formatter 
= NumberFormat::createCurrencyInstance(loc
, status
); 
 928     failure(status
, "NumberFormat::createCurrencyInstance", loc
); 
 930     tempString 
= formatter
->format( 5789.9876, tempString 
); 
 932     if (tempString 
== expectedCurrency
) { 
 933         logln ("Bug 4070798 currency test passed."); 
 935         errln(UnicodeString("Failed:") + 
 936         " Expected " + expectedCurrency 
+ 
 937         " Received " + tempString 
); 
 941     uloc_canonicalize("fr_FR_PREEURO", loc
, 256, &status
); 
 942     formatter 
= NumberFormat::createPercentInstance(Locale(loc
), status
); 
 943     failure(status
, "NumberFormat::createPercentInstance", loc
); 
 945     tempString 
= formatter
->format (-5789.9876, tempString
); 
 947     if (tempString 
== expectedPercent
) { 
 948         logln ("Bug 4070798 percentage test passed."); 
 950         errln(UnicodeString("Failed:") + 
 951         " Expected " + expectedPercent 
+ 
 952         " Received " + tempString 
); 
 958  * Data rounding errors for French (Canada) locale 
 960 void NumberFormatRegressionTest::Test4071005 (void)  
 962     NumberFormat 
*formatter
; 
 963     UnicodeString tempString
; 
 965     String expectedDefault = "-5\u00a0789,987"; 
 966     String expectedCurrency = "5\u00a0789,98\u00a0$"; 
 967     String expectedPercent = "-578\u00a0998%"; 
 970         0x2d, 0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x38, 0x38 
 973         0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x39, 0x00a0, 0x24 
 976         0x2d, 0x35, 0x37, 0x38, 0x00a0, 0x39, 0x39, 0x39, 0x00a0, 0x25 
 978     UnicodeString 
expectedDefault(chars1
, 10, 10); 
 979     UnicodeString 
expectedCurrency(chars2
, 10, 10); 
 980     UnicodeString 
expectedPercent(chars3
, 10, 10); 
 982     UErrorCode status 
= U_ZERO_ERROR
; 
 983     formatter 
= NumberFormat::createInstance(Locale::getCanadaFrench(), status
); 
 984     if (failure(status
, "NumberFormat::createNumberInstance", Locale::getCanadaFrench(), TRUE
)){ 
 988     tempString 
= formatter
->format (-5789.9876, tempString
); 
 990     if (tempString 
== expectedDefault
) { 
 991         logln ("Bug 4071005 default test passed."); 
 993         errln(UnicodeString("Failed:") + 
 994         " Expected " + expectedDefault 
+ 
 995         " Received " + tempString 
); 
 999     formatter 
= NumberFormat::createCurrencyInstance(Locale::getCanadaFrench(), status
); 
1000     failure(status
, "NumberFormat::createCurrencyInstance", Locale::getCanadaFrench()); 
1001     tempString
.remove(); 
1002     tempString 
= formatter
->format( 5789.9876, tempString 
); 
1004     if (tempString 
== expectedCurrency
) { 
1005         logln ("Bug 4071005 currency test assed."); 
1007         errln(UnicodeString("Failed:") + 
1008         " Expected " + expectedCurrency 
+ 
1009         " Received " + tempString 
); 
1013     formatter 
= NumberFormat::createPercentInstance(Locale::getCanadaFrench(), status
); 
1014     failure(status
, "NumberFormat::createPercentInstance", Locale::getCanadaFrench()); 
1015     tempString
.remove(); 
1016     tempString 
= formatter
->format (-5789.9876, tempString
); 
1018     if (tempString 
== expectedPercent
) { 
1019         logln ("Bug 4071005 percentage test passed."); 
1021         errln(UnicodeString("Failed:") + 
1022         " Expected " + expectedPercent 
+ 
1023         " Received " + tempString 
); 
1030  * Data rounding errors for German (Germany) locale 
1032 void NumberFormatRegressionTest::Test4071014 (void)  
1034     NumberFormat 
*formatter
; 
1035     UnicodeString tempString
; 
1037     String expectedDefault = "-5.789,987"; 
1038     String expectedCurrency = "5.789,98 DEM"; 
1039     String expectedPercent = "-578.998%"; 
1041     UnicodeString 
expectedDefault("-5.789,988"); 
1042     UnicodeString 
expectedCurrency("5.789,99\\u00A0DEM"); 
1043     UnicodeString 
expectedPercent("-578.999\\u00A0%"); 
1045     expectedCurrency 
= expectedCurrency
.unescape(); 
1046     expectedPercent 
= expectedPercent
.unescape(); 
1048     UErrorCode status 
= U_ZERO_ERROR
; 
1050     uloc_canonicalize("de_DE_PREEURO", loc
, 256, &status
); 
1051     formatter 
= NumberFormat::createInstance(Locale(loc
), status
); 
1052     if (failure(status
, "NumberFormat::createNumberInstance", loc
, TRUE
)){ 
1056     tempString
.remove(); 
1057     tempString 
= formatter
->format (-5789.9876, tempString
); 
1059     if (tempString 
== expectedDefault
) { 
1060         logln ("Bug 4071014 default test passed."); 
1062         errln(UnicodeString("Failed:") + 
1063         " Expected " + expectedDefault 
+ 
1064         " Received " + tempString 
); 
1067     uloc_canonicalize("de_DE_PREEURO", loc
, 256, &status
); 
1068     formatter 
= NumberFormat::createCurrencyInstance(Locale(loc
), status
); 
1069     failure(status
, "NumberFormat::createCurrencyInstance", loc
); 
1070     tempString
.remove(); 
1071     tempString 
= formatter
->format( 5789.9876, tempString 
); 
1073     if (tempString 
== expectedCurrency
) { 
1074         logln ("Bug 4071014 currency test assed."); 
1076         errln(UnicodeString("Failed:") + 
1077         " Expected " + expectedCurrency 
+ 
1078         " Received " + tempString 
); 
1082     formatter 
= NumberFormat::createPercentInstance(Locale::getGermany(), status
); 
1083     failure(status
, "NumberFormat::createPercentInstance", Locale::getGermany()); 
1084     tempString
.remove(); 
1085     tempString 
= formatter
->format (-5789.9876, tempString
); 
1087     if (tempString 
== expectedPercent
) { 
1088         logln ("Bug 4071014 percentage test passed."); 
1090         errln(UnicodeString("Failed:") + 
1091         " Expected " + expectedPercent 
+ 
1092         " Received " + tempString 
); 
1098  * Data rounding errors for Italian locale number formats 
1100 void NumberFormatRegressionTest::Test4071859 (void)  
1102     NumberFormat 
*formatter
; 
1103     UnicodeString tempString
; 
1105     String expectedDefault = "-5.789,987"; 
1106     String expectedCurrency = "-L.\\u00A05.789,98"; 
1107     String expectedPercent = "-578.998%"; 
1109     UnicodeString 
expectedDefault("-5.789,988"); 
1110     UnicodeString 
expectedCurrency("-ITL\\u00A05.790", -1, US_INV
); 
1111     UnicodeString 
expectedPercent("-578.999%"); 
1112     expectedCurrency 
= expectedCurrency
.unescape(); 
1114     UErrorCode status 
= U_ZERO_ERROR
; 
1116     uloc_canonicalize("it_IT_PREEURO", loc
, 256, &status
); 
1117     formatter 
= NumberFormat::createInstance(Locale(loc
), status
); 
1118     if (failure(status
, "NumberFormat::createNumberInstance", TRUE
)){ 
1122     tempString 
= formatter
->format (-5789.9876, tempString
); 
1124     if (tempString 
== expectedDefault
) { 
1125         logln ("Bug 4071859 default test passed."); 
1127         errln(UnicodeString("Failed:") + 
1128         " Expected " + expectedDefault 
+ 
1129         " Received " + tempString 
); 
1132     uloc_canonicalize("it_IT_PREEURO", loc
, 256, &status
); 
1133     formatter 
= NumberFormat::createCurrencyInstance(Locale(loc
), status
); 
1134     failure(status
, "NumberFormat::createCurrencyInstance"); 
1135     tempString
.remove(); 
1136     tempString 
= formatter
->format( -5789.9876, tempString 
); 
1138     if (tempString 
== expectedCurrency
) { 
1139         logln ("Bug 4071859 currency test assed."); 
1141         errln(UnicodeString("Failed:") + 
1142         " Expected " + expectedCurrency 
+ 
1143         " Received " + tempString 
); 
1146     uloc_canonicalize("it_IT_PREEURO", loc
, 256, &status
); 
1147     formatter 
= NumberFormat::createPercentInstance(Locale(loc
), status
); 
1148     failure(status
, "NumberFormat::createPercentInstance"); 
1149     tempString
.remove(); 
1150     tempString 
= formatter
->format (-5789.9876, tempString
); 
1152     if (tempString 
== expectedPercent
) { 
1153         logln ("Bug 4071859 percentage test passed."); 
1155         errln(UnicodeString("Failed:") + 
1156         " Expected " + expectedPercent 
+ 
1157         " Received " + tempString 
); 
1163  * Test rounding for nearest even. 
1165 void NumberFormatRegressionTest::Test4093610(void) 
1167     UErrorCode status 
= U_ZERO_ERROR
; 
1168     DecimalFormat 
*df 
= new DecimalFormat("#0.#", status
); 
1169     if (!failure(status
, "new DecimalFormat")) { 
1170         UnicodeString 
s("12.4"); 
1171         roundingTest(df
, 12.35, s
); 
1172         roundingTest(df
, 12.45, s
); 
1174         roundingTest(df
, 12.452,s
); 
1176         roundingTest(df
, 12.55, s
); 
1177         roundingTest(df
, 12.65, s
); 
1179         roundingTest(df
, 12.652,s
); 
1181         roundingTest(df
, 12.75, s
); 
1182         roundingTest(df
, 12.752,s
); 
1183         roundingTest(df
, 12.85, s
); 
1185         roundingTest(df
, 12.852,s
); 
1187         roundingTest(df
, 12.95, s
); 
1188         roundingTest(df
, 12.952,s
); 
1194 void NumberFormatRegressionTest::roundingTest(DecimalFormat 
*df
, double x
, UnicodeString
& expected
) 
1197     FieldPosition 
pos(FieldPosition::DONT_CARE
); 
1198     out 
= df
->format(x
, out
, pos
); 
1199     logln(UnicodeString("") + x 
+ " formats with 1 fractional digits to " + out
); 
1200     if (out 
!= expected
)  
1201         errln("FAIL: Expected " + expected
); 
1204  * Tests the setMaximumFractionDigits limit. 
1206 void NumberFormatRegressionTest::Test4098741(void) 
1209     UErrorCode status 
= U_ZERO_ERROR
; 
1210     NumberFormat 
*fmt 
= NumberFormat::createPercentInstance(status
); 
1211     if (U_FAILURE(status
)) { 
1212         dataerrln("Error calling NumberFormat::createPercentInstance"); 
1217         fmt
->setMaximumFractionDigits(20); 
1219         logln(fmt
->format(.001, temp
)); 
1220     /*} catch (Exception foo) { 
1221         errln("Bug 4098471 failed with exception thrown : " + foo.getMessage()); 
1226  * Tests illegal pattern exception. 
1227  * Fix comment : HShih A31 Part1 will not be fixed and javadoc needs to be updated. 
1228  * Part2 has been fixed. 
1230 void NumberFormatRegressionTest::Test4074454(void) 
1233     UErrorCode status 
= U_ZERO_ERROR
;   
1234     DecimalFormat 
*fmt 
= new DecimalFormat("#,#00.00;-#.#", status
); 
1235     if(U_FAILURE(status
)) { 
1236       errcheckln(status
, "Error creating DecimalFormat: %s", u_errorName(status
)); 
1240     failure(status
, "new DecimalFormat"); 
1241       logln("Inconsistent negative pattern is fine."); 
1242         DecimalFormat 
*newFmt 
= new DecimalFormat("#,#00.00 p''ieces;-#,#00.00 p''ieces", status
); 
1243         failure(status
, "new DecimalFormat"); 
1244         UnicodeString tempString
; 
1245         FieldPosition 
pos(FieldPosition::DONT_CARE
); 
1246         tempString 
= newFmt
->format(3456.78, tempString
, pos
); 
1247         if (tempString 
!= UnicodeString("3,456.78 p'ieces")) 
1248             dataerrln("Failed!  3456.78 p'ieces expected, but got : " + tempString
); 
1249     /*} catch (Exception foo) { 
1250         errln("An exception was thrown for any inconsistent negative pattern."); 
1257  * Tests all different comments. 
1258  * Response to some comments : 
1259  * [1] DecimalFormat.parse API documentation is more than just one line. 
1260  * This is not a reproducable doc error in 116 source code. 
1261  * [2] See updated javadoc. 
1263  * [4] NumberFormat.parse(String, ParsePosition) : If parsing fails, 
1264  * a null object will be returned.  The unchanged parse position also 
1265  * reflects an error. 
1266  * NumberFormat.parse(String) : If parsing fails, an ParseException 
1268  * See updated javadoc for more details. 
1269  * [5] See updated javadoc. 
1270  * [6] See updated javadoc. 
1271  * [7] This is a correct behavior if the DateFormat object is linient. 
1272  * Otherwise, an IllegalArgumentException will be thrown when formatting 
1273  * "January 35".  See GregorianCalendar class javadoc for more details. 
1275 void NumberFormatRegressionTest::Test4099404(void) 
1278         UErrorCode status 
= U_ZERO_ERROR
; 
1279         DecimalFormat 
*fmt 
= new DecimalFormat(UnicodeString("000.0#0"), status
); 
1280         if(! U_FAILURE(status
)) 
1281             errln(UnicodeString("Bug 4099404 failed applying illegal pattern \"000.0#0\"")); 
1282     /*} catch (Exception foo) { 
1283         logln("Bug 4099404 pattern \"000.0#0\" passed"); 
1288         fmt 
= new DecimalFormat(UnicodeString("0#0.000"), status
); 
1289         if( !U_FAILURE(status
)) 
1290            errln("Bug 4099404 failed applying illegal pattern \"0#0.000\""); 
1291     /*} catch (Exception foo) { 
1292         logln("Bug 4099404 pattern \"0#0.000\" passed"); 
1298  * DecimalFormat.applyPattern doesn't set minimum integer digits 
1300 void NumberFormatRegressionTest::Test4101481(void) 
1302     UErrorCode status 
= U_ZERO_ERROR
; 
1303     DecimalFormat 
*sdf 
= new DecimalFormat(UnicodeString("#,##0"), status
); 
1304     if(U_FAILURE(status
)) { 
1305       errcheckln(status
, "Error creating DecimalFormat: %s", u_errorName(status
)); 
1309     failure(status
, "new DecimalFormat"); 
1310     if (sdf
->getMinimumIntegerDigits() != 1) 
1311         errln(UnicodeString("Minimum integer digits : ") + sdf
->getMinimumIntegerDigits()); 
1314 /* @bug 4052223 (API addition request A27) 
1315  * Tests ParsePosition.setErrorPosition() and ParsePosition.getErrorPosition(). 
1317 void NumberFormatRegressionTest::Test4052223(void) 
1320     UErrorCode status 
= U_ZERO_ERROR
; 
1321         DecimalFormat 
*fmt 
= new DecimalFormat(UnicodeString("#,#00.00"), status
); 
1322         if(U_FAILURE(status
)) { 
1323           errcheckln(status
, "Error creating DecimalFormat: %s", u_errorName(status
)); 
1327         failure(status
, "new DecimalFormat"); 
1329         fmt
->parse(UnicodeString("abc3"), num
, status
); 
1330         if(! U_FAILURE(status
)) 
1331             errln(UnicodeString("Bug 4052223 failed : can't parse string \"a\".  Got ") /*+ num*/); 
1332     /*} catch (ParseException foo) { 
1333         logln("Caught expected ParseException : " + foo.getMessage() + " at index : " + foo.getErrorOffset()); 
1338  * API tests for API addition request A9. 
1340 void NumberFormatRegressionTest::Test4061302(void) 
1342     UErrorCode status 
= U_ZERO_ERROR
; 
1343     DecimalFormatSymbols 
*fmt 
= new DecimalFormatSymbols(status
); 
1344     failure(status
, "new DecimalFormatSymbols"); 
1345     UnicodeString 
currency(fmt
->getSymbol(DecimalFormatSymbols::kCurrencySymbol
)); 
1346     UnicodeString 
intlCurrency(fmt
->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
)); 
1347     UnicodeString 
monDecSeparator(fmt
->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
)); 
1348     if (currency 
== UnicodeString("") || 
1349         intlCurrency 
== UnicodeString("") || 
1350         monDecSeparator 
== UnicodeString("")) 
1352         errln("getCurrencySymbols failed, got empty string."); 
1354     UnicodeString monDecSeparatorStr
; 
1355     monDecSeparatorStr
.append(monDecSeparator
); 
1356     logln((UnicodeString
)"Before set ==> Currency : " + currency 
+(UnicodeString
)" Intl Currency : " + intlCurrency 
+ (UnicodeString
)" Monetary Decimal Separator : " + monDecSeparatorStr
); 
1357     fmt
->setSymbol(DecimalFormatSymbols::kCurrencySymbol
, UnicodeString("XYZ")); 
1358     fmt
->setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
, UnicodeString("ABC")); 
1359     fmt
->setSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
, UnicodeString((UChar
)0x002A/*'*'*/)); 
1360     currency 
= fmt
->getSymbol(DecimalFormatSymbols::kCurrencySymbol
); 
1361     intlCurrency 
= fmt
->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
); 
1362     monDecSeparator 
= fmt
->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
); 
1363     if (currency 
!= UnicodeString("XYZ") || 
1364         intlCurrency 
!= UnicodeString("ABC") || 
1365         monDecSeparator 
!= UnicodeString((UChar
)0x002A/*'*'*/)) { 
1366         errln("setCurrencySymbols failed."); 
1368     monDecSeparatorStr
.remove(); 
1369     monDecSeparatorStr
.append(monDecSeparator
); 
1370     logln("After set ==> Currency : " + currency 
+ " Intl Currency : " + intlCurrency 
+ " Monetary Decimal Separator : " + monDecSeparatorStr
); 
1375  * API tests for API addition request A23. FieldPosition.getBeginIndex and 
1376  * FieldPosition.getEndIndex. 
1378 void NumberFormatRegressionTest::Test4062486(void) 
1380     UErrorCode status 
= U_ZERO_ERROR
; 
1381     DecimalFormat 
*fmt 
= new DecimalFormat(UnicodeString("#,##0.00"), status
); 
1382     failure(status
, "new DecimalFormat"); 
1383     UnicodeString formatted
; 
1384     FieldPosition 
field(0); 
1385     double num 
= 1234.5; 
1386     fmt
->format(num
, formatted
, field
); 
1387     if (field
.getBeginIndex() != 0 && field
.getEndIndex() != 5) 
1388         errln(UnicodeString("Format 1234.5 failed. Begin index: ") /*+ field.getBeginIndex() + " End index: " + field.getEndIndex()*/); 
1389     field
.setBeginIndex(7); 
1390     field
.setEndIndex(4); 
1391     if (field
.getBeginIndex() != 7 && field
.getEndIndex() != 4) 
1392         errln("Set begin/end field indexes failed. Begin index: " /*+ field.getBeginIndex() + " End index: " + field.getEndIndex()*/); 
1398  * DecimalFormat.parse incorrectly works with a group separator. 
1400 void NumberFormatRegressionTest::Test4108738(void) 
1402     UErrorCode status 
= U_ZERO_ERROR
; 
1403     DecimalFormatSymbols 
*syms 
= new DecimalFormatSymbols(Locale::getUS(), status
); 
1404     failure(status
, "new DecimalFormatSymbols"); 
1405     DecimalFormat 
*df 
= new DecimalFormat("#,##0.###", syms
, status
); 
1406     if(U_FAILURE(status
)) { 
1407       errcheckln(status
, "Error creating DecimalFormat: %s", u_errorName(status
)); 
1411     failure(status
, "new DecimalFormat"); 
1412     UnicodeString 
text("1.222,111"); 
1414     ParsePosition 
pp(0); 
1415     df
->parse(text
, num
, pp
); 
1417     // {sfb} how to do this (again) ? 
1418     // shouldn't just be another round-trip test, should it? 
1420     FieldPosition 
pos(FieldPosition::DONT_CARE
); 
1421     temp 
= df
->format(num
.getDouble(), temp
, pos
); 
1422     //if (!num.toString().equals("1.222")) 
1423     if (temp 
!= UnicodeString("1.222")) 
1424         //errln("\"" + text + "\"  is parsed as " + num); 
1425         errln("\"" + text 
+ "\"  is parsed as " + temp
); 
1426     text 
= UnicodeString("1.222x111"); 
1427     pp 
= ParsePosition(0); 
1428     df
->parse(text
, num
, pp
); 
1430     temp 
= df
->format(num
.getDouble(), temp
, pos
); 
1431     //if (!num.toString().equals("1.222")) 
1432     if (temp 
!= UnicodeString("1.222")) 
1433         errln("\"" + text 
+ "\"  is parsed as " + temp
); 
1439  * DecimalFormat.format() incorrectly formats negative doubles. 
1441 void NumberFormatRegressionTest::Test4106658(void) 
1443     UErrorCode status 
= U_ZERO_ERROR
; 
1444     DecimalFormat 
*df 
= new DecimalFormat(status
); // Corrected; see 4147706 
1445     if(U_FAILURE(status
)) { 
1446       errcheckln(status
, "Error creating DecimalFormat: %s", u_errorName(status
)); 
1450     failure(status
, "new DecimalFormat"); 
1451     volatile double d1 
= 0.0;   // volatile to prevent code optimization 
1452     double d2 
= -0.0001; 
1453     UnicodeString buffer
; 
1455     FieldPosition 
pos(FieldPosition::DONT_CARE
); 
1457 #if U_PLATFORM == U_PF_HPUX 
1458     d1 
= 0.0 * -1.0;    // old HPUX compiler ignores volatile keyword 
1460     d1 
*= -1.0; // Some compilers have a problem with defining -0.0 
1462     logln("pattern: \"" + df
->toPattern(temp
) + "\""); 
1463     df
->format(d1
, buffer
, pos
); 
1464     if (buffer 
!= UnicodeString("-0")) // Corrected; see 4147706 
1465         errln(UnicodeString("") + d1 
+ "      is formatted as " + buffer
); 
1467     df
->format(d2
, buffer
, pos
); 
1468     if (buffer 
!= UnicodeString("-0")) // Corrected; see 4147706 
1469         errln(UnicodeString("") + d2 
+ "      is formatted as " + buffer
); 
1475  * DecimalFormat.parse returns 0 if string parameter is incorrect. 
1477 void NumberFormatRegressionTest::Test4106662(void) 
1479     UErrorCode status 
= U_ZERO_ERROR
; 
1480     DecimalFormat 
*df 
= new DecimalFormat(status
); 
1481     if(U_FAILURE(status
)) { 
1482       errcheckln(status
, "Error creating DecimalFormat: %s", u_errorName(status
)); 
1486     failure(status
, "new DecimalFormat"); 
1487     UnicodeString 
text("x"); 
1488     ParsePosition 
pos1(0), pos2(0); 
1491     logln("pattern: \"" + df
->toPattern(temp
) + "\""); 
1493     df
->parse(text
, num
, pos1
); 
1494     if (pos1 
== ParsePosition(0)/*num != null*/) { 
1495         errln(UnicodeString("Test Failed: \"") + text 
+ "\" is parsed as " /*+ num*/); 
1498     df 
= new DecimalFormat(UnicodeString("$###.00"), status
); 
1499     failure(status
, "new DecimalFormat"); 
1500     df
->parse(UnicodeString("$"), num
, pos2
); 
1501     if (pos2 
== ParsePosition(0) /*num != null*/){ 
1502         errln(UnicodeString("Test Failed: \"$\" is parsed as ") /*+ num*/); 
1508 /* @bug 4114639 (duplicate of 4106662) 
1509  * NumberFormat.parse doesn't return null 
1511 void NumberFormatRegressionTest::Test4114639(void) 
1513     UErrorCode status 
= U_ZERO_ERROR
; 
1514     NumberFormat 
*format 
= NumberFormat::createInstance(status
); 
1515     if(U_FAILURE(status
)) { 
1516       dataerrln("Error creating DecimalFormat: %s", u_errorName(status
)); 
1520     failure(status
, "NumberFormat::createInstance"); 
1521     UnicodeString 
text("time 10:x"); 
1522     ParsePosition 
pos(8); 
1524     format
->parse(text
, result
, pos
); 
1525     if (/*result != null*/pos
.getErrorIndex() != 8)  
1526         errln(UnicodeString("Should return null but got : ") /*+ result*/); // Should be null; it isn't 
1532  * TODO: this test does not work because we need to use a 64 bit number and a 
1533  * a double only MAY only have 52 bits of precision. 
1534  * DecimalFormat.format(long n) fails if n * multiplier > MAX_LONG. 
1536 void NumberFormatRegressionTest::Test4106664(void) 
1538     UErrorCode status 
= U_ZERO_ERROR
; 
1539     DecimalFormat 
*df 
= new DecimalFormat(status
); 
1540     if(U_FAILURE(status
)) { 
1541       errcheckln(status
, "Error creating DecimalFormat: %s", u_errorName(status
)); 
1545     failure(status
, "new DecimalFormat"); 
1546     // {sfb} long in java is 64 bits 
1547     /*long*/double n 
= 1234567890123456.0; 
1548     /*int*/int32_t m 
= 12345678; 
1549     // {sfb} will this work? 
1550     //BigInteger bigN = BigInteger.valueOf(n); 
1551     //bigN = bigN.multiply(BigInteger.valueOf(m)); 
1552     double bigN 
= n 
* m
; 
1553     df
->setMultiplier(m
); 
1554     df
->setGroupingUsed(FALSE
); 
1556     FieldPosition 
pos(FieldPosition::DONT_CARE
); 
1557     logln("formated: " + 
1558         df
->format(n
, temp
, pos
)); 
1561     sprintf(buf
, "%g", bigN
); 
1562     //logln("expected: " + bigN.toString()); 
1563     logln(UnicodeString("expected: ") + buf
); 
1567 /* @bug 4106667 (duplicate of 4106658) 
1568  * DecimalFormat.format incorrectly formats -0.0. 
1570 void NumberFormatRegressionTest::Test4106667(void) 
1572     UErrorCode status 
= U_ZERO_ERROR
; 
1573     DecimalFormat 
*df 
= new DecimalFormat(status
); 
1574     if(U_FAILURE(status
)) { 
1575       errcheckln(status
, "Error creating DecimalFormat: %s", u_errorName(status
)); 
1579     failure(status
, "new DecimalFormat"); 
1580     UChar foo 
[] = { 0x002B }; 
1581     UnicodeString 
bar(foo
, 1, 1); 
1582     volatile double d 
= 0.0;   // volatile to prevent code optimization 
1584     UnicodeString buffer
; 
1585     FieldPosition 
pos(FieldPosition::DONT_CARE
); 
1587     logln("pattern: \"" + df
->toPattern(temp
) + "\""); 
1588 #if U_PLATFORM == U_PF_HPUX 
1589     d 
= 0.0 * -1.0;    // old HPUX compiler ignores volatile keyword 
1591     d 
*= -1.0; // Some compilers have a problem with defining -0.0 
1593     df
->setPositivePrefix(/*"+"*/bar
); 
1594     df
->format(d
, buffer
, pos
); 
1595     if (buffer 
!= UnicodeString("-0")) // Corrected; see 4147706 
1596         errln(/*d + */UnicodeString("  is formatted as ") + buffer
); 
1602  * DecimalFormat.setMaximumIntegerDigits() works incorrectly. 
1604 #if U_PLATFORM == U_PF_OS390 
1605 #   define MAX_INT_DIGITS 70 
1607 #   define MAX_INT_DIGITS 128 
1610 void NumberFormatRegressionTest::Test4110936(void) 
1612     UErrorCode status 
= U_ZERO_ERROR
; 
1613     NumberFormat 
*nf 
= NumberFormat::createInstance(status
); 
1614     if(U_FAILURE(status
)) { 
1615       dataerrln("Error creating DecimalFormat: %s", u_errorName(status
)); 
1619     failure(status
, "NumberFormat::createInstance"); 
1620     nf
->setMaximumIntegerDigits(MAX_INT_DIGITS
); 
1621     logln("setMaximumIntegerDigits(MAX_INT_DIGITS)"); 
1622     if (nf
->getMaximumIntegerDigits() != MAX_INT_DIGITS
) 
1623         errln(UnicodeString("getMaximumIntegerDigits() returns ") + 
1624             nf
->getMaximumIntegerDigits()); 
1630  * Locale data should use generic currency symbol 
1632  * 1) Make sure that all currency formats use the generic currency symbol. 
1633  * 2) Make sure we get the same results using the generic symbol or a 
1636 void NumberFormatRegressionTest::Test4122840(void) 
1639     const Locale 
*locales 
= Locale::getAvailableLocales(count
); 
1641     for (int i 
= 0; i 
< count
; i
++) { 
1642         UErrorCode status 
= U_ZERO_ERROR
; 
1643         ResourceBundle 
*rb 
= new ResourceBundle( 
1644             NULL
/*"java.text.resources.LocaleElements"*/,  
1645             locales
[i
], status
); 
1646         failure(status
, "new ResourceBundle"); 
1647         ResourceBundle numPat 
= rb
->getWithFallback("NumberElements", status
); 
1648         failure(status
, "rb.get(NumberElements)"); 
1649         numPat 
= numPat
.getWithFallback("latn",status
); 
1650         failure(status
, "rb.get(latn)"); 
1651         numPat 
= numPat
.getWithFallback("patterns",status
); 
1652         failure(status
, "rb.get(patterns)"); 
1653         numPat 
= numPat
.getWithFallback("currencyFormat",status
); 
1654         failure(status
, "rb.get(currencyFormat)"); 
1656         // Get the currency pattern for this locale.  We have to fish it 
1657         // out of the ResourceBundle directly, since DecimalFormat.toPattern 
1658         // will return the localized symbol, not \00a4 
1660         UnicodeString pattern 
= numPat
.getString(status
); 
1661         failure(status
, "rb->getString()"); 
1663         UChar fo
[] = { 0x00A4 }; 
1664         UnicodeString 
foo(fo
, 1, 1); 
1666         //if (pattern.indexOf("\u00A4") == -1 ) { 
1667         if (pattern
.indexOf(foo
) == -1 ) { 
1668             errln(UnicodeString("Currency format for ") + UnicodeString(locales
[i
].getName()) + 
1669                     " does not contain generic currency symbol:" + 
1673         // Create a DecimalFormat using the pattern we got and format a number 
1674         DecimalFormatSymbols 
*symbols 
= new DecimalFormatSymbols(locales
[i
], status
); 
1675         failure(status
, "new DecimalFormatSymbols"); 
1676         DecimalFormat 
*fmt1 
= new DecimalFormat(pattern
, *symbols
, status
); 
1677         failure(status
, "new DecimalFormat"); 
1679         UnicodeString result1
; 
1680         FieldPosition 
pos(FieldPosition::DONT_CARE
); 
1681         result1 
= fmt1
->format(1.111, result1
, pos
); 
1684         // Now substitute in the locale's currency symbol and create another 
1685         // pattern.  We have to skip locales where the currency symbol 
1686         // contains decimal separators, because that confuses things 
1688         UChar ba
[] = { 0x002E/*'.'*/ }; 
1689         UnicodeString 
bar(ba
, 1, 1); 
1691         if (symbols
->getSymbol(DecimalFormatSymbols::kCurrencySymbol
).indexOf(bar
) == -1) { 
1692             // {sfb} Also, switch the decimal separator to the monetary decimal 
1693             // separator to mimic the behavior of a currency format 
1694             symbols
->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
, 
1695                 symbols
->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
)); 
1697             UnicodeString 
buf(pattern
); 
1698             for (int j 
= 0; j 
< buf
.length(); j
++) { 
1699                 if (buf
[j
] == 0x00a4 ) { 
1700                     if(buf
[j 
+ 1] == 0x00a4) { 
1701                         // {sfb} added to support double currency marker (intl currency sign) 
1702                         buf
.replace(j
, /*j+*/2, symbols
->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
)); 
1703                         j 
+= symbols
->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
).length(); 
1706                         buf
.replace(j
, /*j+*/1, symbols
->getSymbol(DecimalFormatSymbols::kCurrencySymbol
));  
1707                         j 
+= symbols
->getSymbol(DecimalFormatSymbols::kCurrencySymbol
).length() - 1; 
1712             DecimalFormat 
*fmt2 
= new DecimalFormat(buf
, *symbols
, status
); 
1713             failure(status
, "new DecimalFormat"); 
1715             // Get the currency (if there is one) so we can set the rounding and fraction 
1716             const UChar 
*currency 
= fmt1
->getCurrency(); 
1717             if (*currency 
!= 0) { 
1718                 double rounding 
= ucurr_getRoundingIncrement(currency
, &status
); 
1719                 int32_t frac 
= ucurr_getDefaultFractionDigits(currency
, &status
); 
1720                 if (U_SUCCESS(status
)) { 
1721                     fmt2
->setRoundingIncrement(rounding
); 
1722                     fmt2
->setMinimumFractionDigits(frac
); 
1723                     fmt2
->setMaximumFractionDigits(frac
); 
1726                     failure(status
, "Fetching currency rounding/fractions"); 
1730             UnicodeString result2
; 
1731             fmt2
->format(1.111, result2
, pos
); 
1733             if (result1 
!= result2
) { 
1734                 errln("Results for " + (UnicodeString
)(locales
[i
].getName()) + " differ: " + 
1735                         result1 
+ " vs " + result2
); 
1748  * DecimalFormat.format() delivers wrong string. 
1750 void NumberFormatRegressionTest::Test4125885(void) 
1752     UErrorCode status 
= U_ZERO_ERROR
; 
1753     double rate 
= 12.34; 
1754     DecimalFormat 
*formatDec 
= new DecimalFormat ("000.00", status
); 
1755     if(U_FAILURE(status
)) { 
1756       errcheckln(status
, "Error creating DecimalFormat: %s", u_errorName(status
)); 
1760     failure(status
, "new DecimalFormat"); 
1762     logln("toPattern: " + formatDec
->toPattern(temp
)); 
1763     UnicodeString rateString
; 
1764     FieldPosition 
pos(FieldPosition::DONT_CARE
); 
1765     rateString 
= formatDec
->format(rate
, rateString
, pos
); 
1766     if (rateString 
!= UnicodeString("012.34")) 
1767         errln("result : " + rateString 
+ " expected : 012.34"); 
1769     delete formatDec
;// = null; 
1770     formatDec 
= new DecimalFormat ("+000.00%;-000.00%", status
); 
1771     failure(status
, "new DecimalFormat"); 
1772     logln("toPattern: " + formatDec
->toPattern(temp
)); 
1773     rateString
.remove(); 
1774     rateString 
= formatDec
->format(rate
, rateString
, pos
); 
1775     if (rateString 
!= UnicodeString("+012.34%")) 
1776         errln("result : " + rateString 
+ " expected : +012.34%"); 
1783  * DecimalFormat produces extra zeros when formatting numbers. 
1785 void NumberFormatRegressionTest::Test4134034(void)  
1787     UErrorCode status 
= U_ZERO_ERROR
; 
1788     DecimalFormat 
*nf 
= new DecimalFormat("##,###,###.00", status
); 
1789     if (!failure(status
, "new DecimalFormat")) { 
1791         FieldPosition 
pos(FieldPosition::DONT_CARE
); 
1792         f 
= nf
->format(9.02, f
, pos
); 
1793         if (f 
== UnicodeString("9.02"))  
1796             errln("9.02 -> " + f 
+ "; want 9.02"); 
1799         f 
= nf
->format((int32_t)0, f
, pos
); 
1800         if (f 
== UnicodeString(".00"))  
1803             errln("0 -> " + f 
+ "; want .00"); 
1811  * CANNOT REPRODUCE - This bug could not be reproduced.  It may be 
1812  * a duplicate of 4134034. 
1814  * JDK 1.1.6 Bug, did NOT occur in 1.1.5 
1815  * Possibly related to bug 4125885. 
1817  * This class demonstrates a regression in version 1.1.6 
1818  * of DecimalFormat class. 
1821  * Value 1.2 Format #.00 Result '01.20' !!!wrong 
1822  * Value 1.2 Format 0.00 Result '001.20' !!!wrong 
1823  * Value 1.2 Format 00.00 Result '0001.20' !!!wrong 
1824  * Value 1.2 Format #0.0# Result '1.2' 
1825  * Value 1.2 Format #0.00 Result '001.20' !!!wrong 
1828  * Value 1.2 Format #.00 Result '1.20' 
1829  * Value 1.2 Format 0.00 Result '1.20' 
1830  * Value 1.2 Format 00.00 Result '01.20' 
1831  * Value 1.2 Format #0.0# Result '1.2' 
1832  * Value 1.2 Format #0.00 Result '1.20' 
1834 void NumberFormatRegressionTest::Test4134300(void) { 
1835     UnicodeString DATA 
[] = { 
1836      // Pattern      Expected string 
1837         UnicodeString("#.00"),      UnicodeString("1.20"), 
1838         UnicodeString("0.00"),      UnicodeString("1.20"), 
1839         UnicodeString("00.00"),     UnicodeString("01.20"), 
1840         UnicodeString("#0.0#"),     UnicodeString("1.2"), 
1841         UnicodeString("#0.00"),     UnicodeString("1.20") 
1844     for (int i
=0; i
< 10; i
+=2) { 
1845         UnicodeString result
; 
1846         UErrorCode status 
= U_ZERO_ERROR
; 
1847         DecimalFormat 
*df 
= new DecimalFormat(DATA
[i
], status
); 
1848         if (!failure(status
, "new DecimalFormat")) { 
1849             FieldPosition 
pos(FieldPosition::DONT_CARE
); 
1850             result 
= df
->format(1.2, result
, pos
); 
1851             if (result 
!= DATA
[i
+1]) { 
1852                 errln("Fail: 1.2 x " + DATA
[i
] + " = " + result 
+ 
1853                       "; want " + DATA
[i
+1]); 
1856                 logln("Ok: 1.2 x " + DATA
[i
] + " = " + result
); 
1866  * Empty pattern produces double negative prefix. 
1868 void NumberFormatRegressionTest::Test4140009(void)  
1870     UErrorCode status 
= U_ZERO_ERROR
; 
1871     DecimalFormatSymbols 
*syms 
= new DecimalFormatSymbols(Locale::getEnglish(), status
); 
1872     failure(status
, "new DecimalFormatSymbols"); 
1873     DecimalFormat 
*f 
= new DecimalFormat(UnicodeString(""), syms
, status
); 
1874     if (!failure(status
, "new DecimalFormat")) { 
1876         FieldPosition 
pos(FieldPosition::DONT_CARE
); 
1877         s 
= f
->format(123.456, s
, pos
); 
1878         if (s 
!= UnicodeString("123.456")) 
1879             errln("Fail: Format empty pattern x 123.456 => " + s
); 
1881         s 
= f
->format(-123.456, s
, pos
); 
1882         if (s 
!= UnicodeString("-123.456")) 
1883             errln("Fail: Format empty pattern x -123.456 => " + s
); 
1890  * BigDecimal numbers get their fractions truncated by NumberFormat. 
1892 // {sfb} not pertinent in C++ ?? 
1893 void NumberFormatRegressionTest::Test4141750(void) { 
1895         UnicodeString str("12345.67"); 
1896         BigDecimal bd = new BigDecimal(str); 
1897         String sd = NumberFormat.getInstance(Locale.US).format(bd); 
1898         if (!sd.endsWith("67")) errln("Fail: " + str + " x format -> " + sd); 
1900     catch (Exception e) { 
1901         errln(e.toString()); 
1902         e.printStackTrace(); 
1908  * DecimalFormat toPattern() doesn't quote special characters or handle 
1911 void NumberFormatRegressionTest::Test4145457() { 
1913     UErrorCode status 
= U_ZERO_ERROR
; 
1914     NumberFormat 
*nff 
= NumberFormat::createInstance(status
); 
1915     if (failure(status
, "NumberFormat::createInstance", TRUE
)){ 
1919     DecimalFormat 
*nf 
= dynamic_cast<DecimalFormat 
*>(nff
); 
1921         errln("DecimalFormat needed to continue"); 
1925     DecimalFormatSymbols 
*sym 
= (DecimalFormatSymbols
*) nf
->getDecimalFormatSymbols(); 
1926     sym
->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
, (UChar
)/*'\''*/0x0027); 
1927     nf
->setDecimalFormatSymbols(*sym
); 
1928     double pi 
= 3.14159; 
1930     UnicodeString PATS 
[] = {  
1931         UnicodeString("#.00 'num''ber'"), UnicodeString("''#.00''") 
1934     for (int32_t i
=0; i
<2; ++i
) { 
1935         nf
->applyPattern(PATS
[i
], status
); 
1936         failure(status
, "nf->applyPattern"); 
1938         FieldPosition 
pos(FieldPosition::DONT_CARE
); 
1939         out 
= nf
->format(pi
, out
, pos
); 
1941         pat 
= nf
->toPattern(pat
); 
1943         ParsePosition 
pp(0); 
1944         nf
->parse(out
, num
, pp
); 
1945         double val 
= num
.getDouble(); 
1947         nf
->applyPattern(pat
, status
); 
1948         failure(status
, "nf->applyPattern"); 
1950         out2 
= nf
->format(pi
, out2
, pos
); 
1952         pat2 
= nf
->toPattern(pat2
); 
1954         nf
->parse(out2
, num
, pp
); 
1955         double val2 
= num
.getDouble(); 
1958             errln("Fail with \"" + PATS
[i
] + "\": Patterns should concur, \"" + 
1959                 pat 
+ "\" vs. \"" + pat2 
+ "\""); 
1961             logln("Ok \"" + PATS
[i
] + "\" toPattern() -> \"" + pat 
+ '"'); 
1963         if (val 
== val2 
&& out 
== out2
) { 
1964             logln(UnicodeString("Ok ") + pi 
+ " x \"" + PATS
[i
] + "\" -> \"" + 
1965                 out 
+ "\" -> " + val 
+ " -> \"" + 
1966                 out2 
+ "\" -> " + val2
); 
1969             errln(UnicodeString("Fail ") + pi 
+ " x \"" + PATS
[i
] + "\" -> \"" + 
1970                 out 
+ "\" -> " + val 
+ " -> \"" + 
1971                 out2 
+ "\" -> " + val2
); 
1975     catch (ParseException e) { 
1976         errln("Fail: " + e); 
1977         e.printStackTrace(); 
1985  * DecimalFormat.applyPattern() sets minimum integer digits incorrectly. 
1987  * This bug is a duplicate of 4139344, which is a duplicate of 4134300 
1989 void NumberFormatRegressionTest::Test4147295(void)  
1991     UErrorCode status 
= U_ZERO_ERROR
; 
1992     DecimalFormat 
*sdf 
= new DecimalFormat(status
); 
1993     UnicodeString 
pattern("#,###"); 
1994     logln("Applying pattern \"" + pattern 
+ "\""); 
1995     sdf
->applyPattern(pattern
, status
); 
1996     if (!failure(status
, "sdf->applyPattern")) { 
1997         int minIntDig 
= sdf
->getMinimumIntegerDigits(); 
1998         if (minIntDig 
!= 0) { 
1999             errln("Test failed"); 
2000             errln(UnicodeString(" Minimum integer digits : ") + minIntDig
); 
2002             errln(UnicodeString(" new pattern: ") + sdf
->toPattern(temp
)); 
2004             logln("Test passed"); 
2005             logln(UnicodeString(" Minimum integer digits : ") + minIntDig
); 
2013  * DecimalFormat formats -0.0 as +0.0 
2014  * See also older related bug 4106658, 4106667 
2016 void NumberFormatRegressionTest::Test4147706(void)  
2018     UErrorCode status 
= U_ZERO_ERROR
; 
2019     DecimalFormat 
*df 
= new DecimalFormat("#,##0.0##", status
); 
2020     failure(status
, "new DecimalFormat"); 
2021     DecimalFormatSymbols 
*syms 
= new DecimalFormatSymbols(Locale::getEnglish(), status
); 
2022     if (!failure(status
, "new DecimalFormatSymbols")) { 
2024         UnicodeString f2
, temp
; 
2025         FieldPosition 
pos(FieldPosition::DONT_CARE
); 
2026         volatile double d1 
= 0.0;   // volatile to prevent code optimization 
2027         double d2 
= -0.0001; 
2029 #if U_PLATFORM == U_PF_HPUX 
2030         d1 
= 0.0 * -1.0;    // old HPUX compiler ignores volatile keyword 
2032         d1 
*= -1.0; // Some compilers have a problem with defining -0.0 
2034         df
->adoptDecimalFormatSymbols(syms
); 
2035         f1 
= df
->format(d1
, f1
, pos
); 
2036         f2 
= df
->format(d2
, f2
, pos
); 
2037         if (f1 
!= UnicodeString("-0.0")) { 
2038             errln(UnicodeString("") + d1 
+ UnicodeString(" x \"") + df
->toPattern(temp
) + "\" is formatted as \"" + f1 
+ '"'); 
2040         if (f2 
!= UnicodeString("-0.0")) { 
2041             errln(UnicodeString("") + d2 
+ UnicodeString(" x \"") + df
->toPattern(temp
) + "\" is formatted as \"" + f2 
+ '"'); 
2049 // Not applicable, since no serialization in C++ 
2050 /*class myformat implements Serializable 
2052 DateFormat _dateFormat = DateFormat.getDateInstance(); 
2056     GregorianCalendar calendar = new GregorianCalendar(); 
2057     Date t = calendar.getTime(); 
2058     String nowStr = _dateFormat.format(t); 
2065  * NumberFormat cannot format Double.MAX_VALUE 
2067 // TODO: make this test actually test something 
2069 NumberFormatRegressionTest::Test4162198(void)  
2071     // for some reason, DBL_MAX will not round trip. (bug in sprintf/atof) 
2072     double dbl 
= INT32_MAX 
* 1000.0; 
2073     UErrorCode status 
= U_ZERO_ERROR
; 
2074     NumberFormat 
*f 
= NumberFormat::createInstance(status
); 
2075     if(U_FAILURE(status
)) { 
2076         dataerrln("Couldn't create number format - %s", u_errorName(status
)); 
2079     f
->setMaximumFractionDigits(INT32_MAX
); 
2080     f
->setMaximumIntegerDigits(INT32_MAX
); 
2083     logln(UnicodeString("The number ") + dbl 
+ " formatted to " + s
); 
2086     f
->parse(s
, n
, status
); 
2087     if(U_FAILURE(status
)) 
2088         errln("Couldn't parse!"); 
2089     //} catch (java.text.ParseException e) { 
2090     //    errln("Caught a ParseException:"); 
2091     //    e.printStackTrace(); 
2094     //logln("The string " + s + " parsed as " + n); 
2096     // {dlf} The old code assumes n is a double, but it isn't any more... 
2097     // Formattable apparently does not and never did interconvert... too bad. 
2098     //if(n.getDouble() != dbl) { 
2099     //    errln("Round trip failure"); 
2101     if (n
.getInt64() != dbl
) { 
2102         errln("Round trip failure"); 
2110  * NumberFormat does not parse negative zero. 
2113 NumberFormatRegressionTest::Test4162852(void)  
2115     UErrorCode status 
= U_ZERO_ERROR
; 
2116     for(int32_t i
=0; i 
< 2; ++i
) { 
2117         NumberFormat 
*f 
= (i 
== 0) ? NumberFormat::createInstance(status
) 
2118             : NumberFormat::createPercentInstance(status
); 
2119         if(U_FAILURE(status
)) { 
2120             dataerrln("Couldn't create number format - %s", u_errorName(status
)); 
2128         f
->parse(s
, n
, status
); 
2129         if(U_FAILURE(status
)) 
2130             errln("Couldn't parse!"); 
2131         double e 
= n
.getDouble(); 
2132         logln(UnicodeString("") + 
2134               '"' + s 
+ '"' + " -> " + e
); 
2135 #if (U_PLATFORM == U_PF_OS390 && !defined(IEEE_754)) || U_PLATFORM == U_PF_OS400 
2138         if (e 
!= 0.0 || 1.0/e 
> 0.0) { 
2140             logln("Failed to parse negative zero"); 
2146 static double _u_abs(double a
) { return a
<0?-a
:a
; } 
2149  * May 17 1999 sync up - liu 
2151  * NumberFormat truncates data 
2153 void NumberFormatRegressionTest::Test4167494(void) { 
2154     UErrorCode status 
= U_ZERO_ERROR
; 
2155     NumberFormat 
*fmt 
= NumberFormat::createInstance(Locale::getUS(), status
); 
2156     if (failure(status
, "NumberFormat::createInstance", TRUE
)){ 
2161     double a 
= DBL_MAX 
* 0.99; // DBL_MAX itself overflows to +Inf 
2165     fmt
->parse(s
, num
, status
); 
2166     failure(status
, "Parse"); 
2167     if (num
.getType() == Formattable::kDouble 
&& 
2168         _u_abs(num
.getDouble() - a
) / a 
< 0.01) { // RT within 1% 
2169         logln(UnicodeString("") + a 
+ " -> \"" + s 
+ "\" -> " + 
2170               toString(num
) + " ok"); 
2172         errln(UnicodeString("") + a 
+ " -> \"" + s 
+ "\" -> " + 
2173               toString(num
) + " FAIL"); 
2176     // We don't test Double.MIN_VALUE because the locale data for the US 
2177     // currently doesn't specify enough digits to display Double.MIN_VALUE. 
2178     // This is correct for now; however, we leave this here as a reminder 
2179     // in case we want to address this later. 
2185  * May 17 1999 sync up - liu 
2187  * DecimalFormat.parse() fails when ParseIntegerOnly set to true 
2189 void NumberFormatRegressionTest::Test4170798(void) { 
2190     UErrorCode status 
= U_ZERO_ERROR
; 
2191     NumberFormat 
*nf 
= NumberFormat::createInstance(Locale::getUS(), status
); 
2192     if (failure(status
, "NumberFormat::createInstance", TRUE
)){ 
2196     DecimalFormat 
*df 
= dynamic_cast<DecimalFormat 
*>(nf
); 
2198         errln("DecimalFormat needed to continue"); 
2201     df
->setParseIntegerOnly(TRUE
); 
2203     ParsePosition 
pos(0); 
2204     df
->parse("-0.0", n
, pos
); 
2205     if (n
.getType() != Formattable::kLong
 
2206         || n
.getLong() != 0) { 
2207         errln(UnicodeString("FAIL: parse(\"-0.0\") returns ") + toString(n
)); 
2213  * May 17 1999 sync up - liu 
2214  * toPattern only puts the first grouping separator in. 
2216 void NumberFormatRegressionTest::Test4176114(void) { 
2217     const char* DATA
[] = { 
2219         "000", "#000", // No grouping 
2220         "#000", "#000", // No grouping 
2224         "00,000", "#00,000", 
2225         "000,000", "#,000,000", 
2226         "0,000,000,000,000.0000", "#0,000,000,000,000.0000", // Reported 
2228     int DATA_length 
= (int)(sizeof(DATA
) / sizeof(DATA
[0])); 
2229     UErrorCode status 
= U_ZERO_ERROR
; 
2231     for (int i
=0; i
<DATA_length
; i
+=2) { 
2232         DecimalFormat 
df(DATA
[i
], status
); 
2233         if (!failure(status
, "DecimalFormat constructor")) { 
2235             UnicodeString 
exp(DATA
[i
+1]); 
2237                 errln(UnicodeString("FAIL: ") + DATA
[i
] + " -> " + 
2238                       s 
+ ", want " + exp
); 
2245  * May 17 1999 sync up - liu 
2247  * DecimalFormat is incorrectly rounding numbers like 1.2501 to 1.2 
2249 void NumberFormatRegressionTest::Test4179818(void) { 
2250     const char* DATA
[] = { 
2251         // Input  Pattern  Expected output 
2252         "1.2511", "#.#",   "1.3", 
2253         "1.2501", "#.#",   "1.3", 
2256     int DATA_length 
= (int)(sizeof(DATA
) / sizeof(DATA
[0]));  
2262     UErrorCode status 
= U_ZERO_ERROR
; 
2263     DecimalFormatSymbols 
sym(Locale::getUS(), status
); 
2264     failure(status
, "Construct DecimalFormatSymbols"); 
2265     DecimalFormat 
fmt("#", sym
, status
); 
2266     if (!failure(status
, "Construct DecimalFormat")) { 
2267         for (int i
=0; i
<DATA_length
; i
+=3) { 
2268             double in 
= DOUBLE
[i
/3]; 
2269             UnicodeString 
pat(DATA
[i
+1]); 
2270             UnicodeString 
exp(DATA
[i
+2]); 
2271             fmt
.applyPattern(pat
, status
); 
2272             failure(status
, "applyPattern"); 
2275             fmt
.format(in
, out
, pos
); 
2277                 logln(UnicodeString("Ok: ") + in 
+ " x " + pat 
+ " = " + out
); 
2279                 errln(UnicodeString("FAIL: ") + in 
+ " x  " + pat 
+ " = " + out 
+ 
2280                       ", expected " + exp
); 
2287  * May 17 1999 sync up - liu 
2288  * Some DecimalFormatSymbols changes are not picked up by DecimalFormat. 
2289  * This includes the minus sign, currency symbol, international currency 
2290  * symbol, percent, and permille.  This is filed as bugs 4212072 and 
2293 void NumberFormatRegressionTest::Test4212072(void) { 
2294     UErrorCode status 
= U_ZERO_ERROR
; 
2295     DecimalFormatSymbols 
sym(Locale::getUS(), status
); 
2297     failure(status
, "DecimalFormatSymbols ct", Locale::getUS()); 
2298     DecimalFormat 
fmt(UnicodeString("#"), sym
, status
); 
2299     if(failure(status
, "DecimalFormat ct", Locale::getUS())) { 
2306     sym
.setSymbol(DecimalFormatSymbols::kMinusSignSymbol
, (UChar
)0x5e); 
2307     fmt
.setDecimalFormatSymbols(sym
); 
2309     if (fmt
.format((int32_t)-1, s
, pos
) != UNICODE_STRING("^1", 2)) { 
2310         errln(UnicodeString("FAIL: -1 x (minus=^) -> ") + s 
+ 
2314     if (fmt
.getNegativePrefix(s
) != UnicodeString((UChar
)0x5e)) { 
2315         errln(UnicodeString("FAIL: (minus=^).getNegativePrefix -> ") + 
2318     sym
.setSymbol(DecimalFormatSymbols::kMinusSignSymbol
, (UChar
)0x2d); 
2320     fmt
.applyPattern(UnicodeString("#%"), status
); 
2321     failure(status
, "applyPattern percent"); 
2322     sym
.setSymbol(DecimalFormatSymbols::kPercentSymbol
, (UChar
)0x5e); 
2323     fmt
.setDecimalFormatSymbols(sym
); 
2325     if (fmt
.format(0.25, s
, pos
) != UNICODE_STRING("25^", 3)) { 
2326         errln(UnicodeString("FAIL: 0.25 x (percent=^) -> ") + s 
+ 
2330     if (fmt
.getPositiveSuffix(s
) != UnicodeString((UChar
)0x5e)) { 
2331         errln(UnicodeString("FAIL: (percent=^).getPositiveSuffix -> ") + 
2334     sym
.setSymbol(DecimalFormatSymbols::kPercentSymbol
, (UChar
)0x25); 
2336     fmt
.applyPattern(str("#\\u2030"), status
); 
2337     failure(status
, "applyPattern permill"); 
2338     sym
.setSymbol(DecimalFormatSymbols::kPerMillSymbol
, (UChar
)0x5e); 
2339     fmt
.setDecimalFormatSymbols(sym
); 
2341     if (fmt
.format(0.25, s
, pos
) != UNICODE_STRING("250^", 4)) { 
2342         errln(UnicodeString("FAIL: 0.25 x (permill=^) -> ") + s 
+ 
2346     if (fmt
.getPositiveSuffix(s
) != UnicodeString((UChar
)0x5e)) { 
2347         errln(UnicodeString("FAIL: (permill=^).getPositiveSuffix -> ") + 
2350     sym
.setSymbol(DecimalFormatSymbols::kPerMillSymbol
, (UChar
)0x2030); 
2352     fmt
.applyPattern(str("\\u00A4#.00"), status
); 
2353     failure(status
, "applyPattern currency"); 
2354     sym
.setSymbol(DecimalFormatSymbols::kCurrencySymbol
, "usd"); 
2355     fmt
.setDecimalFormatSymbols(sym
); 
2357     if (fmt
.format(12.5, s
, pos
) != UnicodeString("usd12.50")) { 
2358         errln(UnicodeString("FAIL: 12.5 x (currency=usd) -> ") + s 
+ 
2362     if (fmt
.getPositivePrefix(s
) != UnicodeString("usd")) { 
2363         errln(UnicodeString("FAIL: (currency=usd).getPositivePrefix -> ") + 
2366     sym
.setSymbol(DecimalFormatSymbols::kCurrencySymbol
, "$"); 
2368     fmt
.applyPattern(str("\\u00A4\\u00A4#.00"), status
); 
2369     failure(status
, "applyPattern intl currency"); 
2370     sym
.setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
, "DOL"); 
2371     fmt
.setDecimalFormatSymbols(sym
); 
2373     if (fmt
.format(12.5, s
, pos
) != UnicodeString("DOL12.50")) { 
2374         errln(UnicodeString("FAIL: 12.5 x (intlcurrency=DOL) -> ") + s 
+ 
2378     if (fmt
.getPositivePrefix(s
) != UnicodeString("DOL")) { 
2379         errln(UnicodeString("FAIL: (intlcurrency=DOL).getPositivePrefix -> ") + 
2382     sym
.setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
, "USD"); 
2384     // Since the pattern logic has changed, make sure that patterns round 
2385     // trip properly.  Test stream in/out integrity too. 
2387     const Locale
* avail 
= NumberFormat::getAvailableLocales(n
); 
2388     static const char* type
[] = { 
2393     for (int i
=0; i
<n
; ++i
) { 
2394         for (int j
=0; j
<3; ++j
) { 
2395             status 
= U_ZERO_ERROR
; 
2399                 nf 
= NumberFormat::createInstance(avail
[i
], status
); 
2400                 failure(status
, "createInstance", avail
[i
]); 
2403                 nf 
= NumberFormat::createCurrencyInstance(avail
[i
], status
); 
2404                 failure(status
, "createCurrencyInstance", avail
[i
]); 
2407                 nf 
= NumberFormat::createPercentInstance(avail
[i
], status
); 
2408                 failure(status
, "createPercentInstance", avail
[i
]); 
2411             if (U_FAILURE(status
)) { 
2414             DecimalFormat 
*df 
= (DecimalFormat
*) nf
; 
2416             // Test toPattern/applyPattern round trip 
2419             DecimalFormatSymbols 
symb(avail
[i
], status
); 
2420             failure(status
, "Construct DecimalFormatSymbols", avail
[i
]); 
2421             DecimalFormat 
f2(pat
, symb
, status
); 
2423                         UnicodeString("Construct DecimalFormat(") + pat 
+ ")")) { 
2428                 errln(UnicodeString("FAIL: ") + type
[j
] + avail
[i
].getDisplayName(l
) + 
2430                       "\" -> \"" + f2
.toPattern(p
) + "\""); 
2433                 logln(UnicodeString("PASS: ") + type
[j
] + avail
[i
].getDisplayName(l
) + 
2438             // Test toLocalizedPattern/applyLocalizedPattern round trip 
2439             df
->toLocalizedPattern(pat
); 
2440             f2
.applyLocalizedPattern(pat
, status
); 
2442                     UnicodeString("applyLocalizedPattern(") + pat 
+ ")", avail
[i
]); 
2443             if (U_FAILURE(status
)) { 
2447             // Make sure we set the currency attributes appropriately 
2448             if (j 
== 1) {   // Currency format 
2449                 f2
.setCurrency(f2
.getCurrency(), status
); 
2452                     UnicodeString("setCurrency() for (") + pat 
+ ")", avail
[i
]); 
2453             if (U_FAILURE(status
)) { 
2459                 errln(UnicodeString("FAIL: ") + type
[j
] + avail
[i
].getDisplayName(l
) + 
2460                       " -> localized \"" + pat 
+ 
2461                       "\" -> \"" + f2
.toPattern(p
) + "\""); 
2466             // Test writeObject/readObject round trip 
2467             // NOT ON ICU -- Java only 
2473  * May 17 1999 sync up - liu 
2474  * DecimalFormat.parse() fails for mulipliers 2^n. 
2476 void NumberFormatRegressionTest::Test4216742(void) { 
2477     UErrorCode status 
= U_ZERO_ERROR
; 
2478     DecimalFormat 
*fmt 
= (DecimalFormat
*) NumberFormat::createInstance(Locale::getUS(), status
); 
2479     if (failure(status
, "createInstance", Locale::getUS(), TRUE
)){ 
2483     int32_t DATA
[] = { INT32_MIN
, INT32_MAX
, -100000000, 100000000 }; 
2484     int DATA_length 
= (int)(sizeof(DATA
) / sizeof(DATA
[0])); 
2485     for (int i
=0; i
<DATA_length
; ++i
) { 
2486         UnicodeString 
str((UnicodeString
)"" + DATA
[i
]); 
2487         for (int m 
= 1; m 
<= 100; m
++) { 
2488             fmt
->setMultiplier(m
); 
2490             fmt
->parse(str
, num
, status
); 
2491             failure(status
, "parse", Locale::getUS()); 
2492             if (num
.getType() != Formattable::kLong 
&& 
2493                 num
.getType() != Formattable::kDouble
) { 
2494                 errln(UnicodeString("FAIL: Wanted number, got ") + 
2497                 double d 
= num
.getType() == Formattable::kDouble 
? 
2498                     num
.getDouble() : (double) num
.getLong(); 
2499                 if ((d 
> 0) != (DATA
[i
] > 0)) { 
2500                     errln(UnicodeString("\"") + str 
+ "\" parse(x " + 
2501                           fmt
->getMultiplier() + 
2502                           ") => " + toString(num
)); 
2511  * May 17 1999 sync up - liu 
2512  * DecimalFormat formats 1.001 to "1.00" instead of "1" with 2 fraction 
2515 void NumberFormatRegressionTest::Test4217661(void) { 
2516     const double D
[] = {  0.001, 1.001, 0.006,  1.006 }; 
2517     const char*  S
[] = { "0",   "1",   "0.01", "1.01" }; 
2518     int D_length 
= (int)(sizeof(D
) / sizeof(D
[0])); 
2519     UErrorCode status 
= U_ZERO_ERROR
; 
2520     NumberFormat 
*fmt 
= NumberFormat::createInstance(Locale::getUS(), status
); 
2521     if (failure(status
, "createInstance", Locale::getUS(), TRUE
)){ 
2525     fmt
->setMaximumFractionDigits(2); 
2526     for (int i
=0; i
<D_length
; i
++) { 
2528         fmt
->format(D
[i
], s
); 
2529         if (s 
!= UnicodeString(S
[i
])) { 
2530             errln(UnicodeString("FAIL: Got ") + s 
+ ", exp " + S
[i
]);  
2537  * alphaWorks upgrade 
2539 void NumberFormatRegressionTest::Test4161100(void) { 
2540     UErrorCode status 
= U_ZERO_ERROR
; 
2541     NumberFormat 
*nf 
= NumberFormat::createInstance(Locale::getUS(), status
); 
2542     if (failure(status
, "createInstance", Locale::getUS(), TRUE
)){ 
2546     nf
->setMinimumFractionDigits(1); 
2547     nf
->setMaximumFractionDigits(1); 
2552     logln(UnicodeString() + a 
+ " x " + 
2553           ((DecimalFormat
*) nf
)->toPattern(pat
) + " = " + s
); 
2554     if (s 
!= UnicodeString("-0.1")) { 
2561  * June 16 1999 sync up - liu 
2562  * Formatting .5 rounds to "1" instead of "0". (Regression in 1.2.2 RC1) 
2564 void NumberFormatRegressionTest::Test4243011(void) { 
2565     UErrorCode status 
= U_ZERO_ERROR
; 
2566     DecimalFormatSymbols 
sym(Locale::getUS(), status
); 
2567     failure(status
, "DecimalFormatSymbols ct", Locale::getUS()); 
2568     DecimalFormat 
fmt(UnicodeString("0."), sym
, status
); 
2570     if (!failure(status
, "DecimalFormat ct", Locale::getUS())) { 
2571         const double NUM
[] = {  -2.5,  -1.5,  -0.5,  0.5,  1.5,  2.5,  3.5,  4.5 }; 
2572         const char*  STR
[] = { "-2.", "-2.", "-0.", "0.", "2.", "2.", "4.", "4." }; 
2573         int32_t N 
= (int32_t)(sizeof(NUM
) / sizeof(NUM
[0])); 
2575         for (int32_t i
=0; i
<N
; ++i
) { 
2577             UnicodeString 
exp(STR
[i
]); 
2579             fmt
.format(NUM
[i
], str
, pos
); 
2581                 logln(UnicodeString("Ok   ") + NUM
[i
] + " x 0. = " + str
); 
2583                 errln(UnicodeString("FAIL ") + NUM
[i
] + " x 0. = " + str 
+ 
2591  * June 16 1999 sync up - liu 
2592  * format(0.0) gives "0.1" if preceded by parse("99.99"). 
2593  * (Regression in 1.2.2 RC1) 
2595 void NumberFormatRegressionTest::Test4243108(void) { 
2596     UErrorCode status 
= U_ZERO_ERROR
; 
2597     DecimalFormatSymbols 
sym(Locale::getUS(), status
); 
2598     failure(status
, "DecimalFormatSymbols ct", Locale::getUS()); 
2599     DecimalFormat 
fmt(UnicodeString("#.#"), sym
, status
); 
2600     if (failure(status
, "DecimalFormat ct", Locale::getUS())) { 
2607     fmt
.format(0.0, str
, pos
); 
2608     UnicodeString 
exp("0"); 
2610         logln(UnicodeString("Ok   0.0 x #.# = ") + str
); 
2612         errln(UnicodeString("FAIL 0.0 x #.# = ") + str 
+ 
2618     fmt
.parse(str
, val
, status
); 
2619     failure(status
, "DecimalFormat.parse(99.99)", Locale::getUS()); 
2620     if (val
.getType() == Formattable::kDouble 
&& 
2621         val
.getDouble() == 99.99) { 
2622         logln(UnicodeString("Ok   99.99 / #.# = ") + toString(val
)); 
2624         errln(UnicodeString("FAIL 99.99 / #.# = ") + toString(val
) + 
2629     fmt
.format(0.0, str
, pos
); 
2631         logln(UnicodeString("Ok   0.0 x #.# = ") + str
); 
2633         errln(UnicodeString("FAIL 0.0 x #.# = ") + str 
+ 
2640  * DateFormat should call setIntegerParseOnly(TRUE) on adopted 
2641  * NumberFormat objects. 
2643 void NumberFormatRegressionTest::TestJ691(void) { 
2644     UErrorCode status 
= U_ZERO_ERROR
; 
2645     Locale 
loc("fr", "CH"); 
2647     // set up the input date string & expected output 
2648     UnicodeString 
udt("11.10.2000", ""); 
2649     UnicodeString 
exp("11.10.00", ""); 
2651     // create a Calendar for this locale 
2652     Calendar 
*cal 
= Calendar::createInstance(loc
, status
); 
2653     if (U_FAILURE(status
)) { 
2654         dataerrln("FAIL: Calendar::createInstance() returned " + (UnicodeString
)u_errorName(status
)); 
2658     // create a NumberFormat for this locale 
2659     NumberFormat 
*nf 
= NumberFormat::createInstance(loc
, status
); 
2660     if (U_FAILURE(status
)) { 
2661         dataerrln("FAIL: NumberFormat::createInstance() returned " + (UnicodeString
)u_errorName(status
)); 
2665     // *** Here's the key: We don't want to have to do THIS: 
2666     // nf->setParseIntegerOnly(TRUE); 
2668     // create the DateFormat 
2669     DateFormat 
*df 
= DateFormat::createDateInstance(DateFormat::kShort
, loc
); 
2670     if (U_FAILURE(status
)) { 
2671         errln("FAIL: DateFormat::createInstance() returned " + (UnicodeString
)u_errorName(status
)); 
2675     df
->adoptCalendar(cal
); 
2676     df
->adoptNumberFormat(nf
); 
2678     // set parsing to lenient & parse 
2679     df
->setLenient(TRUE
); 
2680     UDate ulocdat 
= df
->parse(udt
, status
); 
2682     // format back to a string 
2683     UnicodeString outString
; 
2684     df
->format(ulocdat
, outString
); 
2686     if (outString 
!= exp
) { 
2687         errln("FAIL: " + udt 
+ " => " + outString
); 
2693 //--------------------------------------------------------------------------- 
2695 //   Error Checking / Reporting macros 
2697 //--------------------------------------------------------------------------- 
2698 #define TEST_CHECK_STATUS(status) \ 
2699     if (U_FAILURE(status)) {\ 
2700         errln("File %s, Line %d.  status=%s\n", __FILE__, __LINE__, u_errorName(status));\ 
2704 #define TEST_ASSERT(expr) \ 
2705     if ((expr)==FALSE) {\ 
2706         errln("File %s, line %d: Assertion Failed: " #expr "\n", __FILE__, __LINE__);\ 
2710 // Ticket 8199:  Parse failure for numbers in the range of 1E10 - 1E18 
2712 void NumberFormatRegressionTest::Test8199(void) { 
2713     UErrorCode status 
= U_ZERO_ERROR
; 
2714     NumberFormat 
*nf 
= NumberFormat::createInstance(Locale::getEnglish(), status
); 
2716         dataerrln("Fail: NumberFormat::createInstance(Locale::getEnglish(), status)"); 
2719     TEST_CHECK_STATUS(status
); 
2721     // Note:  Retrieving parsed values from a Formattable as a reduced-precision type 
2722     //        should always truncate, no other rounding scheme. 
2724     UnicodeString numStr 
= "1000000000.6";   // 9 zeroes 
2726     nf
->parse(numStr
, val
, status
); 
2727     TEST_CHECK_STATUS(status
); 
2728     TEST_ASSERT(Formattable::kDouble 
== val
.getType()); 
2729     TEST_ASSERT(1000000000 == val
.getInt64(status
)); 
2730     TEST_CHECK_STATUS(status
); 
2731     TEST_ASSERT(1000000000.6 == val
.getDouble(status
)); 
2732     TEST_CHECK_STATUS(status
); 
2734     numStr 
= "100000000000000001.1";   // approx 1E17, parses as a double rather 
2735                                        //   than int64 because of the fraction 
2736                                        //   even though int64 is more precise. 
2737     nf
->parse(numStr
, val
, status
); 
2738     TEST_CHECK_STATUS(status
); 
2739     TEST_ASSERT(Formattable::kDouble 
== val
.getType()); 
2740     TEST_ASSERT(100000000000000001LL == val
.getInt64(status
)); 
2741     TEST_CHECK_STATUS(status
); 
2742     TEST_ASSERT(100000000000000000.0 == val
.getDouble(status
)); 
2743     TEST_CHECK_STATUS(status
); 
2745     numStr 
= "1E17";  // Parses with the internal decimal number having non-zero exponent 
2746     nf
->parse(numStr
, val
, status
); 
2747     TEST_CHECK_STATUS(status
); 
2748     TEST_ASSERT(Formattable::kInt64 
== val
.getType()); 
2749     TEST_ASSERT(100000000000000000LL == val
.getInt64()); 
2750     TEST_ASSERT(1.0E17 
== val
.getDouble(status
)); 
2751     TEST_CHECK_STATUS(status
); 
2753     numStr 
= "9223372036854775807";  // largest int64_t 
2754     nf
->parse(numStr
, val
, status
); 
2755     TEST_CHECK_STATUS(status
); 
2756     TEST_ASSERT(Formattable::kInt64 
== val
.getType()); 
2757     TEST_ASSERT(9223372036854775807LL == val
.getInt64()); 
2758     // In the following check, note that a substantial range of integers will 
2759     //    convert to the same double value.  There are also platform variations 
2760     //    in the rounding at compile time of double constants. 
2761     TEST_ASSERT(9223372036854775808.0 >= val
.getDouble(status
)); 
2762     TEST_ASSERT(9223372036854774700.0 <= val
.getDouble(status
)); 
2763     TEST_CHECK_STATUS(status
); 
2765     numStr 
= "-9223372036854775808";  // smallest int64_t 
2766     nf
->parse(numStr
, val
, status
); 
2767     TEST_CHECK_STATUS(status
); 
2768     TEST_ASSERT(Formattable::kInt64 
== val
.getType()); 
2769     // TEST_ASSERT(-9223372036854775808LL == val.getInt64()); // Compiler chokes on constant. 
2770     TEST_ASSERT((int64_t)0x8000000000000000LL 
== val
.getInt64()); 
2771     TEST_ASSERT(-9223372036854775808.0 == val
.getDouble(status
)); 
2772     TEST_CHECK_STATUS(status
); 
2774     numStr 
= "9223372036854775808";  // largest int64_t + 1 
2775     nf
->parse(numStr
, val
, status
); 
2776     TEST_CHECK_STATUS(status
); 
2777     TEST_ASSERT(Formattable::kDouble 
== val
.getType()); 
2778     TEST_ASSERT(9223372036854775807LL == val
.getInt64(status
)); 
2779     TEST_ASSERT(status 
== U_INVALID_FORMAT_ERROR
); 
2780     status 
= U_ZERO_ERROR
; 
2781     TEST_ASSERT(9223372036854775810.0 == val
.getDouble(status
)); 
2782     TEST_CHECK_STATUS(status
); 
2784     numStr 
= "-9223372036854775809";  // smallest int64_t - 1 
2785     nf
->parse(numStr
, val
, status
); 
2786     TEST_CHECK_STATUS(status
); 
2787     TEST_ASSERT(Formattable::kDouble 
== val
.getType()); 
2788     // TEST_ASSERT(-9223372036854775808LL == val.getInt64(status));  // spurious compiler warnings 
2789     TEST_ASSERT((int64_t)0x8000000000000000LL 
== val
.getInt64(status
)); 
2790     TEST_ASSERT(status 
== U_INVALID_FORMAT_ERROR
); 
2791     status 
= U_ZERO_ERROR
; 
2792     TEST_ASSERT(-9223372036854775810.0 == val
.getDouble(status
)); 
2793     TEST_CHECK_STATUS(status
); 
2795     // Test values near the limit of where doubles can represent all integers. 
2796     // The implementation strategy of getInt64() changes at this boundary. 
2797     // Strings to be parsed include a decimal fraction to force them to be 
2798     //   parsed as doubles rather than ints.  The fraction is discarded 
2799     //   from the parsed double value because it is beyond what can be represented. 
2801     status 
= U_ZERO_ERROR
; 
2802     numStr 
= "9007199254740991.1";  // largest 53 bit int 
2803     nf
->parse(numStr
, val
, status
); 
2804     TEST_CHECK_STATUS(status
); 
2805     // printf("getInt64() returns %lld\n", val.getInt64(status)); 
2806     TEST_ASSERT(Formattable::kDouble 
== val
.getType()); 
2807     TEST_ASSERT(9007199254740991LL == val
.getInt64(status
)); 
2808     TEST_ASSERT(9007199254740991.0 == val
.getDouble(status
)); 
2809     TEST_CHECK_STATUS(status
); 
2811     status 
= U_ZERO_ERROR
; 
2812     numStr 
= "9007199254740992.1";  // 54 bits for the int part. 
2813     nf
->parse(numStr
, val
, status
); 
2814     TEST_CHECK_STATUS(status
); 
2815     TEST_ASSERT(Formattable::kDouble 
== val
.getType()); 
2816     TEST_ASSERT(9007199254740992LL == val
.getInt64(status
)); 
2817     TEST_ASSERT(9007199254740992.0 == val
.getDouble(status
)); 
2818     TEST_CHECK_STATUS(status
); 
2820     status 
= U_ZERO_ERROR
; 
2821     numStr 
= "9007199254740993.1";  // 54 bits for the int part.  Double will round 
2822     nf
->parse(numStr
, val
, status
); //    the ones digit, putting it up to ...994 
2823     TEST_CHECK_STATUS(status
); 
2824     TEST_ASSERT(Formattable::kDouble 
== val
.getType()); 
2825     TEST_ASSERT(9007199254740993LL == val
.getInt64(status
)); 
2826     TEST_ASSERT(9007199254740994.0 == val
.getDouble(status
)); 
2827     TEST_CHECK_STATUS(status
); 
2832 void NumberFormatRegressionTest::Test9109(void) { 
2833     UErrorCode status 
= U_ZERO_ERROR
; 
2836     DecimalFormat 
fmt("+##", status
); 
2837     fmt
.setLenient(TRUE
); 
2839     if (U_FAILURE(status
)) { 
2840         dataerrln("Failed to create DecimalFormat with pattern '+##' - %s", u_errorName(status
)); 
2843     UnicodeString 
text("123"); 
2844     int32_t expected 
= 123; 
2847     fmt
.parse(text
, val
, pos
); 
2848     if (pos
.getErrorIndex() >= 0) { 
2849         errln(UnicodeString("Parse failure at ") + pos
.getErrorIndex()); 
2850     } else if (val
.getLong() != 123) { 
2851         errln(UnicodeString("Incorrect parse result: ") + val
.getLong() + " expected: " + expected
); 
2852     } else if (pos
.getIndex() != 3) { 
2853         errln(UnicodeString("Incorrect parse position: ") + pos
.getIndex() + " expected: " + expos
); 
2858 void NumberFormatRegressionTest::Test9780(void) { 
2859     UErrorCode status 
= U_ZERO_ERROR
; 
2860     NumberFormat 
*nf 
= NumberFormat::createInstance(Locale::getUS(), status
); 
2861     if (failure(status
, "NumberFormat::createInstance", TRUE
)){ 
2865     DecimalFormat 
*df 
= dynamic_cast<DecimalFormat 
*>(nf
); 
2867         errln("DecimalFormat needed to continue"); 
2870     df
->setParseIntegerOnly(TRUE
); 
2874       ParsePosition 
pos(0); 
2875       UnicodeString 
toParse("1,234",""); 
2876       df
->parse(toParse
, n
, pos
); 
2877       if (n
.getType() != Formattable::kLong
 
2878           || n
.getLong() != 1234) { 
2879         errln(UnicodeString("FAIL: parse(\"") + toParse 
+ UnicodeString("\") returns ") + toString(n
)); 
2882     // should still work in lenient mode, just won't get fastpath 
2883     df
->setLenient(TRUE
); 
2886       ParsePosition 
pos(0); 
2887       UnicodeString 
toParse("1,234",""); 
2888       df
->parse(toParse
, n
, pos
); 
2889       if (n
.getType() != Formattable::kLong
 
2890           || n
.getLong() != 1234) { 
2891         errln(UnicodeString("FAIL: parse(\"") + toParse 
+ UnicodeString("\") returns ") + toString(n
)); 
2898 void NumberFormatRegressionTest::Test9677(void) { 
2899   static const UChar pattern
[] = { 0x23,0x23,0x23,0x23,0x2E,0x23,0x23,0x23,0x23,0 }; // "####.####" 
2900   static const UChar positivePrefix
[] = { 0x40,0 }; // "@" 
2901   static const UChar negativePrefix
[] = { 0x6E,0 }; // "n" 
2902   static const UChar text
[] = { 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0 }; // 123456789 
2903   static const UChar text2
[] = { 0x6E, 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0 }; // n123456789 
2905   UErrorCode status 
= U_ZERO_ERROR
; 
2906   LocalUNumberFormatPointer 
f(unum_open(UNUM_DEFAULT
, NULL
, 0, "en_US", NULL
, &status
)); 
2907   if (U_FAILURE(status
)) { 
2908       dataerrln("Failure opening unum_open"); 
2912   if (U_SUCCESS(status
)) { 
2913     unum_applyPattern(f
.getAlias(), FALSE
, pattern
, -1, NULL
, &status
); 
2914     unum_setTextAttribute(f
.getAlias(), UNUM_POSITIVE_PREFIX
, positivePrefix
, -1, &status
); 
2915     assertSuccess("setting attributes", status
); 
2918   if(U_SUCCESS(status
)) { 
2919     int32_t n 
= unum_parse(f
.getAlias(), text
, -1, NULL
, &status
); 
2920     logln("unum_parse status %s, result %d\n", u_errorName(status
), n
); 
2922     if(U_FAILURE(status
)) { 
2923         logln("Got expected parse error %s\n", u_errorName(status
)); 
2924         status 
= U_ZERO_ERROR
; 
2926         errln("FAIL: unum_parse status %s, result %d - expected failure\n", u_errorName(status
), n
); 
2930   if (U_SUCCESS(status
)) { 
2931     unum_setTextAttribute(f
.getAlias(), UNUM_POSITIVE_PREFIX
, NULL
, 0, &status
); 
2932     assertSuccess("setting attributes", status
); 
2933     logln("removed positive prefix"); 
2936   if(U_SUCCESS(status
)) { 
2937     int32_t n 
= unum_parse(f
.getAlias(), text
, -1, NULL
, &status
); 
2938     logln("unum_parse status %s, result %d\n", u_errorName(status
), n
); 
2940     if(U_FAILURE(status
)) { 
2941         errln("FAIL: with pos prefix removed, parse error %s\n", u_errorName(status
)); 
2942         status 
= U_ZERO_ERROR
; 
2945           errln("FAIL: with pos prefix removed , unum_parse status %s, result %d expected 123456789\n", u_errorName(status
), n
); 
2947           logln("PASS: with pos prefix removed , unum_parse status %s, result %d expected 123456789\n", u_errorName(status
),n
); 
2952   if(U_SUCCESS(status
)) { 
2953     int32_t n 
= unum_parse(f
.getAlias(), text2
, -1, NULL
, &status
); 
2954     logln("unum_parse status %s, result %d\n", u_errorName(status
), n
); 
2956     if(U_FAILURE(status
)) { 
2957         logln("text2: Got expected parse error %s\n", u_errorName(status
)); 
2958         status 
= U_ZERO_ERROR
; 
2960         errln("FAIL: text2: unum_parse status %s, result %d - expected failure\n", u_errorName(status
), n
); 
2964   if (U_SUCCESS(status
)) { 
2965     unum_setTextAttribute(f
.getAlias(), UNUM_NEGATIVE_PREFIX
, negativePrefix
, -1, &status
); 
2966     assertSuccess("setting attributes", status
); 
2967     logln("Set a different neg prefix prefix"); 
2970   if(U_SUCCESS(status
)) { 
2971     int32_t n 
= unum_parse(f
.getAlias(), text2
, -1, NULL
, &status
); 
2972     logln("unum_parse status %s, result %d\n", u_errorName(status
), n
); 
2974     if(U_FAILURE(status
)) { 
2975         errln("FAIL: with different neg prefix , parse error %s\n", u_errorName(status
)); 
2976         status 
= U_ZERO_ERROR
; 
2980           errln("FAIL: with different neg prefix , unum_parse status %s, result %d expected -123456789\n", u_errorName(status
), n
); 
2982           logln("PASS: with different neg prefix , unum_parse status %s, result %d expected -123456789\n", u_errorName(status
), n
); 
2989 #endif /* #if !UCONFIG_NO_FORMATTING */