1 /***********************************************************************
3 * Copyright (c) 1997-2006, International Business Machines Corporation
4 * and others. All Rights Reserved.
5 ***********************************************************************/
7 #include "unicode/utypes.h"
9 #if !UCONFIG_NO_FORMATTING
13 #include <float.h> // DBL_MIN, DBL_MAX
16 #include "unicode/dcfmtsym.h"
17 #include "unicode/decimfmt.h"
18 #include "unicode/locid.h"
19 #include "unicode/resbund.h"
20 #include "unicode/calendar.h"
21 #include "unicode/datefmt.h"
22 #include "unicode/ucurr.h"
25 class MyNumberFormatTest
: public NumberFormat
29 virtual UClassID
getDynamicClassID(void) const;
31 virtual UnicodeString
& format( double number
,
32 UnicodeString
& toAppendTo
,
34 UErrorCode
& status
) const
36 return NumberFormat::format(number
, toAppendTo
, pos
, status
);
39 /* Just keep this here to make some of the compilers happy */
40 virtual UnicodeString
& format(const Formattable
& obj
,
41 UnicodeString
& toAppendTo
,
43 UErrorCode
& status
) const
45 return NumberFormat::format(obj
, toAppendTo
, pos
, status
);
48 /* Just use one of the format functions */
49 virtual UnicodeString
& format( double /* number */,
50 UnicodeString
& toAppendTo
,
51 FieldPosition
& /* pos */) const
58 public Number parse(String text, ParsePosition parsePosition)
59 { return new Integer(0); }
62 /* Just use one of the parse functions */
63 virtual void parse( const UnicodeString
& /* text */,
65 ParsePosition
& /* parsePosition */) const
67 result
.setLong((int32_t)0);
70 virtual void parse( const UnicodeString
& text
,
72 UErrorCode
& status
) const
74 NumberFormat::parse(text
, result
, status
);
76 virtual Format
* clone() const
79 virtual UnicodeString
& format(int32_t,
82 { return foo
.remove(); }
84 virtual UnicodeString
& format(int64_t,
87 { return foo
.remove(); }
89 virtual void applyPattern(const UnicodeString
&, UParseError
&, UErrorCode
&){
93 int32_t gMyNumberFormatTestClassID
;
94 UClassID
MyNumberFormatTest::getDynamicClassID() const
96 return (UClassID
)&gMyNumberFormatTestClassID
;
100 // *****************************************************************************
101 // class NumberFormatRegressionTest
102 // *****************************************************************************
104 #define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break
107 NumberFormatRegressionTest::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* /*par*/ )
109 // if (exec) logln((UnicodeString)"TestSuite NumberFormatRegressionTest");
121 CASE(10,Test4086575
);
122 CASE(11,Test4068693
);
123 CASE(12,Test4069754
);
124 CASE(13,Test4087251
);
125 CASE(14,Test4090489
);
126 CASE(15,Test4090504
);
127 CASE(16,Test4095713
);
128 CASE(17,Test4092561
);
129 CASE(18,Test4092480
);
130 CASE(19,Test4087244
);
131 CASE(20,Test4070798
);
132 CASE(21,Test4071005
);
133 CASE(22,Test4071014
);
134 CASE(23,Test4071859
);
135 CASE(24,Test4093610
);
136 CASE(25,Test4098741
);
137 CASE(26,Test4074454
);
138 CASE(27,Test4099404
);
139 CASE(28,Test4101481
);
140 CASE(29,Test4052223
);
141 CASE(30,Test4061302
);
142 CASE(31,Test4062486
);
143 CASE(32,Test4108738
);
144 CASE(33,Test4106658
);
145 CASE(34,Test4106662
);
146 CASE(35,Test4114639
);
147 CASE(36,Test4106664
);
148 CASE(37,Test4106667
);
149 CASE(38,Test4110936
);
150 CASE(39,Test4122840
);
151 CASE(40,Test4125885
);
152 CASE(41,Test4134034
);
153 CASE(42,Test4134300
);
154 CASE(43,Test4140009
);
155 CASE(44,Test4141750
);
156 CASE(45,Test4145457
);
157 CASE(46,Test4147295
);
158 CASE(47,Test4147706
);
159 CASE(48,Test4162198
);
160 CASE(49,Test4162852
);
161 CASE(50,Test4167494
);
162 CASE(51,Test4170798
);
163 CASE(52,Test4176114
);
164 CASE(53,Test4179818
);
165 CASE(54,Test4212072
);
166 CASE(55,Test4216742
);
167 CASE(56,Test4217661
);
168 CASE(57,Test4161100
);
169 CASE(58,Test4243011
);
170 CASE(59,Test4243108
);
173 default: name
= ""; break;
178 NumberFormatRegressionTest::failure(UErrorCode status
, const UnicodeString
& msg
, const Locale
& l
)
180 if(U_FAILURE(status
)) {
181 errln(UnicodeString("FAIL: ", "") + msg
182 + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status
), "") + UnicodeString(l
.getName(),""));
190 NumberFormatRegressionTest::failure(UErrorCode status
, const UnicodeString
& msg
, const char *l
)
192 if(U_FAILURE(status
)) {
193 errln(UnicodeString("FAIL: ", "") + msg
194 + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status
), "") + UnicodeString(l
, ""));
202 NumberFormatRegressionTest::failure(UErrorCode status
, const UnicodeString
& msg
)
204 if(U_FAILURE(status
)) {
205 errln(UnicodeString("FAIL: ", "") + msg
206 + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status
), ""));
214 * Convert Java-style strings with \u Unicode escapes into UnicodeString objects
216 inline UnicodeString
str(const char *input
)
218 return CharsToUnicodeString(input
);
222 * NumberFormat.equals comparing with null should always return false.
224 // {sfb} kind of silly in C++, just checking for new success
225 void NumberFormatRegressionTest::Test4075713(void)
228 MyNumberFormatTest
*tmp
= new MyNumberFormatTest();
230 logln("NumberFormat.equals passed");
231 /*} catch (NullPointerException e) {
232 errln("(new MyNumberFormatTest()).equals(null) throws unexpected exception");
239 * NumberFormat.equals comparing two obj equal even the setGroupingUsed
242 void NumberFormatRegressionTest::Test4074620(void)
245 MyNumberFormatTest
*nf1
= new MyNumberFormatTest();
246 MyNumberFormatTest
*nf2
= new MyNumberFormatTest();
248 nf1
->setGroupingUsed(FALSE
);
249 nf2
->setGroupingUsed(TRUE
);
252 errln("Test for bug 4074620 failed");
254 logln("Test for bug 4074620 passed.");
262 * DecimalFormat.format() incorrectly uses maxFractionDigits setting.
265 void NumberFormatRegressionTest::Test4088161 (void)
267 UErrorCode status
= U_ZERO_ERROR
;
268 DecimalFormat
*df
= new DecimalFormat(status
);
269 failure(status
, "new DecimalFormat", "");
271 df
->setMinimumFractionDigits(0);
272 df
->setMaximumFractionDigits(16);
274 FieldPosition
fp1(0);
275 logln(UnicodeString("d = ") + d
);
276 logln("maxFractionDigits = " + df
->getMaximumFractionDigits());
278 logln(" format(d) = '" + df
->format(d
, sBuf1
, fp1
) + "'");
279 df
->setMaximumFractionDigits(17);
281 FieldPosition
fp2(0);
282 logln("maxFractionDigits = " + df
->getMaximumFractionDigits());
283 sBuf2
= df
->format(d
, sBuf2
, fp2
);
285 errln(" format(d) = '" + sBuf2
+ "'");
291 * DecimalFormatSymbols should be cloned in the ctor DecimalFormat.
292 * DecimalFormat(String, DecimalFormatSymbols).
294 void NumberFormatRegressionTest::Test4087245 (void)
296 UErrorCode status
= U_ZERO_ERROR
;
297 DecimalFormatSymbols
*symbols
= new DecimalFormatSymbols(status
);
298 failure(status
, "new DecimalFormatSymbols", "");
299 // {sfb} One note about this test: if you pass in a pointer
300 // to the symbols, they are adopted and this test will fail,
301 // even though that is the correct behavior. To test the cloning
302 // of the symbols, it is necessary to pass in a reference to the symbols
303 DecimalFormat
*df
= new DecimalFormat("#,##0.0", *symbols
, status
);
304 failure(status
, "new DecimalFormat with symbols", "");
308 FieldPosition
pos(FieldPosition::DONT_CARE
);
309 logln(UnicodeString("format(") + n
+ ") = " +
310 df
->format(n
, buf1
, pos
));
311 symbols
->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
, UnicodeString((UChar
)0x70)); // change value of field
312 logln(UnicodeString("format(") + n
+ ") = " +
313 df
->format(n
, buf2
, pos
));
315 errln("Test for bug 4087245 failed");
322 * DecimalFormat.format() incorrectly formats 0.0
324 void NumberFormatRegressionTest::Test4087535 (void)
326 UErrorCode status
= U_ZERO_ERROR
;
327 DecimalFormat
*df
= new DecimalFormat(status
);
328 failure(status
, "new DecimalFormat", "");
329 df
->setMinimumIntegerDigits(0);
332 UnicodeString buffer
;
333 FieldPosition
pos(FieldPosition::DONT_CARE
);
334 buffer
= df
->format(n
, buffer
, pos
);
335 if (buffer
.length() == 0)
336 errln(/*n + */": '" + buffer
+ "'");
338 buffer
= df
->format(n
, buffer
, pos
);
339 if (buffer
.length() == 0)
340 errln(/*n + */": '" + buffer
+ "'");
346 * DecimalFormat.format fails when groupingSize is set to 0.
348 // {sfb} how do I tell if this worked? --> FieldPosition doesn't change ??
349 void NumberFormatRegressionTest::Test4088503 (void)
351 UErrorCode status
= U_ZERO_ERROR
;
352 DecimalFormat
*df
= new DecimalFormat(status
);
353 failure(status
, "new DecimalFormat", "");
354 df
->setGroupingSize(0);
356 FieldPosition
fp(FieldPosition::DONT_CARE
);
358 logln(df
->format((int32_t)123, sBuf
, fp
));
359 //if(fp == FieldPosition(0))
360 // errln("Test for bug 4088503 failed.");
361 /*} catch (Exception foo) {
362 errln("Test for bug 4088503 failed.");
368 * NumberFormat.getCurrencyInstance is wrong.
370 void NumberFormatRegressionTest::Test4066646 (void)
372 assignFloatValue(2.04f
);
373 assignFloatValue(2.03f
);
374 assignFloatValue(2.02f
);
375 assignFloatValue(0.0f
);
379 NumberFormatRegressionTest::assignFloatValue(float returnfloat
)
381 logln(UnicodeString(" VALUE ") + returnfloat
);
382 UErrorCode status
= U_ZERO_ERROR
;
383 NumberFormat
*nfcommon
= NumberFormat::createCurrencyInstance(Locale::getUS(), status
);
384 if (failure(status
, "NumberFormat::createCurrencyInstance", Locale::getUS())){
388 nfcommon
->setGroupingUsed(FALSE
);
390 UnicodeString stringValue
;
391 stringValue
= nfcommon
->format(returnfloat
, stringValue
);
392 logln(" DISPLAYVALUE " + stringValue
);
394 nfcommon
->parse(stringValue
, result
, status
);
395 failure(status
, "nfcommon->parse", Locale::getUS());
396 float floatResult
= (float) (result
.getType() == Formattable::kDouble
397 ? result
.getDouble() : result
.getLong());
398 if( uprv_fabs(floatResult
- returnfloat
) > 0.0001)
399 //String stringValue = nfcommon.format(returnfloat).substring(1);
400 //if (Float.valueOf(stringValue).floatValue() != returnfloat)
401 errln(UnicodeString("FAIL: expected ") + returnfloat
+ ", got " + floatResult
+ " (" + stringValue
+")");
405 } // End Of assignFloatValue()
408 * DecimalFormat throws exception when parsing "0"
410 void NumberFormatRegressionTest::Test4059870(void)
412 UErrorCode status
= U_ZERO_ERROR
;
413 DecimalFormat
*format
= new DecimalFormat("00", status
);
414 failure(status
, "new Decimalformat", Locale::getUS());
418 format
->parse(UnicodeString("0"), result
, status
);
419 failure(status
, "format->parse", Locale::getUS());
422 catch (Exception e) {
423 errln("Test for bug 4059870 failed : " + e);
429 * DecimalFormatSymbol.equals should always return false when
430 * comparing with null.
432 // {sfb} this is silly in C++
433 void NumberFormatRegressionTest::Test4083018 (void)
435 UErrorCode status
= U_ZERO_ERROR
;
436 DecimalFormatSymbols
*dfs
= new DecimalFormatSymbols(status
);
437 failure(status
, "new DecimalFormatSymbols", Locale::getUS());
440 logln("Test Passed!");
442 errln("Test for bug 4083018 failed");
443 /*} catch (Exception foo) {
444 errln("Test for bug 4083018 failed => Message : " + foo.getMessage());
451 * DecimalFormat does not round up correctly.
453 void NumberFormatRegressionTest::Test4071492 (void)
455 double x
= 0.00159999;
456 UErrorCode status
= U_ZERO_ERROR
;
457 NumberFormat
*nf
= NumberFormat::createInstance(status
);
458 if (failure(status
, "NumberFormat::createInstance", Locale::getUS())) {
462 nf
->setMaximumFractionDigits(4);
464 FieldPosition
pos(FieldPosition::DONT_CARE
);
465 out
= nf
->format(x
, out
, pos
);
466 logln("0.00159999 formats with 4 fractional digits to " + out
);
467 UnicodeString
expected("0.0016");
469 errln("FAIL: Expected " + expected
);
475 * A space as a group separator for localized pattern causes
476 * wrong format. WorkAround : use non-breaking space.
478 void NumberFormatRegressionTest::Test4086575(void)
480 UErrorCode status
= U_ZERO_ERROR
;
481 NumberFormat
*nf1
= NumberFormat::createInstance(Locale::getFrance(), status
);
483 // TODO: There is not a good way to find out that the creation of this number format has
484 // failed. Major rewiring of format construction proposed.
485 if(U_FAILURE(status
)) {
486 errln("Something is wrong with French number format - it should not fallback. Exitting");
490 failure(status
, "NumberFormat::createInstance", Locale::getFrance());
492 // C++ workaround to make sure cast works
493 // Wouldn't dynamic_cast<DecimalFormat*> be great?
494 if(nf1
->getDynamicClassID() != DecimalFormat::getStaticClassID()) {
495 errln("NumberFormat::createInstance returned incorrect type.");
499 DecimalFormat
*nf
= (DecimalFormat
*) nf1
;
501 logln("nf toPattern1: " + nf
->toPattern(temp
));
502 logln("nf toLocPattern1: " + nf
->toLocalizedPattern(temp
));
504 // No group separator
505 logln("...applyLocalizedPattern ###,00;(###,00) ");
506 nf
->applyLocalizedPattern(UnicodeString("###,00;(###,00)"), status
);
507 failure(status
, "nf->applyLocalizedPattern", Locale::getFrance());
508 logln("nf toPattern2: " + nf
->toPattern(temp
));
509 logln("nf toLocPattern2: " + nf
->toLocalizedPattern(temp
));
511 FieldPosition
pos(FieldPosition::DONT_CARE
);
512 logln("nf: " + nf
->format((int32_t)1234, temp
, pos
)); // 1234,00
513 logln("nf: " + nf
->format((int32_t)-1234, temp
, pos
)); // (1234,00)
515 // Space as group separator
517 logln("...applyLocalizedPattern # ###,00;(# ###,00) ");
519 //nf->applyLocalizedPattern("#\u00a0###,00;(#\u00a0###,00)");
521 0x23, 0x00a0, 0x23, 0x23, 0x23, 0x2c, 0x30, 0x30, 0x3b,
522 0x28, 0x23, 0x00a0, 0x23, 0x23, 0x23, 0x2c, 0x30, 0x30, 0x29
524 UnicodeString
pat(patChars
, 19, 19);
525 nf
->applyLocalizedPattern(pat
, status
);
526 failure(status
, "nf->applyLocalizedPattern", Locale::getFrance());
527 logln("nf toPattern2: " + nf
->toPattern(temp
));
528 logln("nf toLocPattern2: " + nf
->toLocalizedPattern(temp
));
529 UnicodeString buffer
;
530 buffer
= nf
->format((int32_t)1234, buffer
, pos
);
531 //if (buffer != UnicodeString("1\u00a0234,00"))
533 0x31, 0x00a0, 0x32, 0x33, 0x34, 0x2c, 0x30, 0x30
535 UnicodeString
cc(c
, 8, 8);
537 errln("nf : " + buffer
); // Expect 1 234,00
540 buffer
= nf
->format((int32_t)-1234, buffer
, pos
);
542 0x28, 0x31, 0x00a0, 0x32, 0x33, 0x34, 0x2c, 0x30, 0x30, 0x29
544 UnicodeString
cc1(c1
, 10, 10);
546 errln("nf : " + buffer
); // Expect (1 234,00)
548 // Erroneously prints:
555 * DecimalFormat.parse returns wrong value
557 // {sfb} slightly converted into a round-trip test, since in C++
558 // there is no Double.toString()
559 void NumberFormatRegressionTest::Test4068693(void)
561 logln("----- Test Application -----");
562 ParsePosition
pos(0);
563 UErrorCode status
= U_ZERO_ERROR
;
564 DecimalFormat
*df
= new DecimalFormat(status
);
565 if(U_FAILURE(status
)) {
566 errln("Error creating DecimalFormat: %s", u_errorName(status
));
570 failure(status
, "new DecimalFormat");
572 //Double d = (Double)df.parse("123.55456", pos=new ParsePosition(0));
573 df
->parse(UnicodeString("123.55456"), d
, pos
);
574 //if (!d.toString().equals("123.55456")) {
576 df
->setMaximumFractionDigits(999);
577 df
->setMaximumIntegerDigits(999);
578 FieldPosition
fp(FieldPosition::DONT_CARE
);
579 dstr
= df
->format(d
.getDouble(), dstr
, fp
);
580 if (dstr
!= UnicodeString("123.55456")) {
581 errln(UnicodeString("Result -> ") + d
.getDouble());
587 /* @bug 4069754, 4067878
588 * null pointer thrown when accessing a deserialized DecimalFormat
591 // {sfb} doesn't apply in C++
592 void NumberFormatRegressionTest::Test4069754(void)
595 myformat it = new myformat();
597 FileOutputStream ostream = new FileOutputStream("t.tmp");
598 ObjectOutputStream p = new ObjectOutputStream(ostream);
603 FileInputStream istream = new FileInputStream("t.tmp");
604 ObjectInputStream p2 = new ObjectInputStream(istream);
605 myformat it2 = (myformat)p2.readObject();
609 } catch (Exception foo) {
610 errln("Test for bug 4069754 or 4057878 failed => Exception: " + foo.getMessage());
615 * DecimalFormat.applyPattern(String) allows illegal patterns
617 void NumberFormatRegressionTest::Test4087251 (void)
619 UErrorCode status
= U_ZERO_ERROR
;
620 DecimalFormat
*df
= new DecimalFormat(status
);
621 if(U_FAILURE(status
)) {
622 errln("Error creating DecimalFormat: %s", u_errorName(status
));
626 failure(status
, "new DecimalFormat");
628 df
->applyPattern(UnicodeString("#.#.#"), status
);
629 if( ! U_FAILURE(status
))
630 errln("df->applyPattern with illegal pattern didn't fail");
632 logln("toPattern() returns \"" + df
->toPattern(temp
) + "\"");
633 //errln("applyPattern(\"#.#.#\") doesn't throw IllegalArgumentException");
634 /*} catch (IllegalArgumentException e) {
635 logln("Caught Illegal Argument Error !");
637 // Second test; added 5/11/98 when reported to fail on 1.2b3
639 df
->applyPattern("#0.0#0#0", status
);
640 if( ! U_FAILURE(status
))
641 errln("df->applyPattern with illegal pattern didn't fail");
642 logln("toPattern() returns \"" + df
->toPattern(temp
) + "\"");
643 //errln("applyPattern(\"#0.0#0#0\") doesn't throw IllegalArgumentException");
644 /*} catch (IllegalArgumentException e) {
645 logln("Ok - IllegalArgumentException for #0.0#0#0");
652 * DecimalFormat.format() loses precision
654 void NumberFormatRegressionTest::Test4090489 (void)
656 // {sfb} sprintf doesn't correctly handle the double, so there is nothing
657 // that NumberFormat can do. For some reason, it does not format the last 1.
659 /* UErrorCode status = U_ZERO_ERROR;
660 DecimalFormat *df = new DecimalFormat(status);
661 failure(status, "new DecimalFormat");
662 df->setMinimumFractionDigits(10);
663 df->setMaximumFractionDigits(999);
664 df->setGroupingUsed(FALSE);
665 double d = 1.000000000000001E7;
666 //BigDecimal bd = new BigDecimal(d);
669 logln(UnicodeString("d = ") + d);
670 //logln("BigDecimal.toString(): " + bd.toString());
671 df->format(d, sb, fp);
672 if (sb != "10000000.0000000100") {
673 errln("DecimalFormat.format(): " + sb);
679 * DecimalFormat.format() loses precision
681 void NumberFormatRegressionTest::Test4090504 (void)
684 logln(UnicodeString("d = ") + d
);
685 UErrorCode status
= U_ZERO_ERROR
;
686 DecimalFormat
*df
= new DecimalFormat(status
);
687 if(U_FAILURE(status
)) {
688 errln("Error creating DecimalFormat: %s", u_errorName(status
));
692 failure(status
, "new DecimalFormat");
694 FieldPosition
fp(FieldPosition::DONT_CARE
);
696 for (int i
= 17; i
<= 20; i
++) {
697 df
->setMaximumFractionDigits(i
);
698 //sb = new StringBuffer("");
700 logln(" getMaximumFractionDigits() = " + i
);
701 logln(" formated: " + df
->format(d
, sb
, fp
));
703 /*} catch (Exception foo) {
704 errln("Bug 4090504 regression test failed. Message : " + foo.getMessage());
710 * DecimalFormat.parse(String str, ParsePosition pp) loses precision
712 void NumberFormatRegressionTest::Test4095713 (void)
714 UErrorCode status
= U_ZERO_ERROR
;
715 DecimalFormat
*df
= new DecimalFormat(status
);
716 if(U_FAILURE(status
)) {
717 errln("Error creating DecimalFormat: %s", u_errorName(status
));
721 failure(status
, "new DecimalFormat");
722 UnicodeString
str("0.1234");
724 //Double d1 = new Double(str);
725 //Double d2 = (Double) df.parse(str, new ParsePosition(0));
728 df
->parse(str
, d2
, pp
);
729 logln(UnicodeString("") + d1
);
730 if (d2
.getDouble() != d1
)
731 errln(UnicodeString("Bug 4095713 test failed, new double value : ") + d2
.getDouble());
736 * DecimalFormat.parse() fails when multiplier is not set to 1
738 // {sfb} not sure what to do with this one
739 void NumberFormatRegressionTest::Test4092561 (void)
741 UErrorCode status
= U_ZERO_ERROR
;
742 DecimalFormat
*df
= new DecimalFormat(status
);
743 if(U_FAILURE(status
)) {
744 errln("Error creating DecimalFormat: %s", u_errorName(status
));
748 failure(status
, "new DecimalFormat");
750 // {sfb} going to cheat here and use sprintf ??
752 /*UnicodeString str = Long.toString(Long.MIN_VALUE);
753 logln("Long.MIN_VALUE : " + df.parse(str, new ParsePosition(0)).toString());
754 df.setMultiplier(100);
755 Number num = df.parse(str, new ParsePosition(0));
756 if (num.doubleValue() != -9.223372036854776E16)
757 errln("Bug 4092561 test failed when multiplier is set to not 1.");
763 * DecimalFormat: Negative format ignored.
765 void NumberFormatRegressionTest::Test4092480 (void)
767 UErrorCode status
= U_ZERO_ERROR
;
768 DecimalFormat
*dfFoo
= new DecimalFormat(UnicodeString("000"), status
);
769 if(U_FAILURE(status
)) {
770 errln("Error creating DecimalFormat: %s", u_errorName(status
));
774 failure(status
, "new DecimalFormat");
777 dfFoo
->applyPattern("0000;-000", status
);
778 failure(status
, "dfFoo->applyPattern");
780 if (dfFoo
->toPattern(temp
) != UnicodeString("#0000"))
781 errln("dfFoo.toPattern : " + dfFoo
->toPattern(temp
));
782 FieldPosition
pos(FieldPosition::DONT_CARE
);
783 logln(dfFoo
->format((int32_t)42, temp
, pos
));
784 logln(dfFoo
->format((int32_t)-42, temp
, pos
));
785 dfFoo
->applyPattern("000;-000", status
);
786 failure(status
, "dfFoo->applyPattern");
787 if (dfFoo
->toPattern(temp
) != UnicodeString("#000"))
788 errln("dfFoo.toPattern : " + dfFoo
->toPattern(temp
));
789 logln(dfFoo
->format((int32_t)42,temp
, pos
));
790 logln(dfFoo
->format((int32_t)-42, temp
, pos
));
792 dfFoo
->applyPattern("000;-0000", status
);
793 failure(status
, "dfFoo->applyPattern");
794 if (dfFoo
->toPattern(temp
) != UnicodeString("#000"))
795 errln("dfFoo.toPattern : " + dfFoo
->toPattern(temp
));
796 logln(dfFoo
->format((int32_t)42, temp
, pos
));
797 logln(dfFoo
->format((int32_t)-42, temp
, pos
));
799 dfFoo
->applyPattern("0000;-000", status
);
800 failure(status
, "dfFoo->applyPattern");
801 if (dfFoo
->toPattern(temp
) != UnicodeString("#0000"))
802 errln("dfFoo.toPattern : " + dfFoo
->toPattern(temp
));
803 logln(dfFoo
->format((int32_t)42, temp
, pos
));
804 logln(dfFoo
->format((int32_t)-42, temp
, pos
));
805 /*} catch (Exception foo) {
806 errln("Message " + foo.getMessage());
812 * NumberFormat.getCurrencyInstance() produces format that uses
813 * decimal separator instead of monetary decimal separator.
815 * Rewrote this test not to depend on the actual pattern. Pattern should
816 * never contain the monetary separator! Decimal separator in pattern is
817 * interpreted as monetary separator if currency symbol is seen!
819 void NumberFormatRegressionTest::Test4087244 (void) {
820 UErrorCode status
= U_ZERO_ERROR
;
822 uloc_canonicalize("pt_PT_PREEURO", loc
, 256, &status
);
823 Locale
*de
= new Locale(loc
);
824 NumberFormat
*nf
= NumberFormat::createCurrencyInstance(*de
, status
);
825 if(U_FAILURE(status
)) {
826 errln("Error creating DecimalFormat: %s", u_errorName(status
));
830 if (nf
->getDynamicClassID() != DecimalFormat::getStaticClassID()) {
831 errln("expected DecimalFormat!");
834 DecimalFormat
*df
= (DecimalFormat
*) nf
;
835 const DecimalFormatSymbols
*sym
= df
->getDecimalFormatSymbols();
836 UnicodeString decSep
= sym
->getSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
);
837 UnicodeString monSep
= sym
->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
);
838 if (decSep
== monSep
) {
839 errln("ERROR in test: want decimal sep != monetary sep");
842 df
->setMinimumIntegerDigits(1);
843 df
->setMinimumFractionDigits(2);
846 df
->format(1.23, str
, pos
);
847 UnicodeString
monStr("1x23");
848 monStr
.replace((int32_t)1, 1, monSep
);
849 UnicodeString
decStr("1x23");
850 decStr
.replace((int32_t)1, 1, decSep
);
851 if (str
.indexOf(monStr
) >= 0 && str
.indexOf(decStr
) < 0) {
852 logln(UnicodeString("OK: 1.23 -> \"") + str
+ "\" contains \"" +
853 monStr
+ "\" and not \"" + decStr
+ '"');
855 errln(UnicodeString("FAIL: 1.23 -> \"") + str
+ "\", should contain \"" +
857 "\" and not \"" + decStr
+ '"');
863 * Number format data rounding errors for locale FR
865 void NumberFormatRegressionTest::Test4070798 (void)
867 NumberFormat
*formatter
;
868 UnicodeString tempString
;
871 String expectedDefault = "-5\u00a0789,987";
872 String expectedCurrency = "5\u00a0789,98 F";
873 String expectedPercent = "-578\u00a0998%";
876 0x2d, 0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x38, 0x38
879 0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x39, 0x20, 0x46
882 0x2d, 0x35, 0x37, 0x38, 0x00a0, 0x39, 0x39, 0x39, 0x00a0, 0x25
884 UnicodeString
expectedDefault(chars1
, 10, 10);
885 UnicodeString
expectedCurrency(chars2
, 10, 10);
886 UnicodeString
expectedPercent(chars3
, 10, 10);
888 UErrorCode status
= U_ZERO_ERROR
;
890 int len
= uloc_canonicalize("fr_FR_PREEURO", loc
, 256, &status
);
891 formatter
= NumberFormat::createInstance(Locale(loc
), status
);
892 if(U_FAILURE(status
)) {
893 errln("Error creating DecimalFormat: %s", u_errorName(status
));
897 failure(status
, "NumberFormat::createNumberInstance", loc
);
898 tempString
= formatter
->format (-5789.9876, tempString
);
900 if (tempString
== expectedDefault
) {
901 logln ("Bug 4070798 default test passed.");
903 errln(UnicodeString("Failed:") +
904 " Expected " + expectedDefault
+
905 " Received " + tempString
);
908 len
= uloc_canonicalize("fr_FR_PREEURO", loc
, 256, &status
);
909 formatter
= NumberFormat::createCurrencyInstance(loc
, status
);
910 failure(status
, "NumberFormat::createCurrencyInstance", loc
);
912 tempString
= formatter
->format( 5789.9876, tempString
);
914 if (tempString
== expectedCurrency
) {
915 logln ("Bug 4070798 currency test passed.");
917 errln(UnicodeString("Failed:") +
918 " Expected " + expectedCurrency
+
919 " Received " + tempString
);
923 uloc_canonicalize("fr_FR_PREEURO", loc
, 256, &status
);
924 formatter
= NumberFormat::createPercentInstance(Locale(loc
), status
);
925 failure(status
, "NumberFormat::createPercentInstance", loc
);
927 tempString
= formatter
->format (-5789.9876, tempString
);
929 if (tempString
== expectedPercent
) {
930 logln ("Bug 4070798 percentage test passed.");
932 errln(UnicodeString("Failed:") +
933 " Expected " + expectedPercent
+
934 " Received " + tempString
);
940 * Data rounding errors for French (Canada) locale
942 void NumberFormatRegressionTest::Test4071005 (void)
944 NumberFormat
*formatter
;
945 UnicodeString tempString
;
947 String expectedDefault = "-5\u00a0789,987";
948 String expectedCurrency = "5\u00a0789,98 $";
949 String expectedPercent = "-578\u00a0998%";
952 0x2d, 0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x38, 0x38
955 0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x39, 0x20, 0x24
958 0x2d, 0x35, 0x37, 0x38, 0x00a0, 0x39, 0x39, 0x39, 0x00a0, 0x25
960 UnicodeString
expectedDefault(chars1
, 10, 10);
961 UnicodeString
expectedCurrency(chars2
, 10, 10);
962 UnicodeString
expectedPercent(chars3
, 10, 10);
964 UErrorCode status
= U_ZERO_ERROR
;
965 formatter
= NumberFormat::createInstance(Locale::getCanadaFrench(), status
);
966 if (failure(status
, "NumberFormat::createNumberInstance", Locale::getCanadaFrench())){
970 tempString
= formatter
->format (-5789.9876, tempString
);
972 if (tempString
== expectedDefault
) {
973 logln ("Bug 4071005 default test passed.");
975 errln(UnicodeString("Failed:") +
976 " Expected " + expectedDefault
+
977 " Received " + tempString
);
981 formatter
= NumberFormat::createCurrencyInstance(Locale::getCanadaFrench(), status
);
982 failure(status
, "NumberFormat::createCurrencyInstance", Locale::getCanadaFrench());
984 tempString
= formatter
->format( 5789.9876, tempString
);
986 if (tempString
== expectedCurrency
) {
987 logln ("Bug 4071005 currency test assed.");
989 errln(UnicodeString("Failed:") +
990 " Expected " + expectedCurrency
+
991 " Received " + tempString
);
995 formatter
= NumberFormat::createPercentInstance(Locale::getCanadaFrench(), status
);
996 failure(status
, "NumberFormat::createPercentInstance", Locale::getCanadaFrench());
998 tempString
= formatter
->format (-5789.9876, tempString
);
1000 if (tempString
== expectedPercent
) {
1001 logln ("Bug 4071005 percentage test passed.");
1003 errln(UnicodeString("Failed:") +
1004 " Expected " + expectedPercent
+
1005 " Received " + tempString
);
1012 * Data rounding errors for German (Germany) locale
1014 void NumberFormatRegressionTest::Test4071014 (void)
1016 NumberFormat
*formatter
;
1017 UnicodeString tempString
;
1019 String expectedDefault = "-5.789,987";
1020 String expectedCurrency = "5.789,98 DM";
1021 String expectedPercent = "-578.998%";
1023 UnicodeString
expectedDefault("-5.789,988");
1024 UnicodeString
expectedCurrency("5.789,99 DM");
1025 UnicodeString
expectedPercent("-578.999%");
1027 UErrorCode status
= U_ZERO_ERROR
;
1029 uloc_canonicalize("de_DE_PREEURO", loc
, 256, &status
);
1030 formatter
= NumberFormat::createInstance(Locale(loc
), status
);
1031 if (failure(status
, "NumberFormat::createNumberInstance", loc
)){
1035 tempString
.remove();
1036 tempString
= formatter
->format (-5789.9876, tempString
);
1038 if (tempString
== expectedDefault
) {
1039 logln ("Bug 4071014 default test passed.");
1041 errln(UnicodeString("Failed:") +
1042 " Expected " + expectedDefault
+
1043 " Received " + tempString
);
1046 uloc_canonicalize("de_DE_PREEURO", loc
, 256, &status
);
1047 formatter
= NumberFormat::createCurrencyInstance(Locale(loc
), status
);
1048 failure(status
, "NumberFormat::createCurrencyInstance", loc
);
1049 tempString
.remove();
1050 tempString
= formatter
->format( 5789.9876, tempString
);
1052 if (tempString
== expectedCurrency
) {
1053 logln ("Bug 4071014 currency test assed.");
1055 errln(UnicodeString("Failed:") +
1056 " Expected " + expectedCurrency
+
1057 " Received " + tempString
);
1061 formatter
= NumberFormat::createPercentInstance(Locale::getGermany(), status
);
1062 failure(status
, "NumberFormat::createPercentInstance", Locale::getGermany());
1063 tempString
.remove();
1064 tempString
= formatter
->format (-5789.9876, tempString
);
1066 if (tempString
== expectedPercent
) {
1067 logln ("Bug 4071014 percentage test passed.");
1069 errln(UnicodeString("Failed:") +
1070 " Expected " + expectedPercent
+
1071 " Received " + tempString
);
1077 * Data rounding errors for Italian locale number formats
1079 void NumberFormatRegressionTest::Test4071859 (void)
1081 NumberFormat
*formatter
;
1082 UnicodeString tempString
;
1084 String expectedDefault = "-5.789,987";
1085 String expectedCurrency = "-L. 5.789,98";
1086 String expectedPercent = "-578.998%";
1088 UnicodeString
expectedDefault("-5.789,988");
1089 UnicodeString
expectedCurrency("-\\u20A4 5.790");
1090 UnicodeString
expectedPercent("-578.999%");
1091 expectedCurrency
= expectedCurrency
.unescape();
1093 UErrorCode status
= U_ZERO_ERROR
;
1095 uloc_canonicalize("it_IT_PREEURO", loc
, 256, &status
);
1096 formatter
= NumberFormat::createInstance(Locale(loc
), status
);
1097 if (failure(status
, "NumberFormat::createNumberInstance")){
1101 tempString
= formatter
->format (-5789.9876, tempString
);
1103 if (tempString
== expectedDefault
) {
1104 logln ("Bug 4071859 default test passed.");
1106 errln(UnicodeString("Failed:") +
1107 " Expected " + expectedDefault
+
1108 " Received " + tempString
);
1111 uloc_canonicalize("it_IT_PREEURO", loc
, 256, &status
);
1112 formatter
= NumberFormat::createCurrencyInstance(Locale(loc
), status
);
1113 failure(status
, "NumberFormat::createCurrencyInstance");
1114 tempString
.remove();
1115 tempString
= formatter
->format( -5789.9876, tempString
);
1117 if (tempString
== expectedCurrency
) {
1118 logln ("Bug 4071859 currency test assed.");
1120 errln(UnicodeString("Failed:") +
1121 " Expected " + expectedCurrency
+
1122 " Received " + tempString
);
1125 uloc_canonicalize("it_IT_PREEURO", loc
, 256, &status
);
1126 formatter
= NumberFormat::createPercentInstance(Locale(loc
), status
);
1127 failure(status
, "NumberFormat::createPercentInstance");
1128 tempString
.remove();
1129 tempString
= formatter
->format (-5789.9876, tempString
);
1131 if (tempString
== expectedPercent
) {
1132 logln ("Bug 4071859 percentage test passed.");
1134 errln(UnicodeString("Failed:") +
1135 " Expected " + expectedPercent
+
1136 " Received " + tempString
);
1142 * Test rounding for nearest even.
1144 void NumberFormatRegressionTest::Test4093610(void)
1146 UErrorCode status
= U_ZERO_ERROR
;
1147 DecimalFormat
*df
= new DecimalFormat("#0.#", status
);
1148 failure(status
, "new DecimalFormat");
1149 UnicodeString
s("12.4");
1150 roundingTest(df
, 12.35, s
);
1151 roundingTest(df
, 12.45, s
);
1153 roundingTest(df
, 12.452,s
);
1155 roundingTest(df
, 12.55, s
);
1156 roundingTest(df
, 12.65, s
);
1158 roundingTest(df
, 12.652,s
);
1160 roundingTest(df
, 12.75, s
);
1161 roundingTest(df
, 12.752,s
);
1162 roundingTest(df
, 12.85, s
);
1164 roundingTest(df
, 12.852,s
);
1166 roundingTest(df
, 12.95, s
);
1167 roundingTest(df
, 12.952,s
);
1172 void NumberFormatRegressionTest::roundingTest(DecimalFormat
*df
, double x
, UnicodeString
& expected
)
1175 FieldPosition
pos(FieldPosition::DONT_CARE
);
1176 out
= df
->format(x
, out
, pos
);
1177 logln(UnicodeString("") + x
+ " formats with 1 fractional digits to " + out
);
1178 if (out
!= expected
)
1179 errln("FAIL: Expected " + expected
);
1182 * Tests the setMaximumFractionDigits limit.
1184 void NumberFormatRegressionTest::Test4098741(void)
1187 UErrorCode status
= U_ZERO_ERROR
;
1188 NumberFormat
*fmt
= NumberFormat::createPercentInstance(status
);
1189 if (U_FAILURE(status
)) {
1190 dataerrln("Error calling NumberFormat::createPercentInstance");
1195 fmt
->setMaximumFractionDigits(20);
1197 logln(fmt
->format(.001, temp
));
1198 /*} catch (Exception foo) {
1199 errln("Bug 4098471 failed with exception thrown : " + foo.getMessage());
1204 * Tests illegal pattern exception.
1205 * Fix comment : HShih A31 Part1 will not be fixed and javadoc needs to be updated.
1206 * Part2 has been fixed.
1208 void NumberFormatRegressionTest::Test4074454(void)
1211 UErrorCode status
= U_ZERO_ERROR
;
1212 DecimalFormat
*fmt
= new DecimalFormat("#,#00.00;-#.#", status
);
1213 if(U_FAILURE(status
)) {
1214 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1218 failure(status
, "new DecimalFormat");
1219 logln("Inconsistent negative pattern is fine.");
1220 DecimalFormat
*newFmt
= new DecimalFormat("#,#00.00 p''ieces;-#,#00.00 p''ieces", status
);
1221 failure(status
, "new DecimalFormat");
1222 UnicodeString tempString
;
1223 FieldPosition
pos(FieldPosition::DONT_CARE
);
1224 tempString
= newFmt
->format(3456.78, tempString
, pos
);
1225 if (tempString
!= UnicodeString("3,456.78 p'ieces"))
1226 errln("Failed! 3456.78 p'ieces expected, but got : " + tempString
);
1227 /*} catch (Exception foo) {
1228 errln("An exception was thrown for any inconsistent negative pattern.");
1235 * Tests all different comments.
1236 * Response to some comments :
1237 * [1] DecimalFormat.parse API documentation is more than just one line.
1238 * This is not a reproducable doc error in 116 source code.
1239 * [2] See updated javadoc.
1241 * [4] NumberFormat.parse(String, ParsePosition) : If parsing fails,
1242 * a null object will be returned. The unchanged parse position also
1243 * reflects an error.
1244 * NumberFormat.parse(String) : If parsing fails, an ParseException
1246 * See updated javadoc for more details.
1247 * [5] See updated javadoc.
1248 * [6] See updated javadoc.
1249 * [7] This is a correct behavior if the DateFormat object is linient.
1250 * Otherwise, an IllegalArgumentException will be thrown when formatting
1251 * "January 35". See GregorianCalendar class javadoc for more details.
1253 void NumberFormatRegressionTest::Test4099404(void)
1256 UErrorCode status
= U_ZERO_ERROR
;
1257 DecimalFormat
*fmt
= new DecimalFormat(UnicodeString("000.0#0"), status
);
1258 if(! U_FAILURE(status
))
1259 errln(UnicodeString("Bug 4099404 failed applying illegal pattern \"000.0#0\""));
1260 /*} catch (Exception foo) {
1261 logln("Bug 4099404 pattern \"000.0#0\" passed");
1266 fmt
= new DecimalFormat(UnicodeString("0#0.000"), status
);
1267 if( !U_FAILURE(status
))
1268 errln("Bug 4099404 failed applying illegal pattern \"0#0.000\"");
1269 /*} catch (Exception foo) {
1270 logln("Bug 4099404 pattern \"0#0.000\" passed");
1276 * DecimalFormat.applyPattern doesn't set minimum integer digits
1278 void NumberFormatRegressionTest::Test4101481(void)
1280 UErrorCode status
= U_ZERO_ERROR
;
1281 DecimalFormat
*sdf
= new DecimalFormat(UnicodeString("#,##0"), status
);
1282 if(U_FAILURE(status
)) {
1283 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1287 failure(status
, "new DecimalFormat");
1288 if (sdf
->getMinimumIntegerDigits() != 1)
1289 errln("Minimum integer digits : " + sdf
->getMinimumIntegerDigits());
1292 /* @bug 4052223 (API addition request A27)
1293 * Tests ParsePosition.setErrorPosition() and ParsePosition.getErrorPosition().
1295 void NumberFormatRegressionTest::Test4052223(void)
1298 UErrorCode status
= U_ZERO_ERROR
;
1299 DecimalFormat
*fmt
= new DecimalFormat(UnicodeString("#,#00.00"), status
);
1300 if(U_FAILURE(status
)) {
1301 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1305 failure(status
, "new DecimalFormat");
1307 fmt
->parse(UnicodeString("abc3"), num
, status
);
1308 if(! U_FAILURE(status
))
1309 errln(UnicodeString("Bug 4052223 failed : can't parse string \"a\". Got ") /*+ num*/);
1310 /*} catch (ParseException foo) {
1311 logln("Caught expected ParseException : " + foo.getMessage() + " at index : " + foo.getErrorOffset());
1316 * API tests for API addition request A9.
1318 void NumberFormatRegressionTest::Test4061302(void)
1320 UErrorCode status
= U_ZERO_ERROR
;
1321 DecimalFormatSymbols
*fmt
= new DecimalFormatSymbols(status
);
1322 failure(status
, "new DecimalFormatSymbols");
1323 UnicodeString
currency(fmt
->getSymbol(DecimalFormatSymbols::kCurrencySymbol
));
1324 UnicodeString
intlCurrency(fmt
->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
));
1325 UnicodeString
monDecSeparator(fmt
->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
));
1326 if (currency
== UnicodeString("") ||
1327 intlCurrency
== UnicodeString("") ||
1328 monDecSeparator
== UnicodeString(""))
1330 errln("getCurrencySymbols failed, got empty string.");
1332 UnicodeString monDecSeparatorStr
;
1333 monDecSeparatorStr
.append(monDecSeparator
);
1334 logln((UnicodeString
)"Before set ==> Currency : " + currency
+(UnicodeString
)" Intl Currency : " + intlCurrency
+ (UnicodeString
)" Monetary Decimal Separator : " + monDecSeparatorStr
);
1335 fmt
->setSymbol(DecimalFormatSymbols::kCurrencySymbol
, UnicodeString("XYZ"));
1336 fmt
->setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
, UnicodeString("ABC"));
1337 fmt
->setSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
, UnicodeString((UChar
)0x002A/*'*'*/));
1338 currency
= fmt
->getSymbol(DecimalFormatSymbols::kCurrencySymbol
);
1339 intlCurrency
= fmt
->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
);
1340 monDecSeparator
= fmt
->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
);
1341 if (currency
!= UnicodeString("XYZ") ||
1342 intlCurrency
!= UnicodeString("ABC") ||
1343 monDecSeparator
!= UnicodeString((UChar
)0x002A/*'*'*/)) {
1344 errln("setCurrencySymbols failed.");
1346 monDecSeparatorStr
.remove();
1347 monDecSeparatorStr
.append(monDecSeparator
);
1348 logln("After set ==> Currency : " + currency
+ " Intl Currency : " + intlCurrency
+ " Monetary Decimal Separator : " + monDecSeparatorStr
);
1353 * API tests for API addition request A23. FieldPosition.getBeginIndex and
1354 * FieldPosition.getEndIndex.
1356 void NumberFormatRegressionTest::Test4062486(void)
1358 UErrorCode status
= U_ZERO_ERROR
;
1359 DecimalFormat
*fmt
= new DecimalFormat(UnicodeString("#,##0.00"), status
);
1360 failure(status
, "new DecimalFormat");
1361 UnicodeString formatted
;
1362 FieldPosition
field(0);
1363 double num
= 1234.5;
1364 fmt
->format(num
, formatted
, field
);
1365 if (field
.getBeginIndex() != 0 && field
.getEndIndex() != 5)
1366 errln(UnicodeString("Format 1234.5 failed. Begin index: ") /*+ field.getBeginIndex() + " End index: " + field.getEndIndex()*/);
1367 field
.setBeginIndex(7);
1368 field
.setEndIndex(4);
1369 if (field
.getBeginIndex() != 7 && field
.getEndIndex() != 4)
1370 errln("Set begin/end field indexes failed. Begin index: " /*+ field.getBeginIndex() + " End index: " + field.getEndIndex()*/);
1376 * DecimalFormat.parse incorrectly works with a group separator.
1378 void NumberFormatRegressionTest::Test4108738(void)
1380 UErrorCode status
= U_ZERO_ERROR
;
1381 DecimalFormatSymbols
*syms
= new DecimalFormatSymbols(Locale::getUS(), status
);
1382 failure(status
, "new DecimalFormatSymbols");
1383 DecimalFormat
*df
= new DecimalFormat("#,##0.###", syms
, status
);
1384 if(U_FAILURE(status
)) {
1385 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1389 failure(status
, "new DecimalFormat");
1390 UnicodeString
text("1.222,111");
1392 ParsePosition
pp(0);
1393 df
->parse(text
, num
, pp
);
1395 // {sfb} how to do this (again) ?
1396 // shouldn't just be another round-trip test, should it?
1398 FieldPosition
pos(FieldPosition::DONT_CARE
);
1399 temp
= df
->format(num
.getDouble(), temp
, pos
);
1400 //if (!num.toString().equals("1.222"))
1401 if (temp
!= UnicodeString("1.222"))
1402 //errln("\"" + text + "\" is parsed as " + num);
1403 errln("\"" + text
+ "\" is parsed as " + temp
);
1404 text
= UnicodeString("1.222x111");
1405 pp
= ParsePosition(0);
1406 df
->parse(text
, num
, pp
);
1408 temp
= df
->format(num
.getDouble(), temp
, pos
);
1409 //if (!num.toString().equals("1.222"))
1410 if (temp
!= UnicodeString("1.222"))
1411 errln("\"" + text
+ "\" is parsed as " + temp
);
1417 * DecimalFormat.format() incorrectly formats negative doubles.
1419 void NumberFormatRegressionTest::Test4106658(void)
1421 UErrorCode status
= U_ZERO_ERROR
;
1422 DecimalFormat
*df
= new DecimalFormat(status
); // Corrected; see 4147706
1423 if(U_FAILURE(status
)) {
1424 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1428 failure(status
, "new DecimalFormat");
1429 volatile double d1
= 0.0; // volatile to prevent code optimization
1430 double d2
= -0.0001;
1431 UnicodeString buffer
;
1433 FieldPosition
pos(FieldPosition::DONT_CARE
);
1436 d1
= 0.0 * -1.0; // old HPUX compiler ignores volatile keyword
1438 d1
*= -1.0; // Some compilers have a problem with defining -0.0
1440 logln("pattern: \"" + df
->toPattern(temp
) + "\"");
1441 df
->format(d1
, buffer
, pos
);
1442 if (buffer
!= UnicodeString("-0")) // Corrected; see 4147706
1443 errln(UnicodeString("") + d1
+ " is formatted as " + buffer
);
1445 df
->format(d2
, buffer
, pos
);
1446 if (buffer
!= UnicodeString("-0")) // Corrected; see 4147706
1447 errln(UnicodeString("") + d2
+ " is formatted as " + buffer
);
1453 * DecimalFormat.parse returns 0 if string parameter is incorrect.
1455 void NumberFormatRegressionTest::Test4106662(void)
1457 UErrorCode status
= U_ZERO_ERROR
;
1458 DecimalFormat
*df
= new DecimalFormat(status
);
1459 if(U_FAILURE(status
)) {
1460 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1464 failure(status
, "new DecimalFormat");
1465 UnicodeString
text("x");
1466 ParsePosition
pos1(0), pos2(0);
1469 logln("pattern: \"" + df
->toPattern(temp
) + "\"");
1471 df
->parse(text
, num
, pos1
);
1472 if (pos1
== ParsePosition(0)/*num != null*/) {
1473 errln(UnicodeString("Test Failed: \"") + text
+ "\" is parsed as " /*+ num*/);
1476 df
= new DecimalFormat(UnicodeString("$###.00"), status
);
1477 failure(status
, "new DecimalFormat");
1478 df
->parse(UnicodeString("$"), num
, pos2
);
1479 if (pos2
== ParsePosition(0) /*num != null*/){
1480 errln(UnicodeString("Test Failed: \"$\" is parsed as ") /*+ num*/);
1486 /* @bug 4114639 (duplicate of 4106662)
1487 * NumberFormat.parse doesn't return null
1489 void NumberFormatRegressionTest::Test4114639(void)
1491 UErrorCode status
= U_ZERO_ERROR
;
1492 NumberFormat
*format
= NumberFormat::createInstance(status
);
1493 if(U_FAILURE(status
)) {
1494 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1498 failure(status
, "NumberFormat::createInstance");
1499 UnicodeString
text("time 10:x");
1500 ParsePosition
pos(8);
1502 format
->parse(text
, result
, pos
);
1503 if (/*result != null*/pos
.getErrorIndex() != 8)
1504 errln(UnicodeString("Should return null but got : ") /*+ result*/); // Should be null; it isn't
1510 * TODO: this test does not work because we need to use a 64 bit number and a
1511 * a double only MAY only have 52 bits of precision.
1512 * DecimalFormat.format(long n) fails if n * multiplier > MAX_LONG.
1514 void NumberFormatRegressionTest::Test4106664(void)
1516 UErrorCode status
= U_ZERO_ERROR
;
1517 DecimalFormat
*df
= new DecimalFormat(status
);
1518 if(U_FAILURE(status
)) {
1519 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1523 failure(status
, "new DecimalFormat");
1524 // {sfb} long in java is 64 bits
1525 /*long*/double n
= 1234567890123456.0;
1526 /*int*/int32_t m
= 12345678;
1527 // {sfb} will this work?
1528 //BigInteger bigN = BigInteger.valueOf(n);
1529 //bigN = bigN.multiply(BigInteger.valueOf(m));
1530 double bigN
= n
* m
;
1531 df
->setMultiplier(m
);
1532 df
->setGroupingUsed(FALSE
);
1534 FieldPosition
pos(FieldPosition::DONT_CARE
);
1535 logln("formated: " +
1536 df
->format(n
, temp
, pos
));
1539 sprintf(buf
, "%g", bigN
);
1540 //logln("expected: " + bigN.toString());
1541 logln(UnicodeString("expected: ") + buf
);
1545 /* @bug 4106667 (duplicate of 4106658)
1546 * DecimalFormat.format incorrectly formats -0.0.
1548 void NumberFormatRegressionTest::Test4106667(void)
1550 UErrorCode status
= U_ZERO_ERROR
;
1551 DecimalFormat
*df
= new DecimalFormat(status
);
1552 if(U_FAILURE(status
)) {
1553 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1557 failure(status
, "new DecimalFormat");
1558 UChar foo
[] = { 0x002B };
1559 UnicodeString
bar(foo
, 1, 1);
1560 volatile double d
= 0.0; // volatile to prevent code optimization
1562 UnicodeString buffer
;
1563 FieldPosition
pos(FieldPosition::DONT_CARE
);
1565 logln("pattern: \"" + df
->toPattern(temp
) + "\"");
1567 d
= 0.0 * -1.0; // old HPUX compiler ignores volatile keyword
1569 d
*= -1.0; // Some compilers have a problem with defining -0.0
1571 df
->setPositivePrefix(/*"+"*/bar
);
1572 df
->format(d
, buffer
, pos
);
1573 if (buffer
!= UnicodeString("-0")) // Corrected; see 4147706
1574 errln(/*d + */UnicodeString(" is formatted as ") + buffer
);
1580 * DecimalFormat.setMaximumIntegerDigits() works incorrectly.
1583 # define MAX_INT_DIGITS 70
1585 # define MAX_INT_DIGITS 128
1588 void NumberFormatRegressionTest::Test4110936(void)
1590 UErrorCode status
= U_ZERO_ERROR
;
1591 NumberFormat
*nf
= NumberFormat::createInstance(status
);
1592 if(U_FAILURE(status
)) {
1593 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1597 failure(status
, "NumberFormat::createInstance");
1598 nf
->setMaximumIntegerDigits(MAX_INT_DIGITS
);
1599 logln("setMaximumIntegerDigits(MAX_INT_DIGITS)");
1600 if (nf
->getMaximumIntegerDigits() != MAX_INT_DIGITS
)
1601 errln("getMaximumIntegerDigits() returns " +
1602 nf
->getMaximumIntegerDigits());
1608 * Locale data should use generic currency symbol
1610 * 1) Make sure that all currency formats use the generic currency symbol.
1611 * 2) Make sure we get the same results using the generic symbol or a
1614 void NumberFormatRegressionTest::Test4122840(void)
1617 const Locale
*locales
= Locale::getAvailableLocales(count
);
1619 for (int i
= 0; i
< count
; i
++) {
1620 UErrorCode status
= U_ZERO_ERROR
;
1621 ResourceBundle
*rb
= new ResourceBundle(
1622 NULL
/*"java.text.resources.LocaleElements"*/,
1623 locales
[i
], status
);
1624 failure(status
, "new ResourceBundle");
1625 ResourceBundle numPat
= rb
->get("NumberPatterns", status
);
1626 failure(status
, "new ResourceBundle(NumberPatterns)");
1628 // Get the currency pattern for this locale. We have to fish it
1629 // out of the ResourceBundle directly, since DecimalFormat.toPattern
1630 // will return the localized symbol, not \00a4
1632 UnicodeString pattern
= numPat
.getStringEx(1, status
);
1633 failure(status
, "rb->getStringArray");
1635 UChar fo
[] = { 0x00A4 };
1636 UnicodeString
foo(fo
, 1, 1);
1638 //if (pattern.indexOf("\u00A4") == -1 ) {
1639 if (pattern
.indexOf(foo
) == -1 ) {
1640 errln(UnicodeString("Currency format for ") + UnicodeString(locales
[i
].getName()) +
1641 " does not contain generic currency symbol:" +
1645 // Create a DecimalFormat using the pattern we got and format a number
1646 DecimalFormatSymbols
*symbols
= new DecimalFormatSymbols(locales
[i
], status
);
1647 failure(status
, "new DecimalFormatSymbols");
1648 DecimalFormat
*fmt1
= new DecimalFormat(pattern
, *symbols
, status
);
1649 failure(status
, "new DecimalFormat");
1651 UnicodeString result1
;
1652 FieldPosition
pos(FieldPosition::DONT_CARE
);
1653 result1
= fmt1
->format(1.111, result1
, pos
);
1656 // Now substitute in the locale's currency symbol and create another
1657 // pattern. We have to skip locales where the currency symbol
1658 // contains decimal separators, because that confuses things
1660 UChar ba
[] = { 0x002E/*'.'*/ };
1661 UnicodeString
bar(ba
, 1, 1);
1663 if (symbols
->getSymbol(DecimalFormatSymbols::kCurrencySymbol
).indexOf(bar
) == -1) {
1664 // {sfb} Also, switch the decimal separator to the monetary decimal
1665 // separator to mimic the behavior of a currency format
1666 symbols
->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
,
1667 symbols
->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
));
1669 UnicodeString
buf(pattern
);
1670 for (int j
= 0; j
< buf
.length(); j
++) {
1671 if (buf
[j
] == 0x00a4 ) {
1672 if(buf
[j
+ 1] == 0x00a4) {
1673 // {sfb} added to support double currency marker (intl currency sign)
1674 buf
.replace(j
, /*j+*/2, symbols
->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
));
1675 j
+= symbols
->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
).length();
1678 buf
.replace(j
, /*j+*/1, symbols
->getSymbol(DecimalFormatSymbols::kCurrencySymbol
));
1679 j
+= symbols
->getSymbol(DecimalFormatSymbols::kCurrencySymbol
).length() - 1;
1684 DecimalFormat
*fmt2
= new DecimalFormat(buf
, *symbols
, status
);
1685 failure(status
, "new DecimalFormat");
1687 // Get the currency (if there is one) so we can set the rounding and fraction
1688 const UChar
*currency
= fmt1
->getCurrency();
1689 if (*currency
!= 0) {
1690 double rounding
= ucurr_getRoundingIncrement(currency
, &status
);
1691 int32_t frac
= ucurr_getDefaultFractionDigits(currency
, &status
);
1692 if (U_SUCCESS(status
)) {
1693 fmt2
->setRoundingIncrement(rounding
);
1694 fmt2
->setMinimumFractionDigits(frac
);
1695 fmt2
->setMaximumFractionDigits(frac
);
1698 failure(status
, "Fetching currency rounding/fractions");
1702 UnicodeString result2
;
1703 fmt2
->format(1.111, result2
, pos
);
1705 if (result1
!= result2
) {
1706 errln("Results for " + (UnicodeString
)(locales
[i
].getName()) + " differ: " +
1707 result1
+ " vs " + result2
);
1720 * DecimalFormat.format() delivers wrong string.
1722 void NumberFormatRegressionTest::Test4125885(void)
1724 UErrorCode status
= U_ZERO_ERROR
;
1725 double rate
= 12.34;
1726 DecimalFormat
*formatDec
= new DecimalFormat ("000.00", status
);
1727 if(U_FAILURE(status
)) {
1728 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1732 failure(status
, "new DecimalFormat");
1734 logln("toPattern: " + formatDec
->toPattern(temp
));
1735 UnicodeString rateString
;
1736 FieldPosition
pos(FieldPosition::DONT_CARE
);
1737 rateString
= formatDec
->format(rate
, rateString
, pos
);
1738 if (rateString
!= UnicodeString("012.34"))
1739 errln("result : " + rateString
+ " expected : 012.34");
1741 delete formatDec
;// = null;
1742 formatDec
= new DecimalFormat ("+000.00%;-000.00%", status
);
1743 failure(status
, "new DecimalFormat");
1744 logln("toPattern: " + formatDec
->toPattern(temp
));
1745 rateString
.remove();
1746 rateString
= formatDec
->format(rate
, rateString
, pos
);
1747 if (rateString
!= UnicodeString("+012.34%"))
1748 errln("result : " + rateString
+ " expected : +012.34%");
1755 * DecimalFormat produces extra zeros when formatting numbers.
1757 void NumberFormatRegressionTest::Test4134034(void)
1759 UErrorCode status
= U_ZERO_ERROR
;
1760 DecimalFormat
*nf
= new DecimalFormat("##,###,###.00", status
);
1761 failure(status
, "new DecimalFormat");
1764 FieldPosition
pos(FieldPosition::DONT_CARE
);
1765 f
= nf
->format(9.02, f
, pos
);
1766 if (f
== UnicodeString("9.02"))
1769 errln("9.02 -> " + f
+ "; want 9.02");
1772 f
= nf
->format((int32_t)0, f
, pos
);
1773 if (f
== UnicodeString(".00"))
1776 errln("0 -> " + f
+ "; want .00");
1783 * CANNOT REPRODUCE - This bug could not be reproduced. It may be
1784 * a duplicate of 4134034.
1786 * JDK 1.1.6 Bug, did NOT occur in 1.1.5
1787 * Possibly related to bug 4125885.
1789 * This class demonstrates a regression in version 1.1.6
1790 * of DecimalFormat class.
1793 * Value 1.2 Format #.00 Result '01.20' !!!wrong
1794 * Value 1.2 Format 0.00 Result '001.20' !!!wrong
1795 * Value 1.2 Format 00.00 Result '0001.20' !!!wrong
1796 * Value 1.2 Format #0.0# Result '1.2'
1797 * Value 1.2 Format #0.00 Result '001.20' !!!wrong
1800 * Value 1.2 Format #.00 Result '1.20'
1801 * Value 1.2 Format 0.00 Result '1.20'
1802 * Value 1.2 Format 00.00 Result '01.20'
1803 * Value 1.2 Format #0.0# Result '1.2'
1804 * Value 1.2 Format #0.00 Result '1.20'
1806 void NumberFormatRegressionTest::Test4134300(void) {
1807 UnicodeString DATA
[] = {
1808 // Pattern Expected string
1809 UnicodeString("#.00"), UnicodeString("1.20"),
1810 UnicodeString("0.00"), UnicodeString("1.20"),
1811 UnicodeString("00.00"), UnicodeString("01.20"),
1812 UnicodeString("#0.0#"), UnicodeString("1.2"),
1813 UnicodeString("#0.00"), UnicodeString("1.20")
1816 for (int i
=0; i
< 10; i
+=2) {
1817 UnicodeString result
;
1818 UErrorCode status
= U_ZERO_ERROR
;
1819 DecimalFormat
*df
= new DecimalFormat(DATA
[i
], status
);
1820 failure(status
, "new DecimalFormat");
1821 FieldPosition
pos(FieldPosition::DONT_CARE
);
1822 result
= df
->format(1.2, result
, pos
);
1823 if (result
!= DATA
[i
+1]) {
1824 errln("Fail: 1.2 x " + DATA
[i
] + " = " + result
+
1825 "; want " + DATA
[i
+1]);
1828 logln("Ok: 1.2 x " + DATA
[i
] + " = " + result
);
1837 * Empty pattern produces double negative prefix.
1839 void NumberFormatRegressionTest::Test4140009(void)
1841 UErrorCode status
= U_ZERO_ERROR
;
1842 DecimalFormatSymbols
*syms
= new DecimalFormatSymbols(Locale::getEnglish(), status
);
1843 failure(status
, "new DecimalFormatSymbols");
1844 DecimalFormat
*f
= new DecimalFormat(UnicodeString(""), syms
, status
);
1845 failure(status
, "new DecimalFormat");
1847 FieldPosition
pos(FieldPosition::DONT_CARE
);
1848 s
= f
->format(123.456, s
, pos
);
1849 if (s
!= UnicodeString("123.456"))
1850 errln("Fail: Format empty pattern x 123.456 => " + s
);
1852 s
= f
->format(-123.456, s
, pos
);
1853 if (s
!= UnicodeString("-123.456"))
1854 errln("Fail: Format empty pattern x -123.456 => " + s
);
1860 * BigDecimal numbers get their fractions truncated by NumberFormat.
1862 // {sfb} not pertinent in C++ ??
1863 void NumberFormatRegressionTest::Test4141750(void) {
1865 UnicodeString str("12345.67");
1866 BigDecimal bd = new BigDecimal(str);
1867 String sd = NumberFormat.getInstance(Locale.US).format(bd);
1868 if (!sd.endsWith("67")) errln("Fail: " + str + " x format -> " + sd);
1870 catch (Exception e) {
1871 errln(e.toString());
1872 e.printStackTrace();
1878 * DecimalFormat toPattern() doesn't quote special characters or handle
1881 void NumberFormatRegressionTest::Test4145457() {
1883 UErrorCode status
= U_ZERO_ERROR
;
1884 NumberFormat
*nff
= NumberFormat::createInstance(status
);
1885 if (failure(status
, "NumberFormat::createInstance")){
1889 if(nff
->getDynamicClassID() != DecimalFormat::getStaticClassID()) {
1890 errln("DecimalFormat needed to continue");
1894 DecimalFormat
*nf
= (DecimalFormat
*)nff
;
1895 DecimalFormatSymbols
*sym
= (DecimalFormatSymbols
*) nf
->getDecimalFormatSymbols();
1896 sym
->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
, (UChar
)/*'\''*/0x0027);
1897 nf
->setDecimalFormatSymbols(*sym
);
1898 double pi
= 3.14159;
1900 UnicodeString PATS
[] = {
1901 UnicodeString("#.00 'num''ber'"), UnicodeString("''#.00''")
1904 for (int32_t i
=0; i
<2; ++i
) {
1905 nf
->applyPattern(PATS
[i
], status
);
1906 failure(status
, "nf->applyPattern");
1908 FieldPosition
pos(FieldPosition::DONT_CARE
);
1909 out
= nf
->format(pi
, out
, pos
);
1911 pat
= nf
->toPattern(pat
);
1913 ParsePosition
pp(0);
1914 nf
->parse(out
, num
, pp
);
1915 double val
= num
.getDouble();
1917 nf
->applyPattern(pat
, status
);
1918 failure(status
, "nf->applyPattern");
1920 out2
= nf
->format(pi
, out2
, pos
);
1922 pat2
= nf
->toPattern(pat2
);
1923 nf
->parse(out2
, num
, pp
);
1924 double val2
= num
.getDouble();
1927 errln("Fail with \"" + PATS
[i
] + "\": Patterns should concur, \"" +
1928 pat
+ "\" vs. \"" + pat2
+ "\"");
1930 logln("Ok \"" + PATS
[i
] + "\" toPattern() -> \"" + pat
+ '"');
1932 if (val
== val2
&& out
== out2
) {
1933 logln(UnicodeString("Ok ") + pi
+ " x \"" + PATS
[i
] + "\" -> \"" +
1934 out
+ "\" -> " + val
+ " -> \"" +
1935 out2
+ "\" -> " + val2
);
1938 errln(UnicodeString("Fail ") + pi
+ " x \"" + PATS
[i
] + "\" -> \"" +
1939 out
+ "\" -> " + val
+ " -> \"" +
1940 out2
+ "\" -> " + val2
);
1944 catch (ParseException e) {
1945 errln("Fail: " + e);
1946 e.printStackTrace();
1954 * DecimalFormat.applyPattern() sets minimum integer digits incorrectly.
1956 * This bug is a duplicate of 4139344, which is a duplicate of 4134300
1958 void NumberFormatRegressionTest::Test4147295(void)
1960 UErrorCode status
= U_ZERO_ERROR
;
1961 DecimalFormat
*sdf
= new DecimalFormat(status
);
1962 UnicodeString
pattern("#,###");
1963 logln("Applying pattern \"" + pattern
+ "\"");
1964 sdf
->applyPattern(pattern
, status
);
1965 failure(status
, "sdf->applyPattern");
1966 int minIntDig
= sdf
->getMinimumIntegerDigits();
1967 if (minIntDig
!= 0) {
1968 errln("Test failed");
1969 errln(" Minimum integer digits : " + minIntDig
);
1971 errln(" new pattern: " + sdf
->toPattern(temp
));
1973 logln("Test passed");
1974 logln(" Minimum integer digits : " + minIntDig
);
1981 * DecimalFormat formats -0.0 as +0.0
1982 * See also older related bug 4106658, 4106667
1984 void NumberFormatRegressionTest::Test4147706(void)
1986 UErrorCode status
= U_ZERO_ERROR
;
1987 DecimalFormat
*df
= new DecimalFormat("#,##0.0##", status
);
1988 failure(status
, "new DecimalFormat");
1989 DecimalFormatSymbols
*syms
= new DecimalFormatSymbols(Locale::getEnglish(), status
);
1990 failure(status
, "new DecimalFormatSymbols");
1992 UnicodeString f2
, temp
;
1993 FieldPosition
pos(FieldPosition::DONT_CARE
);
1994 volatile double d1
= 0.0; // volatile to prevent code optimization
1995 double d2
= -0.0001;
1998 d1
= 0.0 * -1.0; // old HPUX compiler ignores volatile keyword
2000 d1
*= -1.0; // Some compilers have a problem with defining -0.0
2002 df
->adoptDecimalFormatSymbols(syms
);
2003 f1
= df
->format(d1
, f1
, pos
);
2004 f2
= df
->format(d2
, f2
, pos
);
2005 if (f1
!= UnicodeString("-0.0")) {
2006 errln(UnicodeString("") + d1
+ UnicodeString(" x \"") + df
->toPattern(temp
) + "\" is formatted as \"" + f1
+ '"');
2008 if (f2
!= UnicodeString("-0.0")) {
2009 errln(UnicodeString("") + d2
+ UnicodeString(" x \"") + df
->toPattern(temp
) + "\" is formatted as \"" + f2
+ '"');
2016 // Not applicable, since no serialization in C++
2017 /*class myformat implements Serializable
2019 DateFormat _dateFormat = DateFormat.getDateInstance();
2023 GregorianCalendar calendar = new GregorianCalendar();
2024 Date t = calendar.getTime();
2025 String nowStr = _dateFormat.format(t);
2032 * NumberFormat cannot format Double.MAX_VALUE
2034 // TODO: make this test actually test something
2036 NumberFormatRegressionTest::Test4162198(void)
2038 // for some reason, DBL_MAX will not round trip. (bug in sprintf/atof)
2039 double dbl
= INT32_MAX
* 1000.0;
2040 UErrorCode status
= U_ZERO_ERROR
;
2041 NumberFormat
*f
= NumberFormat::createInstance(status
);
2042 if(U_FAILURE(status
)) {
2043 errln("Couldn't create number format");
2046 f
->setMaximumFractionDigits(INT32_MAX
);
2047 f
->setMaximumIntegerDigits(INT32_MAX
);
2050 logln(UnicodeString("The number ") + dbl
+ " formatted to " + s
);
2053 f
->parse(s
, n
, status
);
2054 if(U_FAILURE(status
))
2055 errln("Couldn't parse!");
2056 //} catch (java.text.ParseException e) {
2057 // errln("Caught a ParseException:");
2058 // e.printStackTrace();
2061 //logln("The string " + s + " parsed as " + n);
2063 // {dlf} The old code assumes n is a double, but it isn't any more...
2064 // Formattable apparently does not and never did interconvert... too bad.
2065 //if(n.getDouble() != dbl) {
2066 // errln("Round trip failure");
2068 if (n
.getInt64() != dbl
) {
2069 errln("Round trip failure");
2077 * NumberFormat does not parse negative zero.
2080 NumberFormatRegressionTest::Test4162852(void)
2082 UErrorCode status
= U_ZERO_ERROR
;
2083 for(int32_t i
=0; i
< 2; ++i
) {
2084 NumberFormat
*f
= (i
== 0) ? NumberFormat::createInstance(status
)
2085 : NumberFormat::createPercentInstance(status
);
2086 if(U_FAILURE(status
)) {
2087 errln("Couldn't create number format");
2095 f
->parse(s
, n
, status
);
2096 if(U_FAILURE(status
))
2097 errln("Couldn't parse!");
2098 double e
= n
.getDouble();
2099 logln(UnicodeString("") +
2101 '"' + s
+ '"' + " -> " + e
);
2102 #if (defined(OS390) && !defined(IEEE_754)) || defined(OS400)
2105 if (e
!= 0.0 || 1.0/e
> 0.0) {
2107 logln("Failed to parse negative zero");
2113 static double _u_abs(double a
) { return a
<0?-a
:a
; }
2116 * May 17 1999 sync up - liu
2118 * NumberFormat truncates data
2120 void NumberFormatRegressionTest::Test4167494(void) {
2121 UErrorCode status
= U_ZERO_ERROR
;
2122 NumberFormat
*fmt
= NumberFormat::createInstance(Locale::getUS(), status
);
2123 if (failure(status
, "NumberFormat::createInstance")){
2128 double a
= DBL_MAX
* 0.99; // DBL_MAX itself overflows to +Inf
2132 fmt
->parse(s
, num
, status
);
2133 failure(status
, "Parse");
2134 if (num
.getType() == Formattable::kDouble
&&
2135 _u_abs(num
.getDouble() - a
) / a
< 0.01) { // RT within 1%
2136 logln(UnicodeString("") + a
+ " -> \"" + s
+ "\" -> " +
2137 toString(num
) + " ok");
2139 errln(UnicodeString("") + a
+ " -> \"" + s
+ "\" -> " +
2140 toString(num
) + " FAIL");
2143 // We don't test Double.MIN_VALUE because the locale data for the US
2144 // currently doesn't specify enough digits to display Double.MIN_VALUE.
2145 // This is correct for now; however, we leave this here as a reminder
2146 // in case we want to address this later.
2152 * May 17 1999 sync up - liu
2154 * DecimalFormat.parse() fails when ParseIntegerOnly set to true
2156 void NumberFormatRegressionTest::Test4170798(void) {
2157 UErrorCode status
= U_ZERO_ERROR
;
2158 NumberFormat
*nf
= NumberFormat::createInstance(Locale::getUS(), status
);
2159 if (failure(status
, "NumberFormat::createInstance")){
2163 if(nf
->getDynamicClassID() != DecimalFormat::getStaticClassID()) {
2164 errln("DecimalFormat needed to continue");
2167 DecimalFormat
*df
= (DecimalFormat
*) nf
;
2168 df
->setParseIntegerOnly(TRUE
);
2170 ParsePosition
pos(0);
2171 df
->parse("-0.0", n
, pos
);
2172 if (n
.getType() != Formattable::kLong
2173 || n
.getLong() != 0) {
2174 errln(UnicodeString("FAIL: parse(\"-0.0\") returns ") + toString(n
));
2180 * May 17 1999 sync up - liu
2181 * toPattern only puts the first grouping separator in.
2183 void NumberFormatRegressionTest::Test4176114(void) {
2184 const char* DATA
[] = {
2186 "000", "#000", // No grouping
2187 "#000", "#000", // No grouping
2191 "00,000", "#00,000",
2192 "000,000", "#,000,000",
2193 "0,000,000,000,000.0000", "#0,000,000,000,000.0000", // Reported
2195 int DATA_length
= (int)(sizeof(DATA
) / sizeof(DATA
[0]));
2196 UErrorCode status
= U_ZERO_ERROR
;
2198 for (int i
=0; i
<DATA_length
; i
+=2) {
2199 DecimalFormat
df(DATA
[i
], status
);
2200 failure(status
, "DecimalFormat constructor");
2202 UnicodeString
exp(DATA
[i
+1]);
2204 errln(UnicodeString("FAIL: ") + DATA
[i
] + " -> " +
2205 s
+ ", want " + exp
);
2211 * May 17 1999 sync up - liu
2213 * DecimalFormat is incorrectly rounding numbers like 1.2501 to 1.2
2215 void NumberFormatRegressionTest::Test4179818(void) {
2216 const char* DATA
[] = {
2217 // Input Pattern Expected output
2218 "1.2511", "#.#", "1.3",
2219 "1.2501", "#.#", "1.3",
2222 int DATA_length
= (int)(sizeof(DATA
) / sizeof(DATA
[0]));
2228 UErrorCode status
= U_ZERO_ERROR
;
2229 DecimalFormatSymbols
sym(Locale::getUS(), status
);
2230 failure(status
, "Construct DecimalFormatSymbols");
2231 DecimalFormat
fmt("#", sym
, status
);
2232 failure(status
, "Construct DecimalFormat");
2233 for (int i
=0; i
<DATA_length
; i
+=3) {
2234 double in
= DOUBLE
[i
/3];
2235 UnicodeString
pat(DATA
[i
+1]);
2236 UnicodeString
exp(DATA
[i
+2]);
2237 fmt
.applyPattern(pat
, status
);
2238 failure(status
, "applyPattern");
2241 fmt
.format(in
, out
, pos
);
2243 logln(UnicodeString("Ok: ") + in
+ " x " + pat
+ " = " + out
);
2245 errln(UnicodeString("FAIL: ") + in
+ " x " + pat
+ " = " + out
+
2246 ", expected " + exp
);
2252 * May 17 1999 sync up - liu
2253 * Some DecimalFormatSymbols changes are not picked up by DecimalFormat.
2254 * This includes the minus sign, currency symbol, international currency
2255 * symbol, percent, and permille. This is filed as bugs 4212072 and
2258 void NumberFormatRegressionTest::Test4212072(void) {
2259 UErrorCode status
= U_ZERO_ERROR
;
2260 DecimalFormatSymbols
sym(Locale::getUS(), status
);
2262 failure(status
, "DecimalFormatSymbols ct", Locale::getUS());
2263 DecimalFormat
fmt(UnicodeString("#"), sym
, status
);
2264 failure(status
, "DecimalFormat ct", Locale::getUS());
2269 sym
.setSymbol(DecimalFormatSymbols::kMinusSignSymbol
, (UChar
)0x5e);
2270 fmt
.setDecimalFormatSymbols(sym
);
2272 if (fmt
.format((int32_t)-1, s
, pos
) != UNICODE_STRING("^1", 2)) {
2273 errln(UnicodeString("FAIL: -1 x (minus=^) -> ") + s
+
2277 if (fmt
.getNegativePrefix(s
) != UnicodeString((UChar
)0x5e)) {
2278 errln(UnicodeString("FAIL: (minus=^).getNegativePrefix -> ") +
2281 sym
.setSymbol(DecimalFormatSymbols::kMinusSignSymbol
, (UChar
)0x2d);
2283 fmt
.applyPattern(UnicodeString("#%"), status
);
2284 failure(status
, "applyPattern percent");
2285 sym
.setSymbol(DecimalFormatSymbols::kPercentSymbol
, (UChar
)0x5e);
2286 fmt
.setDecimalFormatSymbols(sym
);
2288 if (fmt
.format(0.25, s
, pos
) != UNICODE_STRING("25^", 3)) {
2289 errln(UnicodeString("FAIL: 0.25 x (percent=^) -> ") + s
+
2293 if (fmt
.getPositiveSuffix(s
) != UnicodeString((UChar
)0x5e)) {
2294 errln(UnicodeString("FAIL: (percent=^).getPositiveSuffix -> ") +
2297 sym
.setSymbol(DecimalFormatSymbols::kPercentSymbol
, (UChar
)0x25);
2299 fmt
.applyPattern(str("#\\u2030"), status
);
2300 failure(status
, "applyPattern permill");
2301 sym
.setSymbol(DecimalFormatSymbols::kPerMillSymbol
, (UChar
)0x5e);
2302 fmt
.setDecimalFormatSymbols(sym
);
2304 if (fmt
.format(0.25, s
, pos
) != UNICODE_STRING("250^", 4)) {
2305 errln(UnicodeString("FAIL: 0.25 x (permill=^) -> ") + s
+
2309 if (fmt
.getPositiveSuffix(s
) != UnicodeString((UChar
)0x5e)) {
2310 errln(UnicodeString("FAIL: (permill=^).getPositiveSuffix -> ") +
2313 sym
.setSymbol(DecimalFormatSymbols::kPerMillSymbol
, (UChar
)0x2030);
2315 fmt
.applyPattern(str("\\u00A4#.00"), status
);
2316 failure(status
, "applyPattern currency");
2317 sym
.setSymbol(DecimalFormatSymbols::kCurrencySymbol
, "usd");
2318 fmt
.setDecimalFormatSymbols(sym
);
2320 if (fmt
.format(12.5, s
, pos
) != UnicodeString("usd12.50")) {
2321 errln(UnicodeString("FAIL: 12.5 x (currency=usd) -> ") + s
+
2325 if (fmt
.getPositivePrefix(s
) != UnicodeString("usd")) {
2326 errln(UnicodeString("FAIL: (currency=usd).getPositivePrefix -> ") +
2329 sym
.setSymbol(DecimalFormatSymbols::kCurrencySymbol
, "$");
2331 fmt
.applyPattern(str("\\u00A4\\u00A4#.00"), status
);
2332 failure(status
, "applyPattern intl currency");
2333 sym
.setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
, "DOL");
2334 fmt
.setDecimalFormatSymbols(sym
);
2336 if (fmt
.format(12.5, s
, pos
) != UnicodeString("DOL12.50")) {
2337 errln(UnicodeString("FAIL: 12.5 x (intlcurrency=DOL) -> ") + s
+
2341 if (fmt
.getPositivePrefix(s
) != UnicodeString("DOL")) {
2342 errln(UnicodeString("FAIL: (intlcurrency=DOL).getPositivePrefix -> ") +
2345 sym
.setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
, "USD");
2347 // Since the pattern logic has changed, make sure that patterns round
2348 // trip properly. Test stream in/out integrity too.
2350 const Locale
* avail
= NumberFormat::getAvailableLocales(n
);
2351 static const char* type
[] = {
2356 for (int i
=0; i
<n
; ++i
) {
2357 for (int j
=0; j
<3; ++j
) {
2358 status
= U_ZERO_ERROR
;
2362 nf
= NumberFormat::createInstance(avail
[i
], status
);
2363 failure(status
, "createInstance", avail
[i
]);
2366 nf
= NumberFormat::createCurrencyInstance(avail
[i
], status
);
2367 failure(status
, "createCurrencyInstance", avail
[i
]);
2370 nf
= NumberFormat::createPercentInstance(avail
[i
], status
);
2371 failure(status
, "createPercentInstance", avail
[i
]);
2374 if (U_FAILURE(status
)) {
2377 DecimalFormat
*df
= (DecimalFormat
*) nf
;
2379 // Test toPattern/applyPattern round trip
2382 DecimalFormatSymbols
symb(avail
[i
], status
);
2383 failure(status
, "Construct DecimalFormatSymbols", avail
[i
]);
2384 DecimalFormat
f2(pat
, symb
, status
);
2386 UnicodeString("Construct DecimalFormat(") + pat
+ ")")) {
2391 errln(UnicodeString("FAIL: ") + type
[j
] + avail
[i
].getDisplayName(l
) +
2393 "\" -> \"" + f2
.toPattern(p
) + "\"");
2396 // Test toLocalizedPattern/applyLocalizedPattern round trip
2397 df
->toLocalizedPattern(pat
);
2398 f2
.applyLocalizedPattern(pat
, status
);
2400 UnicodeString("applyLocalizedPattern(") + pat
+ ")", avail
[i
]);
2401 if (U_FAILURE(status
)) {
2405 // Make sure we set the currency attributes appropriately
2406 if (j
== 1) { // Currency format
2407 f2
.setCurrency(f2
.getCurrency(), status
);
2410 UnicodeString("setCurrency() for (") + pat
+ ")", avail
[i
]);
2411 if (U_FAILURE(status
)) {
2417 errln(UnicodeString("FAIL: ") + type
[j
] + avail
[i
].getDisplayName(l
) +
2418 " -> localized \"" + pat
+
2419 "\" -> \"" + f2
.toPattern(p
) + "\"");
2424 // Test writeObject/readObject round trip
2425 // NOT ON ICU -- Java only
2431 * May 17 1999 sync up - liu
2432 * DecimalFormat.parse() fails for mulipliers 2^n.
2434 void NumberFormatRegressionTest::Test4216742(void) {
2435 UErrorCode status
= U_ZERO_ERROR
;
2436 DecimalFormat
*fmt
= (DecimalFormat
*) NumberFormat::createInstance(Locale::getUS(), status
);
2437 if (failure(status
, "createInstance", Locale::getUS())){
2441 int32_t DATA
[] = { INT32_MIN
, INT32_MAX
, -100000000, 100000000 };
2442 int DATA_length
= (int)(sizeof(DATA
) / sizeof(DATA
[0]));
2443 for (int i
=0; i
<DATA_length
; ++i
) {
2444 UnicodeString
str((UnicodeString
)"" + DATA
[i
]);
2445 for (int m
= 1; m
<= 100; m
++) {
2446 fmt
->setMultiplier(m
);
2448 fmt
->parse(str
, num
, status
);
2449 failure(status
, "parse", Locale::getUS());
2450 if (num
.getType() != Formattable::kLong
&&
2451 num
.getType() != Formattable::kDouble
) {
2452 errln(UnicodeString("FAIL: Wanted number, got ") +
2455 double d
= num
.getType() == Formattable::kDouble
?
2456 num
.getDouble() : (double) num
.getLong();
2457 if (d
> 0 != DATA
[i
] > 0) {
2458 errln(UnicodeString("\"") + str
+ "\" parse(x " +
2459 fmt
->getMultiplier() +
2460 ") => " + toString(num
));
2469 * May 17 1999 sync up - liu
2470 * DecimalFormat formats 1.001 to "1.00" instead of "1" with 2 fraction
2473 void NumberFormatRegressionTest::Test4217661(void) {
2474 const double D
[] = { 0.001, 1.001, 0.006, 1.006 };
2475 const char* S
[] = { "0", "1", "0.01", "1.01" };
2476 int D_length
= (int)(sizeof(D
) / sizeof(D
[0]));
2477 UErrorCode status
= U_ZERO_ERROR
;
2478 NumberFormat
*fmt
= NumberFormat::createInstance(Locale::getUS(), status
);
2479 if (failure(status
, "createInstance", Locale::getUS())){
2483 fmt
->setMaximumFractionDigits(2);
2484 for (int i
=0; i
<D_length
; i
++) {
2486 fmt
->format(D
[i
], s
);
2487 if (s
!= UnicodeString(S
[i
])) {
2488 errln(UnicodeString("FAIL: Got ") + s
+ ", exp " + S
[i
]);
2495 * alphaWorks upgrade
2497 void NumberFormatRegressionTest::Test4161100(void) {
2498 UErrorCode status
= U_ZERO_ERROR
;
2499 NumberFormat
*nf
= NumberFormat::createInstance(Locale::getUS(), status
);
2500 if (failure(status
, "createInstance", Locale::getUS())){
2504 nf
->setMinimumFractionDigits(1);
2505 nf
->setMaximumFractionDigits(1);
2510 logln(UnicodeString() + a
+ " x " +
2511 ((DecimalFormat
*) nf
)->toPattern(pat
) + " = " + s
);
2512 if (s
!= UnicodeString("-0.1")) {
2519 * June 16 1999 sync up - liu
2520 * Formatting .5 rounds to "1" instead of "0". (Regression in 1.2.2 RC1)
2522 void NumberFormatRegressionTest::Test4243011(void) {
2523 UErrorCode status
= U_ZERO_ERROR
;
2524 DecimalFormatSymbols
sym(Locale::getUS(), status
);
2525 failure(status
, "DecimalFormatSymbols ct", Locale::getUS());
2526 DecimalFormat
fmt(UnicodeString("0."), sym
, status
);
2527 failure(status
, "DecimalFormat ct", Locale::getUS());
2529 const double NUM
[] = { -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5 };
2530 const char* STR
[] = { "-2.", "-2.", "-0.", "0.", "2.", "2.", "4.", "4." };
2531 int32_t N
= (int32_t)(sizeof(NUM
) / sizeof(NUM
[0]));
2533 for (int32_t i
=0; i
<N
; ++i
) {
2535 UnicodeString
exp(STR
[i
]);
2537 fmt
.format(NUM
[i
], str
, pos
);
2539 logln(UnicodeString("Ok ") + NUM
[i
] + " x 0. = " + str
);
2541 errln(UnicodeString("FAIL ") + NUM
[i
] + " x 0. = " + str
+
2548 * June 16 1999 sync up - liu
2549 * format(0.0) gives "0.1" if preceded by parse("99.99").
2550 * (Regression in 1.2.2 RC1)
2552 void NumberFormatRegressionTest::Test4243108(void) {
2553 UErrorCode status
= U_ZERO_ERROR
;
2554 DecimalFormatSymbols
sym(Locale::getUS(), status
);
2555 failure(status
, "DecimalFormatSymbols ct", Locale::getUS());
2556 DecimalFormat
fmt(UnicodeString("#.#"), sym
, status
);
2557 failure(status
, "DecimalFormat ct", Locale::getUS());
2562 fmt
.format(0.0, str
, pos
);
2563 UnicodeString
exp("0");
2565 logln(UnicodeString("Ok 0.0 x #.# = ") + str
);
2567 errln(UnicodeString("FAIL 0.0 x #.# = ") + str
+
2573 fmt
.parse(str
, val
, status
);
2574 failure(status
, "DecimalFormat.parse(99.99)", Locale::getUS());
2575 if (val
.getType() == Formattable::kDouble
&&
2576 val
.getDouble() == 99.99) {
2577 logln(UnicodeString("Ok 99.99 / #.# = ") + toString(val
));
2579 errln(UnicodeString("FAIL 99.99 / #.# = ") + toString(val
) +
2584 fmt
.format(0.0, str
, pos
);
2586 logln(UnicodeString("Ok 0.0 x #.# = ") + str
);
2588 errln(UnicodeString("FAIL 0.0 x #.# = ") + str
+
2595 * DateFormat should call setIntegerParseOnly(TRUE) on adopted
2596 * NumberFormat objects.
2598 void NumberFormatRegressionTest::TestJ691(void) {
2599 UErrorCode status
= U_ZERO_ERROR
;
2600 Locale
loc("fr", "CH");
2602 // set up the input date string & expected output
2603 UnicodeString
udt("11.10.2000", "");
2604 UnicodeString
exp("11.10.00", "");
2606 // create a Calendar for this locale
2607 Calendar
*cal
= Calendar::createInstance(loc
, status
);
2608 if (U_FAILURE(status
)) {
2609 errln("FAIL: Calendar::createInstance() returned " + (UnicodeString
)u_errorName(status
));
2613 // create a NumberFormat for this locale
2614 NumberFormat
*nf
= NumberFormat::createInstance(loc
, status
);
2615 if (U_FAILURE(status
)) {
2616 errln("FAIL: NumberFormat::createInstance() returned " + (UnicodeString
)u_errorName(status
));
2620 // *** Here's the key: We don't want to have to do THIS:
2621 // nf->setParseIntegerOnly(TRUE);
2623 // create the DateFormat
2624 DateFormat
*df
= DateFormat::createDateInstance(DateFormat::kShort
, loc
);
2625 if (U_FAILURE(status
)) {
2626 errln("FAIL: DateFormat::createInstance() returned " + (UnicodeString
)u_errorName(status
));
2630 df
->adoptCalendar(cal
);
2631 df
->adoptNumberFormat(nf
);
2633 // set parsing to lenient & parse
2634 df
->setLenient(TRUE
);
2635 UDate ulocdat
= df
->parse(udt
, status
);
2637 // format back to a string
2638 UnicodeString outString
;
2639 df
->format(ulocdat
, outString
);
2641 if (outString
!= exp
) {
2642 errln("FAIL: " + udt
+ " => " + outString
);
2648 #endif /* #if !UCONFIG_NO_FORMATTING */