1 /***********************************************************************
2 * Copyright (c) 1997-2008, 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
,
33 UErrorCode
& status
) const
35 return NumberFormat::format(number
, toAppendTo
, pos
, 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
);
172 default: name
= ""; break;
177 NumberFormatRegressionTest::failure(UErrorCode status
, const UnicodeString
& msg
, const Locale
& l
)
179 if(U_FAILURE(status
)) {
180 errln(UnicodeString("FAIL: ", "") + msg
181 + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status
), "") + UnicodeString(l
.getName(),""));
189 NumberFormatRegressionTest::failure(UErrorCode status
, const UnicodeString
& msg
, const char *l
)
191 if(U_FAILURE(status
)) {
192 errln(UnicodeString("FAIL: ", "") + msg
193 + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status
), "") + UnicodeString(l
, ""));
201 NumberFormatRegressionTest::failure(UErrorCode status
, const UnicodeString
& msg
)
203 if(U_FAILURE(status
)) {
204 errln(UnicodeString("FAIL: ", "") + msg
205 + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status
), ""));
213 * Convert Java-style strings with \u Unicode escapes into UnicodeString objects
215 inline UnicodeString
str(const char *input
)
217 return CharsToUnicodeString(input
);
221 * NumberFormat.equals comparing with null should always return false.
223 // {sfb} kind of silly in C++, just checking for new success
224 void NumberFormatRegressionTest::Test4075713(void)
227 MyNumberFormatTest
*tmp
= new MyNumberFormatTest();
229 logln("NumberFormat.equals passed");
230 /*} catch (NullPointerException e) {
231 errln("(new MyNumberFormatTest()).equals(null) throws unexpected exception");
238 * NumberFormat.equals comparing two obj equal even the setGroupingUsed
241 void NumberFormatRegressionTest::Test4074620(void)
244 MyNumberFormatTest
*nf1
= new MyNumberFormatTest();
245 MyNumberFormatTest
*nf2
= new MyNumberFormatTest();
247 nf1
->setGroupingUsed(FALSE
);
248 nf2
->setGroupingUsed(TRUE
);
251 errln("Test for bug 4074620 failed");
253 logln("Test for bug 4074620 passed.");
261 * DecimalFormat.format() incorrectly uses maxFractionDigits setting.
264 void NumberFormatRegressionTest::Test4088161 (void)
266 UErrorCode status
= U_ZERO_ERROR
;
267 DecimalFormat
*df
= new DecimalFormat(status
);
268 failure(status
, "new DecimalFormat", "");
270 df
->setMinimumFractionDigits(0);
271 df
->setMaximumFractionDigits(16);
273 FieldPosition
fp1(0);
274 logln(UnicodeString("d = ") + d
);
275 logln("maxFractionDigits = " + df
->getMaximumFractionDigits());
277 logln(" format(d) = '" + df
->format(d
, sBuf1
, fp1
) + "'");
278 df
->setMaximumFractionDigits(17);
280 FieldPosition
fp2(0);
281 logln("maxFractionDigits = " + df
->getMaximumFractionDigits());
282 sBuf2
= df
->format(d
, sBuf2
, fp2
);
284 errln(" format(d) = '" + sBuf2
+ "'");
290 * DecimalFormatSymbols should be cloned in the ctor DecimalFormat.
291 * DecimalFormat(String, DecimalFormatSymbols).
293 void NumberFormatRegressionTest::Test4087245 (void)
295 UErrorCode status
= U_ZERO_ERROR
;
296 DecimalFormatSymbols
*symbols
= new DecimalFormatSymbols(status
);
297 failure(status
, "new DecimalFormatSymbols", "");
298 // {sfb} One note about this test: if you pass in a pointer
299 // to the symbols, they are adopted and this test will fail,
300 // even though that is the correct behavior. To test the cloning
301 // of the symbols, it is necessary to pass in a reference to the symbols
302 DecimalFormat
*df
= new DecimalFormat("#,##0.0", *symbols
, status
);
303 failure(status
, "new DecimalFormat with symbols", "");
307 FieldPosition
pos(FieldPosition::DONT_CARE
);
308 logln(UnicodeString("format(") + n
+ ") = " +
309 df
->format(n
, buf1
, pos
));
310 symbols
->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
, UnicodeString((UChar
)0x70)); // change value of field
311 logln(UnicodeString("format(") + n
+ ") = " +
312 df
->format(n
, buf2
, pos
));
314 errln("Test for bug 4087245 failed");
321 * DecimalFormat.format() incorrectly formats 0.0
323 void NumberFormatRegressionTest::Test4087535 (void)
325 UErrorCode status
= U_ZERO_ERROR
;
326 DecimalFormat
*df
= new DecimalFormat(status
);
327 failure(status
, "new DecimalFormat", "");
328 df
->setMinimumIntegerDigits(0);
331 UnicodeString buffer
;
332 FieldPosition
pos(FieldPosition::DONT_CARE
);
333 buffer
= df
->format(n
, buffer
, pos
);
334 if (buffer
.length() == 0)
335 errln(/*n + */": '" + buffer
+ "'");
337 buffer
= df
->format(n
, buffer
, pos
);
338 if (buffer
.length() == 0)
339 errln(/*n + */": '" + buffer
+ "'");
345 * DecimalFormat.format fails when groupingSize is set to 0.
347 // {sfb} how do I tell if this worked? --> FieldPosition doesn't change ??
348 void NumberFormatRegressionTest::Test4088503 (void)
350 UErrorCode status
= U_ZERO_ERROR
;
351 DecimalFormat
*df
= new DecimalFormat(status
);
352 failure(status
, "new DecimalFormat", "");
353 df
->setGroupingSize(0);
355 FieldPosition
fp(FieldPosition::DONT_CARE
);
357 logln(df
->format((int32_t)123, sBuf
, fp
));
358 //if(fp == FieldPosition(0))
359 // errln("Test for bug 4088503 failed.");
360 /*} catch (Exception foo) {
361 errln("Test for bug 4088503 failed.");
367 * NumberFormat.getCurrencyInstance is wrong.
369 void NumberFormatRegressionTest::Test4066646 (void)
371 assignFloatValue(2.04f
);
372 assignFloatValue(2.03f
);
373 assignFloatValue(2.02f
);
374 assignFloatValue(0.0f
);
378 NumberFormatRegressionTest::assignFloatValue(float returnfloat
)
380 logln(UnicodeString(" VALUE ") + returnfloat
);
381 UErrorCode status
= U_ZERO_ERROR
;
382 NumberFormat
*nfcommon
= NumberFormat::createCurrencyInstance(Locale::getUS(), status
);
383 if (failure(status
, "NumberFormat::createCurrencyInstance", Locale::getUS())){
387 nfcommon
->setGroupingUsed(FALSE
);
389 UnicodeString stringValue
;
390 stringValue
= nfcommon
->format(returnfloat
, stringValue
);
391 logln(" DISPLAYVALUE " + stringValue
);
393 nfcommon
->parse(stringValue
, result
, status
);
394 failure(status
, "nfcommon->parse", Locale::getUS());
395 float floatResult
= (float) (result
.getType() == Formattable::kDouble
396 ? result
.getDouble() : result
.getLong());
397 if( uprv_fabs(floatResult
- returnfloat
) > 0.0001)
398 //String stringValue = nfcommon.format(returnfloat).substring(1);
399 //if (Float.valueOf(stringValue).floatValue() != returnfloat)
400 errln(UnicodeString("FAIL: expected ") + returnfloat
+ ", got " + floatResult
+ " (" + stringValue
+")");
404 } // End Of assignFloatValue()
407 * DecimalFormat throws exception when parsing "0"
409 void NumberFormatRegressionTest::Test4059870(void)
411 UErrorCode status
= U_ZERO_ERROR
;
412 DecimalFormat
*format
= new DecimalFormat("00", status
);
413 failure(status
, "new Decimalformat", Locale::getUS());
417 format
->parse(UnicodeString("0"), result
, status
);
418 failure(status
, "format->parse", Locale::getUS());
421 catch (Exception e) {
422 errln("Test for bug 4059870 failed : " + e);
428 * DecimalFormatSymbol.equals should always return false when
429 * comparing with null.
431 // {sfb} this is silly in C++
432 void NumberFormatRegressionTest::Test4083018 (void)
434 UErrorCode status
= U_ZERO_ERROR
;
435 DecimalFormatSymbols
*dfs
= new DecimalFormatSymbols(status
);
436 failure(status
, "new DecimalFormatSymbols", Locale::getUS());
439 logln("Test Passed!");
441 errln("Test for bug 4083018 failed");
442 /*} catch (Exception foo) {
443 errln("Test for bug 4083018 failed => Message : " + foo.getMessage());
450 * DecimalFormat does not round up correctly.
452 void NumberFormatRegressionTest::Test4071492 (void)
454 double x
= 0.00159999;
455 UErrorCode status
= U_ZERO_ERROR
;
456 NumberFormat
*nf
= NumberFormat::createInstance(status
);
457 if (failure(status
, "NumberFormat::createInstance", Locale::getUS())) {
461 nf
->setMaximumFractionDigits(4);
463 FieldPosition
pos(FieldPosition::DONT_CARE
);
464 out
= nf
->format(x
, out
, pos
);
465 logln("0.00159999 formats with 4 fractional digits to " + out
);
466 UnicodeString
expected("0.0016");
468 errln("FAIL: Expected " + expected
);
474 * A space as a group separator for localized pattern causes
475 * wrong format. WorkAround : use non-breaking space.
477 void NumberFormatRegressionTest::Test4086575(void)
479 UErrorCode status
= U_ZERO_ERROR
;
480 NumberFormat
*nf1
= NumberFormat::createInstance(Locale::getFrance(), status
);
482 // TODO: There is not a good way to find out that the creation of this number format has
483 // failed. Major rewiring of format construction proposed.
484 if(U_FAILURE(status
)) {
485 errln("Something is wrong with French number format - it should not fallback. Exitting");
489 failure(status
, "NumberFormat::createInstance", Locale::getFrance());
491 // C++ workaround to make sure cast works
492 // Wouldn't dynamic_cast<DecimalFormat*> be great?
493 if(nf1
->getDynamicClassID() != DecimalFormat::getStaticClassID()) {
494 errln("NumberFormat::createInstance returned incorrect type.");
498 DecimalFormat
*nf
= (DecimalFormat
*) nf1
;
500 logln("nf toPattern1: " + nf
->toPattern(temp
));
501 logln("nf toLocPattern1: " + nf
->toLocalizedPattern(temp
));
503 // No group separator
504 logln("...applyLocalizedPattern ###,00;(###,00) ");
505 nf
->applyLocalizedPattern(UnicodeString("###,00;(###,00)"), status
);
506 failure(status
, "nf->applyLocalizedPattern", Locale::getFrance());
507 logln("nf toPattern2: " + nf
->toPattern(temp
));
508 logln("nf toLocPattern2: " + nf
->toLocalizedPattern(temp
));
510 FieldPosition
pos(FieldPosition::DONT_CARE
);
511 logln("nf: " + nf
->format((int32_t)1234, temp
, pos
)); // 1234,00
512 logln("nf: " + nf
->format((int32_t)-1234, temp
, pos
)); // (1234,00)
514 // Space as group separator
516 logln("...applyLocalizedPattern # ###,00;(# ###,00) ");
518 //nf->applyLocalizedPattern("#\u00a0###,00;(#\u00a0###,00)");
520 0x23, 0x00a0, 0x23, 0x23, 0x23, 0x2c, 0x30, 0x30, 0x3b,
521 0x28, 0x23, 0x00a0, 0x23, 0x23, 0x23, 0x2c, 0x30, 0x30, 0x29
523 UnicodeString
pat(patChars
, 19, 19);
524 nf
->applyLocalizedPattern(pat
, status
);
525 failure(status
, "nf->applyLocalizedPattern", Locale::getFrance());
526 logln("nf toPattern2: " + nf
->toPattern(temp
));
527 logln("nf toLocPattern2: " + nf
->toLocalizedPattern(temp
));
528 UnicodeString buffer
;
529 buffer
= nf
->format((int32_t)1234, buffer
, pos
);
530 //if (buffer != UnicodeString("1\u00a0234,00"))
532 0x31, 0x00a0, 0x32, 0x33, 0x34, 0x2c, 0x30, 0x30
534 UnicodeString
cc(c
, 8, 8);
536 errln("nf : " + buffer
); // Expect 1 234,00
539 buffer
= nf
->format((int32_t)-1234, buffer
, pos
);
541 0x28, 0x31, 0x00a0, 0x32, 0x33, 0x34, 0x2c, 0x30, 0x30, 0x29
543 UnicodeString
cc1(c1
, 10, 10);
545 errln("nf : " + buffer
); // Expect (1 234,00)
547 // Erroneously prints:
554 * DecimalFormat.parse returns wrong value
556 // {sfb} slightly converted into a round-trip test, since in C++
557 // there is no Double.toString()
558 void NumberFormatRegressionTest::Test4068693(void)
560 logln("----- Test Application -----");
561 ParsePosition
pos(0);
562 UErrorCode status
= U_ZERO_ERROR
;
563 DecimalFormat
*df
= new DecimalFormat(status
);
564 if(U_FAILURE(status
)) {
565 errln("Error creating DecimalFormat: %s", u_errorName(status
));
569 failure(status
, "new DecimalFormat");
571 //Double d = (Double)df.parse("123.55456", pos=new ParsePosition(0));
572 df
->parse(UnicodeString("123.55456"), d
, pos
);
573 //if (!d.toString().equals("123.55456")) {
575 df
->setMaximumFractionDigits(999);
576 df
->setMaximumIntegerDigits(999);
577 FieldPosition
fp(FieldPosition::DONT_CARE
);
578 dstr
= df
->format(d
.getDouble(), dstr
, fp
);
579 if (dstr
!= UnicodeString("123.55456")) {
580 errln(UnicodeString("Result -> ") + d
.getDouble());
586 /* @bug 4069754, 4067878
587 * null pointer thrown when accessing a deserialized DecimalFormat
590 // {sfb} doesn't apply in C++
591 void NumberFormatRegressionTest::Test4069754(void)
594 myformat it = new myformat();
596 FileOutputStream ostream = new FileOutputStream("t.tmp");
597 ObjectOutputStream p = new ObjectOutputStream(ostream);
602 FileInputStream istream = new FileInputStream("t.tmp");
603 ObjectInputStream p2 = new ObjectInputStream(istream);
604 myformat it2 = (myformat)p2.readObject();
608 } catch (Exception foo) {
609 errln("Test for bug 4069754 or 4057878 failed => Exception: " + foo.getMessage());
614 * DecimalFormat.applyPattern(String) allows illegal patterns
616 void NumberFormatRegressionTest::Test4087251 (void)
618 UErrorCode status
= U_ZERO_ERROR
;
619 DecimalFormat
*df
= new DecimalFormat(status
);
620 if(U_FAILURE(status
)) {
621 errln("Error creating DecimalFormat: %s", u_errorName(status
));
625 failure(status
, "new DecimalFormat");
627 df
->applyPattern(UnicodeString("#.#.#"), status
);
628 if( ! U_FAILURE(status
))
629 errln("df->applyPattern with illegal pattern didn't fail");
631 logln("toPattern() returns \"" + df
->toPattern(temp
) + "\"");
632 //errln("applyPattern(\"#.#.#\") doesn't throw IllegalArgumentException");
633 /*} catch (IllegalArgumentException e) {
634 logln("Caught Illegal Argument Error !");
636 // Second test; added 5/11/98 when reported to fail on 1.2b3
638 df
->applyPattern("#0.0#0#0", status
);
639 if( ! U_FAILURE(status
))
640 errln("df->applyPattern with illegal pattern didn't fail");
641 logln("toPattern() returns \"" + df
->toPattern(temp
) + "\"");
642 //errln("applyPattern(\"#0.0#0#0\") doesn't throw IllegalArgumentException");
643 /*} catch (IllegalArgumentException e) {
644 logln("Ok - IllegalArgumentException for #0.0#0#0");
651 * DecimalFormat.format() loses precision
653 void NumberFormatRegressionTest::Test4090489 (void)
655 // {sfb} sprintf doesn't correctly handle the double, so there is nothing
656 // that NumberFormat can do. For some reason, it does not format the last 1.
658 /* UErrorCode status = U_ZERO_ERROR;
659 DecimalFormat *df = new DecimalFormat(status);
660 failure(status, "new DecimalFormat");
661 df->setMinimumFractionDigits(10);
662 df->setMaximumFractionDigits(999);
663 df->setGroupingUsed(FALSE);
664 double d = 1.000000000000001E7;
665 //BigDecimal bd = new BigDecimal(d);
668 logln(UnicodeString("d = ") + d);
669 //logln("BigDecimal.toString(): " + bd.toString());
670 df->format(d, sb, fp);
671 if (sb != "10000000.0000000100") {
672 errln("DecimalFormat.format(): " + sb);
678 * DecimalFormat.format() loses precision
680 void NumberFormatRegressionTest::Test4090504 (void)
683 logln(UnicodeString("d = ") + d
);
684 UErrorCode status
= U_ZERO_ERROR
;
685 DecimalFormat
*df
= new DecimalFormat(status
);
686 if(U_FAILURE(status
)) {
687 errln("Error creating DecimalFormat: %s", u_errorName(status
));
691 failure(status
, "new DecimalFormat");
693 FieldPosition
fp(FieldPosition::DONT_CARE
);
695 for (int i
= 17; i
<= 20; i
++) {
696 df
->setMaximumFractionDigits(i
);
697 //sb = new StringBuffer("");
699 logln(" getMaximumFractionDigits() = " + i
);
700 logln(" formated: " + df
->format(d
, sb
, fp
));
702 /*} catch (Exception foo) {
703 errln("Bug 4090504 regression test failed. Message : " + foo.getMessage());
709 * DecimalFormat.parse(String str, ParsePosition pp) loses precision
711 void NumberFormatRegressionTest::Test4095713 (void)
713 UErrorCode status
= U_ZERO_ERROR
;
714 DecimalFormat
*df
= new DecimalFormat(status
);
715 if(U_FAILURE(status
)) {
716 errln("Error creating DecimalFormat: %s", u_errorName(status
));
720 failure(status
, "new DecimalFormat");
721 UnicodeString
str("0.1234");
723 //Double d1 = new Double(str);
724 //Double d2 = (Double) df.parse(str, new ParsePosition(0));
727 df
->parse(str
, d2
, pp
);
728 logln(UnicodeString("") + d1
);
729 if (d2
.getDouble() != d1
)
730 errln(UnicodeString("Bug 4095713 test failed, new double value : ") + d2
.getDouble());
735 * DecimalFormat.parse() fails when multiplier is not set to 1
737 // {sfb} not sure what to do with this one
738 void NumberFormatRegressionTest::Test4092561 (void)
740 UErrorCode status
= U_ZERO_ERROR
;
741 DecimalFormat
*df
= new DecimalFormat(status
);
742 if(U_FAILURE(status
)) {
743 errln("Error creating DecimalFormat: %s", u_errorName(status
));
747 failure(status
, "new DecimalFormat");
749 // {sfb} going to cheat here and use sprintf ??
751 /*UnicodeString str = Long.toString(Long.MIN_VALUE);
752 logln("Long.MIN_VALUE : " + df.parse(str, new ParsePosition(0)).toString());
753 df.setMultiplier(100);
754 Number num = df.parse(str, new ParsePosition(0));
755 if (num.doubleValue() != -9.223372036854776E16)
756 errln("Bug 4092561 test failed when multiplier is set to not 1.");
762 * DecimalFormat: Negative format ignored.
764 void NumberFormatRegressionTest::Test4092480 (void)
766 UErrorCode status
= U_ZERO_ERROR
;
767 DecimalFormat
*dfFoo
= new DecimalFormat(UnicodeString("000"), status
);
768 if(U_FAILURE(status
)) {
769 errln("Error creating DecimalFormat: %s", u_errorName(status
));
773 failure(status
, "new DecimalFormat");
776 dfFoo
->applyPattern("0000;-000", status
);
777 failure(status
, "dfFoo->applyPattern");
779 if (dfFoo
->toPattern(temp
) != UnicodeString("#0000"))
780 errln("dfFoo.toPattern : " + dfFoo
->toPattern(temp
));
781 FieldPosition
pos(FieldPosition::DONT_CARE
);
782 logln(dfFoo
->format((int32_t)42, temp
, pos
));
783 logln(dfFoo
->format((int32_t)-42, temp
, pos
));
784 dfFoo
->applyPattern("000;-000", status
);
785 failure(status
, "dfFoo->applyPattern");
786 if (dfFoo
->toPattern(temp
) != UnicodeString("#000"))
787 errln("dfFoo.toPattern : " + dfFoo
->toPattern(temp
));
788 logln(dfFoo
->format((int32_t)42,temp
, pos
));
789 logln(dfFoo
->format((int32_t)-42, temp
, pos
));
791 dfFoo
->applyPattern("000;-0000", status
);
792 failure(status
, "dfFoo->applyPattern");
793 if (dfFoo
->toPattern(temp
) != UnicodeString("#000"))
794 errln("dfFoo.toPattern : " + dfFoo
->toPattern(temp
));
795 logln(dfFoo
->format((int32_t)42, temp
, pos
));
796 logln(dfFoo
->format((int32_t)-42, temp
, pos
));
798 dfFoo
->applyPattern("0000;-000", status
);
799 failure(status
, "dfFoo->applyPattern");
800 if (dfFoo
->toPattern(temp
) != UnicodeString("#0000"))
801 errln("dfFoo.toPattern : " + dfFoo
->toPattern(temp
));
802 logln(dfFoo
->format((int32_t)42, temp
, pos
));
803 logln(dfFoo
->format((int32_t)-42, temp
, pos
));
804 /*} catch (Exception foo) {
805 errln("Message " + foo.getMessage());
811 * NumberFormat.getCurrencyInstance() produces format that uses
812 * decimal separator instead of monetary decimal separator.
814 * Rewrote this test not to depend on the actual pattern. Pattern should
815 * never contain the monetary separator! Decimal separator in pattern is
816 * interpreted as monetary separator if currency symbol is seen!
818 void NumberFormatRegressionTest::Test4087244 (void) {
819 UErrorCode status
= U_ZERO_ERROR
;
821 uloc_canonicalize("pt_PT_PREEURO", loc
, 256, &status
);
822 Locale
*de
= new Locale(loc
);
823 NumberFormat
*nf
= NumberFormat::createCurrencyInstance(*de
, status
);
824 if(U_FAILURE(status
)) {
825 errln("Error creating DecimalFormat: %s", u_errorName(status
));
829 if (nf
->getDynamicClassID() != DecimalFormat::getStaticClassID()) {
830 errln("expected DecimalFormat!");
833 DecimalFormat
*df
= (DecimalFormat
*) nf
;
834 const DecimalFormatSymbols
*sym
= df
->getDecimalFormatSymbols();
835 UnicodeString decSep
= sym
->getSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
);
836 UnicodeString monSep
= sym
->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
);
837 if (decSep
== monSep
) {
838 errln("ERROR in test: want decimal sep != monetary sep");
841 df
->setMinimumIntegerDigits(1);
842 df
->setMinimumFractionDigits(2);
845 df
->format(1.23, str
, pos
);
846 UnicodeString
monStr("1x23");
847 monStr
.replace((int32_t)1, 1, monSep
);
848 UnicodeString
decStr("1x23");
849 decStr
.replace((int32_t)1, 1, decSep
);
850 if (str
.indexOf(monStr
) >= 0 && str
.indexOf(decStr
) < 0) {
851 logln(UnicodeString("OK: 1.23 -> \"") + str
+ "\" contains \"" +
852 monStr
+ "\" and not \"" + decStr
+ '"');
854 errln(UnicodeString("FAIL: 1.23 -> \"") + str
+ "\", should contain \"" +
856 "\" and not \"" + decStr
+ '"');
862 * Number format data rounding errors for locale FR
864 void NumberFormatRegressionTest::Test4070798 (void)
866 NumberFormat
*formatter
;
867 UnicodeString tempString
;
870 String expectedDefault = "-5\u00a0789,987";
871 String expectedCurrency = "5\u00a0789,98\u00a0F";
872 String expectedPercent = "-578\u00a0998%";
875 0x2d, 0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x38, 0x38
878 0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x39, 0x00a0, 0x46
881 0x2d, 0x35, 0x37, 0x38, 0x00a0, 0x39, 0x39, 0x39, 0x00a0, 0x25
883 UnicodeString
expectedDefault(chars1
, 10, 10);
884 UnicodeString
expectedCurrency(chars2
, 10, 10);
885 UnicodeString
expectedPercent(chars3
, 10, 10);
887 UErrorCode status
= U_ZERO_ERROR
;
889 int len
= uloc_canonicalize("fr_FR_PREEURO", loc
, 256, &status
);
890 formatter
= NumberFormat::createInstance(Locale(loc
), status
);
891 if(U_FAILURE(status
)) {
892 errln("Error creating DecimalFormat: %s", u_errorName(status
));
896 failure(status
, "NumberFormat::createNumberInstance", loc
);
897 tempString
= formatter
->format (-5789.9876, tempString
);
899 if (tempString
== expectedDefault
) {
900 logln ("Bug 4070798 default test passed.");
902 errln(UnicodeString("Failed:") +
903 " Expected " + expectedDefault
+
904 " Received " + tempString
);
907 len
= uloc_canonicalize("fr_FR_PREEURO", loc
, 256, &status
);
908 formatter
= NumberFormat::createCurrencyInstance(loc
, status
);
909 failure(status
, "NumberFormat::createCurrencyInstance", loc
);
911 tempString
= formatter
->format( 5789.9876, tempString
);
913 if (tempString
== expectedCurrency
) {
914 logln ("Bug 4070798 currency test passed.");
916 errln(UnicodeString("Failed:") +
917 " Expected " + expectedCurrency
+
918 " Received " + tempString
);
922 uloc_canonicalize("fr_FR_PREEURO", loc
, 256, &status
);
923 formatter
= NumberFormat::createPercentInstance(Locale(loc
), status
);
924 failure(status
, "NumberFormat::createPercentInstance", loc
);
926 tempString
= formatter
->format (-5789.9876, tempString
);
928 if (tempString
== expectedPercent
) {
929 logln ("Bug 4070798 percentage test passed.");
931 errln(UnicodeString("Failed:") +
932 " Expected " + expectedPercent
+
933 " Received " + tempString
);
939 * Data rounding errors for French (Canada) locale
941 void NumberFormatRegressionTest::Test4071005 (void)
943 NumberFormat
*formatter
;
944 UnicodeString tempString
;
946 String expectedDefault = "-5\u00a0789,987";
947 String expectedCurrency = "5\u00a0789,98\u00a0$";
948 String expectedPercent = "-578\u00a0998%";
951 0x2d, 0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x38, 0x38
954 0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x39, 0x00a0, 0x24
957 0x2d, 0x35, 0x37, 0x38, 0x00a0, 0x39, 0x39, 0x39, 0x00a0, 0x25
959 UnicodeString
expectedDefault(chars1
, 10, 10);
960 UnicodeString
expectedCurrency(chars2
, 10, 10);
961 UnicodeString
expectedPercent(chars3
, 10, 10);
963 UErrorCode status
= U_ZERO_ERROR
;
964 formatter
= NumberFormat::createInstance(Locale::getCanadaFrench(), status
);
965 if (failure(status
, "NumberFormat::createNumberInstance", Locale::getCanadaFrench())){
969 tempString
= formatter
->format (-5789.9876, tempString
);
971 if (tempString
== expectedDefault
) {
972 logln ("Bug 4071005 default test passed.");
974 errln(UnicodeString("Failed:") +
975 " Expected " + expectedDefault
+
976 " Received " + tempString
);
980 formatter
= NumberFormat::createCurrencyInstance(Locale::getCanadaFrench(), status
);
981 failure(status
, "NumberFormat::createCurrencyInstance", Locale::getCanadaFrench());
983 tempString
= formatter
->format( 5789.9876, tempString
);
985 if (tempString
== expectedCurrency
) {
986 logln ("Bug 4071005 currency test assed.");
988 errln(UnicodeString("Failed:") +
989 " Expected " + expectedCurrency
+
990 " Received " + tempString
);
994 formatter
= NumberFormat::createPercentInstance(Locale::getCanadaFrench(), status
);
995 failure(status
, "NumberFormat::createPercentInstance", Locale::getCanadaFrench());
997 tempString
= formatter
->format (-5789.9876, tempString
);
999 if (tempString
== expectedPercent
) {
1000 logln ("Bug 4071005 percentage test passed.");
1002 errln(UnicodeString("Failed:") +
1003 " Expected " + expectedPercent
+
1004 " Received " + tempString
);
1011 * Data rounding errors for German (Germany) locale
1013 void NumberFormatRegressionTest::Test4071014 (void)
1015 NumberFormat
*formatter
;
1016 UnicodeString tempString
;
1018 String expectedDefault = "-5.789,987";
1019 String expectedCurrency = "5.789,98 DM";
1020 String expectedPercent = "-578.998%";
1022 UnicodeString
expectedDefault("-5.789,988");
1023 UnicodeString
expectedCurrency("5.789,99\\u00A0DM");
1024 UnicodeString
expectedPercent("-578.999\\u00A0%");
1026 expectedCurrency
= expectedCurrency
.unescape();
1027 expectedPercent
= expectedPercent
.unescape();
1029 UErrorCode status
= U_ZERO_ERROR
;
1031 uloc_canonicalize("de_DE_PREEURO", loc
, 256, &status
);
1032 formatter
= NumberFormat::createInstance(Locale(loc
), status
);
1033 if (failure(status
, "NumberFormat::createNumberInstance", loc
)){
1037 tempString
.remove();
1038 tempString
= formatter
->format (-5789.9876, tempString
);
1040 if (tempString
== expectedDefault
) {
1041 logln ("Bug 4071014 default test passed.");
1043 errln(UnicodeString("Failed:") +
1044 " Expected " + expectedDefault
+
1045 " Received " + tempString
);
1048 uloc_canonicalize("de_DE_PREEURO", loc
, 256, &status
);
1049 formatter
= NumberFormat::createCurrencyInstance(Locale(loc
), status
);
1050 failure(status
, "NumberFormat::createCurrencyInstance", loc
);
1051 tempString
.remove();
1052 tempString
= formatter
->format( 5789.9876, tempString
);
1054 if (tempString
== expectedCurrency
) {
1055 logln ("Bug 4071014 currency test assed.");
1057 errln(UnicodeString("Failed:") +
1058 " Expected " + expectedCurrency
+
1059 " Received " + tempString
);
1063 formatter
= NumberFormat::createPercentInstance(Locale::getGermany(), status
);
1064 failure(status
, "NumberFormat::createPercentInstance", Locale::getGermany());
1065 tempString
.remove();
1066 tempString
= formatter
->format (-5789.9876, tempString
);
1068 if (tempString
== expectedPercent
) {
1069 logln ("Bug 4071014 percentage test passed.");
1071 errln(UnicodeString("Failed:") +
1072 " Expected " + expectedPercent
+
1073 " Received " + tempString
);
1079 * Data rounding errors for Italian locale number formats
1081 void NumberFormatRegressionTest::Test4071859 (void)
1083 NumberFormat
*formatter
;
1084 UnicodeString tempString
;
1086 String expectedDefault = "-5.789,987";
1087 String expectedCurrency = "-L.\\u00A05.789,98";
1088 String expectedPercent = "-578.998%";
1090 UnicodeString
expectedDefault("-5.789,988");
1091 UnicodeString
expectedCurrency("-\\u20A4\\u00A05.790", -1, US_INV
);
1092 UnicodeString
expectedPercent("-578.999%");
1093 expectedCurrency
= expectedCurrency
.unescape();
1095 UErrorCode status
= U_ZERO_ERROR
;
1097 uloc_canonicalize("it_IT_PREEURO", loc
, 256, &status
);
1098 formatter
= NumberFormat::createInstance(Locale(loc
), status
);
1099 if (failure(status
, "NumberFormat::createNumberInstance")){
1103 tempString
= formatter
->format (-5789.9876, tempString
);
1105 if (tempString
== expectedDefault
) {
1106 logln ("Bug 4071859 default test passed.");
1108 errln(UnicodeString("Failed:") +
1109 " Expected " + expectedDefault
+
1110 " Received " + tempString
);
1113 uloc_canonicalize("it_IT_PREEURO", loc
, 256, &status
);
1114 formatter
= NumberFormat::createCurrencyInstance(Locale(loc
), status
);
1115 failure(status
, "NumberFormat::createCurrencyInstance");
1116 tempString
.remove();
1117 tempString
= formatter
->format( -5789.9876, tempString
);
1119 if (tempString
== expectedCurrency
) {
1120 logln ("Bug 4071859 currency test assed.");
1122 errln(UnicodeString("Failed:") +
1123 " Expected " + expectedCurrency
+
1124 " Received " + tempString
);
1127 uloc_canonicalize("it_IT_PREEURO", loc
, 256, &status
);
1128 formatter
= NumberFormat::createPercentInstance(Locale(loc
), status
);
1129 failure(status
, "NumberFormat::createPercentInstance");
1130 tempString
.remove();
1131 tempString
= formatter
->format (-5789.9876, tempString
);
1133 if (tempString
== expectedPercent
) {
1134 logln ("Bug 4071859 percentage test passed.");
1136 errln(UnicodeString("Failed:") +
1137 " Expected " + expectedPercent
+
1138 " Received " + tempString
);
1144 * Test rounding for nearest even.
1146 void NumberFormatRegressionTest::Test4093610(void)
1148 UErrorCode status
= U_ZERO_ERROR
;
1149 DecimalFormat
*df
= new DecimalFormat("#0.#", status
);
1150 failure(status
, "new DecimalFormat");
1151 UnicodeString
s("12.4");
1152 roundingTest(df
, 12.35, s
);
1153 roundingTest(df
, 12.45, s
);
1155 roundingTest(df
, 12.452,s
);
1157 roundingTest(df
, 12.55, s
);
1158 roundingTest(df
, 12.65, s
);
1160 roundingTest(df
, 12.652,s
);
1162 roundingTest(df
, 12.75, s
);
1163 roundingTest(df
, 12.752,s
);
1164 roundingTest(df
, 12.85, s
);
1166 roundingTest(df
, 12.852,s
);
1168 roundingTest(df
, 12.95, s
);
1169 roundingTest(df
, 12.952,s
);
1174 void NumberFormatRegressionTest::roundingTest(DecimalFormat
*df
, double x
, UnicodeString
& expected
)
1177 FieldPosition
pos(FieldPosition::DONT_CARE
);
1178 out
= df
->format(x
, out
, pos
);
1179 logln(UnicodeString("") + x
+ " formats with 1 fractional digits to " + out
);
1180 if (out
!= expected
)
1181 errln("FAIL: Expected " + expected
);
1184 * Tests the setMaximumFractionDigits limit.
1186 void NumberFormatRegressionTest::Test4098741(void)
1189 UErrorCode status
= U_ZERO_ERROR
;
1190 NumberFormat
*fmt
= NumberFormat::createPercentInstance(status
);
1191 if (U_FAILURE(status
)) {
1192 dataerrln("Error calling NumberFormat::createPercentInstance");
1197 fmt
->setMaximumFractionDigits(20);
1199 logln(fmt
->format(.001, temp
));
1200 /*} catch (Exception foo) {
1201 errln("Bug 4098471 failed with exception thrown : " + foo.getMessage());
1206 * Tests illegal pattern exception.
1207 * Fix comment : HShih A31 Part1 will not be fixed and javadoc needs to be updated.
1208 * Part2 has been fixed.
1210 void NumberFormatRegressionTest::Test4074454(void)
1213 UErrorCode status
= U_ZERO_ERROR
;
1214 DecimalFormat
*fmt
= new DecimalFormat("#,#00.00;-#.#", status
);
1215 if(U_FAILURE(status
)) {
1216 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1220 failure(status
, "new DecimalFormat");
1221 logln("Inconsistent negative pattern is fine.");
1222 DecimalFormat
*newFmt
= new DecimalFormat("#,#00.00 p''ieces;-#,#00.00 p''ieces", status
);
1223 failure(status
, "new DecimalFormat");
1224 UnicodeString tempString
;
1225 FieldPosition
pos(FieldPosition::DONT_CARE
);
1226 tempString
= newFmt
->format(3456.78, tempString
, pos
);
1227 if (tempString
!= UnicodeString("3,456.78 p'ieces"))
1228 errln("Failed! 3456.78 p'ieces expected, but got : " + tempString
);
1229 /*} catch (Exception foo) {
1230 errln("An exception was thrown for any inconsistent negative pattern.");
1237 * Tests all different comments.
1238 * Response to some comments :
1239 * [1] DecimalFormat.parse API documentation is more than just one line.
1240 * This is not a reproducable doc error in 116 source code.
1241 * [2] See updated javadoc.
1243 * [4] NumberFormat.parse(String, ParsePosition) : If parsing fails,
1244 * a null object will be returned. The unchanged parse position also
1245 * reflects an error.
1246 * NumberFormat.parse(String) : If parsing fails, an ParseException
1248 * See updated javadoc for more details.
1249 * [5] See updated javadoc.
1250 * [6] See updated javadoc.
1251 * [7] This is a correct behavior if the DateFormat object is linient.
1252 * Otherwise, an IllegalArgumentException will be thrown when formatting
1253 * "January 35". See GregorianCalendar class javadoc for more details.
1255 void NumberFormatRegressionTest::Test4099404(void)
1258 UErrorCode status
= U_ZERO_ERROR
;
1259 DecimalFormat
*fmt
= new DecimalFormat(UnicodeString("000.0#0"), status
);
1260 if(! U_FAILURE(status
))
1261 errln(UnicodeString("Bug 4099404 failed applying illegal pattern \"000.0#0\""));
1262 /*} catch (Exception foo) {
1263 logln("Bug 4099404 pattern \"000.0#0\" passed");
1268 fmt
= new DecimalFormat(UnicodeString("0#0.000"), status
);
1269 if( !U_FAILURE(status
))
1270 errln("Bug 4099404 failed applying illegal pattern \"0#0.000\"");
1271 /*} catch (Exception foo) {
1272 logln("Bug 4099404 pattern \"0#0.000\" passed");
1278 * DecimalFormat.applyPattern doesn't set minimum integer digits
1280 void NumberFormatRegressionTest::Test4101481(void)
1282 UErrorCode status
= U_ZERO_ERROR
;
1283 DecimalFormat
*sdf
= new DecimalFormat(UnicodeString("#,##0"), status
);
1284 if(U_FAILURE(status
)) {
1285 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1289 failure(status
, "new DecimalFormat");
1290 if (sdf
->getMinimumIntegerDigits() != 1)
1291 errln("Minimum integer digits : " + sdf
->getMinimumIntegerDigits());
1294 /* @bug 4052223 (API addition request A27)
1295 * Tests ParsePosition.setErrorPosition() and ParsePosition.getErrorPosition().
1297 void NumberFormatRegressionTest::Test4052223(void)
1300 UErrorCode status
= U_ZERO_ERROR
;
1301 DecimalFormat
*fmt
= new DecimalFormat(UnicodeString("#,#00.00"), status
);
1302 if(U_FAILURE(status
)) {
1303 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1307 failure(status
, "new DecimalFormat");
1309 fmt
->parse(UnicodeString("abc3"), num
, status
);
1310 if(! U_FAILURE(status
))
1311 errln(UnicodeString("Bug 4052223 failed : can't parse string \"a\". Got ") /*+ num*/);
1312 /*} catch (ParseException foo) {
1313 logln("Caught expected ParseException : " + foo.getMessage() + " at index : " + foo.getErrorOffset());
1318 * API tests for API addition request A9.
1320 void NumberFormatRegressionTest::Test4061302(void)
1322 UErrorCode status
= U_ZERO_ERROR
;
1323 DecimalFormatSymbols
*fmt
= new DecimalFormatSymbols(status
);
1324 failure(status
, "new DecimalFormatSymbols");
1325 UnicodeString
currency(fmt
->getSymbol(DecimalFormatSymbols::kCurrencySymbol
));
1326 UnicodeString
intlCurrency(fmt
->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
));
1327 UnicodeString
monDecSeparator(fmt
->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
));
1328 if (currency
== UnicodeString("") ||
1329 intlCurrency
== UnicodeString("") ||
1330 monDecSeparator
== UnicodeString(""))
1332 errln("getCurrencySymbols failed, got empty string.");
1334 UnicodeString monDecSeparatorStr
;
1335 monDecSeparatorStr
.append(monDecSeparator
);
1336 logln((UnicodeString
)"Before set ==> Currency : " + currency
+(UnicodeString
)" Intl Currency : " + intlCurrency
+ (UnicodeString
)" Monetary Decimal Separator : " + monDecSeparatorStr
);
1337 fmt
->setSymbol(DecimalFormatSymbols::kCurrencySymbol
, UnicodeString("XYZ"));
1338 fmt
->setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
, UnicodeString("ABC"));
1339 fmt
->setSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
, UnicodeString((UChar
)0x002A/*'*'*/));
1340 currency
= fmt
->getSymbol(DecimalFormatSymbols::kCurrencySymbol
);
1341 intlCurrency
= fmt
->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
);
1342 monDecSeparator
= fmt
->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
);
1343 if (currency
!= UnicodeString("XYZ") ||
1344 intlCurrency
!= UnicodeString("ABC") ||
1345 monDecSeparator
!= UnicodeString((UChar
)0x002A/*'*'*/)) {
1346 errln("setCurrencySymbols failed.");
1348 monDecSeparatorStr
.remove();
1349 monDecSeparatorStr
.append(monDecSeparator
);
1350 logln("After set ==> Currency : " + currency
+ " Intl Currency : " + intlCurrency
+ " Monetary Decimal Separator : " + monDecSeparatorStr
);
1355 * API tests for API addition request A23. FieldPosition.getBeginIndex and
1356 * FieldPosition.getEndIndex.
1358 void NumberFormatRegressionTest::Test4062486(void)
1360 UErrorCode status
= U_ZERO_ERROR
;
1361 DecimalFormat
*fmt
= new DecimalFormat(UnicodeString("#,##0.00"), status
);
1362 failure(status
, "new DecimalFormat");
1363 UnicodeString formatted
;
1364 FieldPosition
field(0);
1365 double num
= 1234.5;
1366 fmt
->format(num
, formatted
, field
);
1367 if (field
.getBeginIndex() != 0 && field
.getEndIndex() != 5)
1368 errln(UnicodeString("Format 1234.5 failed. Begin index: ") /*+ field.getBeginIndex() + " End index: " + field.getEndIndex()*/);
1369 field
.setBeginIndex(7);
1370 field
.setEndIndex(4);
1371 if (field
.getBeginIndex() != 7 && field
.getEndIndex() != 4)
1372 errln("Set begin/end field indexes failed. Begin index: " /*+ field.getBeginIndex() + " End index: " + field.getEndIndex()*/);
1378 * DecimalFormat.parse incorrectly works with a group separator.
1380 void NumberFormatRegressionTest::Test4108738(void)
1382 UErrorCode status
= U_ZERO_ERROR
;
1383 DecimalFormatSymbols
*syms
= new DecimalFormatSymbols(Locale::getUS(), status
);
1384 failure(status
, "new DecimalFormatSymbols");
1385 DecimalFormat
*df
= new DecimalFormat("#,##0.###", syms
, status
);
1386 if(U_FAILURE(status
)) {
1387 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1391 failure(status
, "new DecimalFormat");
1392 UnicodeString
text("1.222,111");
1394 ParsePosition
pp(0);
1395 df
->parse(text
, num
, pp
);
1397 // {sfb} how to do this (again) ?
1398 // shouldn't just be another round-trip test, should it?
1400 FieldPosition
pos(FieldPosition::DONT_CARE
);
1401 temp
= df
->format(num
.getDouble(), temp
, pos
);
1402 //if (!num.toString().equals("1.222"))
1403 if (temp
!= UnicodeString("1.222"))
1404 //errln("\"" + text + "\" is parsed as " + num);
1405 errln("\"" + text
+ "\" is parsed as " + temp
);
1406 text
= UnicodeString("1.222x111");
1407 pp
= ParsePosition(0);
1408 df
->parse(text
, num
, pp
);
1410 temp
= df
->format(num
.getDouble(), temp
, pos
);
1411 //if (!num.toString().equals("1.222"))
1412 if (temp
!= UnicodeString("1.222"))
1413 errln("\"" + text
+ "\" is parsed as " + temp
);
1419 * DecimalFormat.format() incorrectly formats negative doubles.
1421 void NumberFormatRegressionTest::Test4106658(void)
1423 UErrorCode status
= U_ZERO_ERROR
;
1424 DecimalFormat
*df
= new DecimalFormat(status
); // Corrected; see 4147706
1425 if(U_FAILURE(status
)) {
1426 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1430 failure(status
, "new DecimalFormat");
1431 volatile double d1
= 0.0; // volatile to prevent code optimization
1432 double d2
= -0.0001;
1433 UnicodeString buffer
;
1435 FieldPosition
pos(FieldPosition::DONT_CARE
);
1438 d1
= 0.0 * -1.0; // old HPUX compiler ignores volatile keyword
1440 d1
*= -1.0; // Some compilers have a problem with defining -0.0
1442 logln("pattern: \"" + df
->toPattern(temp
) + "\"");
1443 df
->format(d1
, buffer
, pos
);
1444 if (buffer
!= UnicodeString("-0")) // Corrected; see 4147706
1445 errln(UnicodeString("") + d1
+ " is formatted as " + buffer
);
1447 df
->format(d2
, buffer
, pos
);
1448 if (buffer
!= UnicodeString("-0")) // Corrected; see 4147706
1449 errln(UnicodeString("") + d2
+ " is formatted as " + buffer
);
1455 * DecimalFormat.parse returns 0 if string parameter is incorrect.
1457 void NumberFormatRegressionTest::Test4106662(void)
1459 UErrorCode status
= U_ZERO_ERROR
;
1460 DecimalFormat
*df
= new DecimalFormat(status
);
1461 if(U_FAILURE(status
)) {
1462 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1466 failure(status
, "new DecimalFormat");
1467 UnicodeString
text("x");
1468 ParsePosition
pos1(0), pos2(0);
1471 logln("pattern: \"" + df
->toPattern(temp
) + "\"");
1473 df
->parse(text
, num
, pos1
);
1474 if (pos1
== ParsePosition(0)/*num != null*/) {
1475 errln(UnicodeString("Test Failed: \"") + text
+ "\" is parsed as " /*+ num*/);
1478 df
= new DecimalFormat(UnicodeString("$###.00"), status
);
1479 failure(status
, "new DecimalFormat");
1480 df
->parse(UnicodeString("$"), num
, pos2
);
1481 if (pos2
== ParsePosition(0) /*num != null*/){
1482 errln(UnicodeString("Test Failed: \"$\" is parsed as ") /*+ num*/);
1488 /* @bug 4114639 (duplicate of 4106662)
1489 * NumberFormat.parse doesn't return null
1491 void NumberFormatRegressionTest::Test4114639(void)
1493 UErrorCode status
= U_ZERO_ERROR
;
1494 NumberFormat
*format
= NumberFormat::createInstance(status
);
1495 if(U_FAILURE(status
)) {
1496 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1500 failure(status
, "NumberFormat::createInstance");
1501 UnicodeString
text("time 10:x");
1502 ParsePosition
pos(8);
1504 format
->parse(text
, result
, pos
);
1505 if (/*result != null*/pos
.getErrorIndex() != 8)
1506 errln(UnicodeString("Should return null but got : ") /*+ result*/); // Should be null; it isn't
1512 * TODO: this test does not work because we need to use a 64 bit number and a
1513 * a double only MAY only have 52 bits of precision.
1514 * DecimalFormat.format(long n) fails if n * multiplier > MAX_LONG.
1516 void NumberFormatRegressionTest::Test4106664(void)
1518 UErrorCode status
= U_ZERO_ERROR
;
1519 DecimalFormat
*df
= new DecimalFormat(status
);
1520 if(U_FAILURE(status
)) {
1521 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1525 failure(status
, "new DecimalFormat");
1526 // {sfb} long in java is 64 bits
1527 /*long*/double n
= 1234567890123456.0;
1528 /*int*/int32_t m
= 12345678;
1529 // {sfb} will this work?
1530 //BigInteger bigN = BigInteger.valueOf(n);
1531 //bigN = bigN.multiply(BigInteger.valueOf(m));
1532 double bigN
= n
* m
;
1533 df
->setMultiplier(m
);
1534 df
->setGroupingUsed(FALSE
);
1536 FieldPosition
pos(FieldPosition::DONT_CARE
);
1537 logln("formated: " +
1538 df
->format(n
, temp
, pos
));
1541 sprintf(buf
, "%g", bigN
);
1542 //logln("expected: " + bigN.toString());
1543 logln(UnicodeString("expected: ") + buf
);
1547 /* @bug 4106667 (duplicate of 4106658)
1548 * DecimalFormat.format incorrectly formats -0.0.
1550 void NumberFormatRegressionTest::Test4106667(void)
1552 UErrorCode status
= U_ZERO_ERROR
;
1553 DecimalFormat
*df
= new DecimalFormat(status
);
1554 if(U_FAILURE(status
)) {
1555 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1559 failure(status
, "new DecimalFormat");
1560 UChar foo
[] = { 0x002B };
1561 UnicodeString
bar(foo
, 1, 1);
1562 volatile double d
= 0.0; // volatile to prevent code optimization
1564 UnicodeString buffer
;
1565 FieldPosition
pos(FieldPosition::DONT_CARE
);
1567 logln("pattern: \"" + df
->toPattern(temp
) + "\"");
1569 d
= 0.0 * -1.0; // old HPUX compiler ignores volatile keyword
1571 d
*= -1.0; // Some compilers have a problem with defining -0.0
1573 df
->setPositivePrefix(/*"+"*/bar
);
1574 df
->format(d
, buffer
, pos
);
1575 if (buffer
!= UnicodeString("-0")) // Corrected; see 4147706
1576 errln(/*d + */UnicodeString(" is formatted as ") + buffer
);
1582 * DecimalFormat.setMaximumIntegerDigits() works incorrectly.
1585 # define MAX_INT_DIGITS 70
1587 # define MAX_INT_DIGITS 128
1590 void NumberFormatRegressionTest::Test4110936(void)
1592 UErrorCode status
= U_ZERO_ERROR
;
1593 NumberFormat
*nf
= NumberFormat::createInstance(status
);
1594 if(U_FAILURE(status
)) {
1595 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1599 failure(status
, "NumberFormat::createInstance");
1600 nf
->setMaximumIntegerDigits(MAX_INT_DIGITS
);
1601 logln("setMaximumIntegerDigits(MAX_INT_DIGITS)");
1602 if (nf
->getMaximumIntegerDigits() != MAX_INT_DIGITS
)
1603 errln("getMaximumIntegerDigits() returns " +
1604 nf
->getMaximumIntegerDigits());
1610 * Locale data should use generic currency symbol
1612 * 1) Make sure that all currency formats use the generic currency symbol.
1613 * 2) Make sure we get the same results using the generic symbol or a
1616 void NumberFormatRegressionTest::Test4122840(void)
1619 const Locale
*locales
= Locale::getAvailableLocales(count
);
1621 for (int i
= 0; i
< count
; i
++) {
1622 UErrorCode status
= U_ZERO_ERROR
;
1623 ResourceBundle
*rb
= new ResourceBundle(
1624 NULL
/*"java.text.resources.LocaleElements"*/,
1625 locales
[i
], status
);
1626 failure(status
, "new ResourceBundle");
1627 ResourceBundle numPat
= rb
->get("NumberPatterns", status
);
1628 failure(status
, "new ResourceBundle(NumberPatterns)");
1630 // Get the currency pattern for this locale. We have to fish it
1631 // out of the ResourceBundle directly, since DecimalFormat.toPattern
1632 // will return the localized symbol, not \00a4
1634 UnicodeString pattern
= numPat
.getStringEx(1, status
);
1635 failure(status
, "rb->getStringArray");
1637 UChar fo
[] = { 0x00A4 };
1638 UnicodeString
foo(fo
, 1, 1);
1640 //if (pattern.indexOf("\u00A4") == -1 ) {
1641 if (pattern
.indexOf(foo
) == -1 ) {
1642 errln(UnicodeString("Currency format for ") + UnicodeString(locales
[i
].getName()) +
1643 " does not contain generic currency symbol:" +
1647 // Create a DecimalFormat using the pattern we got and format a number
1648 DecimalFormatSymbols
*symbols
= new DecimalFormatSymbols(locales
[i
], status
);
1649 failure(status
, "new DecimalFormatSymbols");
1650 DecimalFormat
*fmt1
= new DecimalFormat(pattern
, *symbols
, status
);
1651 failure(status
, "new DecimalFormat");
1653 UnicodeString result1
;
1654 FieldPosition
pos(FieldPosition::DONT_CARE
);
1655 result1
= fmt1
->format(1.111, result1
, pos
);
1658 // Now substitute in the locale's currency symbol and create another
1659 // pattern. We have to skip locales where the currency symbol
1660 // contains decimal separators, because that confuses things
1662 UChar ba
[] = { 0x002E/*'.'*/ };
1663 UnicodeString
bar(ba
, 1, 1);
1665 if (symbols
->getSymbol(DecimalFormatSymbols::kCurrencySymbol
).indexOf(bar
) == -1) {
1666 // {sfb} Also, switch the decimal separator to the monetary decimal
1667 // separator to mimic the behavior of a currency format
1668 symbols
->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
,
1669 symbols
->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
));
1671 UnicodeString
buf(pattern
);
1672 for (int j
= 0; j
< buf
.length(); j
++) {
1673 if (buf
[j
] == 0x00a4 ) {
1674 if(buf
[j
+ 1] == 0x00a4) {
1675 // {sfb} added to support double currency marker (intl currency sign)
1676 buf
.replace(j
, /*j+*/2, symbols
->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
));
1677 j
+= symbols
->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
).length();
1680 buf
.replace(j
, /*j+*/1, symbols
->getSymbol(DecimalFormatSymbols::kCurrencySymbol
));
1681 j
+= symbols
->getSymbol(DecimalFormatSymbols::kCurrencySymbol
).length() - 1;
1686 DecimalFormat
*fmt2
= new DecimalFormat(buf
, *symbols
, status
);
1687 failure(status
, "new DecimalFormat");
1689 // Get the currency (if there is one) so we can set the rounding and fraction
1690 const UChar
*currency
= fmt1
->getCurrency();
1691 if (*currency
!= 0) {
1692 double rounding
= ucurr_getRoundingIncrement(currency
, &status
);
1693 int32_t frac
= ucurr_getDefaultFractionDigits(currency
, &status
);
1694 if (U_SUCCESS(status
)) {
1695 fmt2
->setRoundingIncrement(rounding
);
1696 fmt2
->setMinimumFractionDigits(frac
);
1697 fmt2
->setMaximumFractionDigits(frac
);
1700 failure(status
, "Fetching currency rounding/fractions");
1704 UnicodeString result2
;
1705 fmt2
->format(1.111, result2
, pos
);
1707 if (result1
!= result2
) {
1708 errln("Results for " + (UnicodeString
)(locales
[i
].getName()) + " differ: " +
1709 result1
+ " vs " + result2
);
1722 * DecimalFormat.format() delivers wrong string.
1724 void NumberFormatRegressionTest::Test4125885(void)
1726 UErrorCode status
= U_ZERO_ERROR
;
1727 double rate
= 12.34;
1728 DecimalFormat
*formatDec
= new DecimalFormat ("000.00", status
);
1729 if(U_FAILURE(status
)) {
1730 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1734 failure(status
, "new DecimalFormat");
1736 logln("toPattern: " + formatDec
->toPattern(temp
));
1737 UnicodeString rateString
;
1738 FieldPosition
pos(FieldPosition::DONT_CARE
);
1739 rateString
= formatDec
->format(rate
, rateString
, pos
);
1740 if (rateString
!= UnicodeString("012.34"))
1741 errln("result : " + rateString
+ " expected : 012.34");
1743 delete formatDec
;// = null;
1744 formatDec
= new DecimalFormat ("+000.00%;-000.00%", status
);
1745 failure(status
, "new DecimalFormat");
1746 logln("toPattern: " + formatDec
->toPattern(temp
));
1747 rateString
.remove();
1748 rateString
= formatDec
->format(rate
, rateString
, pos
);
1749 if (rateString
!= UnicodeString("+012.34%"))
1750 errln("result : " + rateString
+ " expected : +012.34%");
1757 * DecimalFormat produces extra zeros when formatting numbers.
1759 void NumberFormatRegressionTest::Test4134034(void)
1761 UErrorCode status
= U_ZERO_ERROR
;
1762 DecimalFormat
*nf
= new DecimalFormat("##,###,###.00", status
);
1763 failure(status
, "new DecimalFormat");
1766 FieldPosition
pos(FieldPosition::DONT_CARE
);
1767 f
= nf
->format(9.02, f
, pos
);
1768 if (f
== UnicodeString("9.02"))
1771 errln("9.02 -> " + f
+ "; want 9.02");
1774 f
= nf
->format((int32_t)0, f
, pos
);
1775 if (f
== UnicodeString(".00"))
1778 errln("0 -> " + f
+ "; want .00");
1785 * CANNOT REPRODUCE - This bug could not be reproduced. It may be
1786 * a duplicate of 4134034.
1788 * JDK 1.1.6 Bug, did NOT occur in 1.1.5
1789 * Possibly related to bug 4125885.
1791 * This class demonstrates a regression in version 1.1.6
1792 * of DecimalFormat class.
1795 * Value 1.2 Format #.00 Result '01.20' !!!wrong
1796 * Value 1.2 Format 0.00 Result '001.20' !!!wrong
1797 * Value 1.2 Format 00.00 Result '0001.20' !!!wrong
1798 * Value 1.2 Format #0.0# Result '1.2'
1799 * Value 1.2 Format #0.00 Result '001.20' !!!wrong
1802 * Value 1.2 Format #.00 Result '1.20'
1803 * Value 1.2 Format 0.00 Result '1.20'
1804 * Value 1.2 Format 00.00 Result '01.20'
1805 * Value 1.2 Format #0.0# Result '1.2'
1806 * Value 1.2 Format #0.00 Result '1.20'
1808 void NumberFormatRegressionTest::Test4134300(void) {
1809 UnicodeString DATA
[] = {
1810 // Pattern Expected string
1811 UnicodeString("#.00"), UnicodeString("1.20"),
1812 UnicodeString("0.00"), UnicodeString("1.20"),
1813 UnicodeString("00.00"), UnicodeString("01.20"),
1814 UnicodeString("#0.0#"), UnicodeString("1.2"),
1815 UnicodeString("#0.00"), UnicodeString("1.20")
1818 for (int i
=0; i
< 10; i
+=2) {
1819 UnicodeString result
;
1820 UErrorCode status
= U_ZERO_ERROR
;
1821 DecimalFormat
*df
= new DecimalFormat(DATA
[i
], status
);
1822 failure(status
, "new DecimalFormat");
1823 FieldPosition
pos(FieldPosition::DONT_CARE
);
1824 result
= df
->format(1.2, result
, pos
);
1825 if (result
!= DATA
[i
+1]) {
1826 errln("Fail: 1.2 x " + DATA
[i
] + " = " + result
+
1827 "; want " + DATA
[i
+1]);
1830 logln("Ok: 1.2 x " + DATA
[i
] + " = " + result
);
1839 * Empty pattern produces double negative prefix.
1841 void NumberFormatRegressionTest::Test4140009(void)
1843 UErrorCode status
= U_ZERO_ERROR
;
1844 DecimalFormatSymbols
*syms
= new DecimalFormatSymbols(Locale::getEnglish(), status
);
1845 failure(status
, "new DecimalFormatSymbols");
1846 DecimalFormat
*f
= new DecimalFormat(UnicodeString(""), syms
, status
);
1847 failure(status
, "new DecimalFormat");
1849 FieldPosition
pos(FieldPosition::DONT_CARE
);
1850 s
= f
->format(123.456, s
, pos
);
1851 if (s
!= UnicodeString("123.456"))
1852 errln("Fail: Format empty pattern x 123.456 => " + s
);
1854 s
= f
->format(-123.456, s
, pos
);
1855 if (s
!= UnicodeString("-123.456"))
1856 errln("Fail: Format empty pattern x -123.456 => " + s
);
1862 * BigDecimal numbers get their fractions truncated by NumberFormat.
1864 // {sfb} not pertinent in C++ ??
1865 void NumberFormatRegressionTest::Test4141750(void) {
1867 UnicodeString str("12345.67");
1868 BigDecimal bd = new BigDecimal(str);
1869 String sd = NumberFormat.getInstance(Locale.US).format(bd);
1870 if (!sd.endsWith("67")) errln("Fail: " + str + " x format -> " + sd);
1872 catch (Exception e) {
1873 errln(e.toString());
1874 e.printStackTrace();
1880 * DecimalFormat toPattern() doesn't quote special characters or handle
1883 void NumberFormatRegressionTest::Test4145457() {
1885 UErrorCode status
= U_ZERO_ERROR
;
1886 NumberFormat
*nff
= NumberFormat::createInstance(status
);
1887 if (failure(status
, "NumberFormat::createInstance")){
1891 if(nff
->getDynamicClassID() != DecimalFormat::getStaticClassID()) {
1892 errln("DecimalFormat needed to continue");
1896 DecimalFormat
*nf
= (DecimalFormat
*)nff
;
1897 DecimalFormatSymbols
*sym
= (DecimalFormatSymbols
*) nf
->getDecimalFormatSymbols();
1898 sym
->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
, (UChar
)/*'\''*/0x0027);
1899 nf
->setDecimalFormatSymbols(*sym
);
1900 double pi
= 3.14159;
1902 UnicodeString PATS
[] = {
1903 UnicodeString("#.00 'num''ber'"), UnicodeString("''#.00''")
1906 for (int32_t i
=0; i
<2; ++i
) {
1907 nf
->applyPattern(PATS
[i
], status
);
1908 failure(status
, "nf->applyPattern");
1910 FieldPosition
pos(FieldPosition::DONT_CARE
);
1911 out
= nf
->format(pi
, out
, pos
);
1913 pat
= nf
->toPattern(pat
);
1915 ParsePosition
pp(0);
1916 nf
->parse(out
, num
, pp
);
1917 double val
= num
.getDouble();
1919 nf
->applyPattern(pat
, status
);
1920 failure(status
, "nf->applyPattern");
1922 out2
= nf
->format(pi
, out2
, pos
);
1924 pat2
= nf
->toPattern(pat2
);
1925 nf
->parse(out2
, num
, pp
);
1926 double val2
= num
.getDouble();
1929 errln("Fail with \"" + PATS
[i
] + "\": Patterns should concur, \"" +
1930 pat
+ "\" vs. \"" + pat2
+ "\"");
1932 logln("Ok \"" + PATS
[i
] + "\" toPattern() -> \"" + pat
+ '"');
1934 if (val
== val2
&& out
== out2
) {
1935 logln(UnicodeString("Ok ") + pi
+ " x \"" + PATS
[i
] + "\" -> \"" +
1936 out
+ "\" -> " + val
+ " -> \"" +
1937 out2
+ "\" -> " + val2
);
1940 errln(UnicodeString("Fail ") + pi
+ " x \"" + PATS
[i
] + "\" -> \"" +
1941 out
+ "\" -> " + val
+ " -> \"" +
1942 out2
+ "\" -> " + val2
);
1946 catch (ParseException e) {
1947 errln("Fail: " + e);
1948 e.printStackTrace();
1956 * DecimalFormat.applyPattern() sets minimum integer digits incorrectly.
1958 * This bug is a duplicate of 4139344, which is a duplicate of 4134300
1960 void NumberFormatRegressionTest::Test4147295(void)
1962 UErrorCode status
= U_ZERO_ERROR
;
1963 DecimalFormat
*sdf
= new DecimalFormat(status
);
1964 UnicodeString
pattern("#,###");
1965 logln("Applying pattern \"" + pattern
+ "\"");
1966 sdf
->applyPattern(pattern
, status
);
1967 failure(status
, "sdf->applyPattern");
1968 int minIntDig
= sdf
->getMinimumIntegerDigits();
1969 if (minIntDig
!= 0) {
1970 errln("Test failed");
1971 errln(" Minimum integer digits : " + minIntDig
);
1973 errln(" new pattern: " + sdf
->toPattern(temp
));
1975 logln("Test passed");
1976 logln(" Minimum integer digits : " + minIntDig
);
1983 * DecimalFormat formats -0.0 as +0.0
1984 * See also older related bug 4106658, 4106667
1986 void NumberFormatRegressionTest::Test4147706(void)
1988 UErrorCode status
= U_ZERO_ERROR
;
1989 DecimalFormat
*df
= new DecimalFormat("#,##0.0##", status
);
1990 failure(status
, "new DecimalFormat");
1991 DecimalFormatSymbols
*syms
= new DecimalFormatSymbols(Locale::getEnglish(), status
);
1992 failure(status
, "new DecimalFormatSymbols");
1994 UnicodeString f2
, temp
;
1995 FieldPosition
pos(FieldPosition::DONT_CARE
);
1996 volatile double d1
= 0.0; // volatile to prevent code optimization
1997 double d2
= -0.0001;
2000 d1
= 0.0 * -1.0; // old HPUX compiler ignores volatile keyword
2002 d1
*= -1.0; // Some compilers have a problem with defining -0.0
2004 df
->adoptDecimalFormatSymbols(syms
);
2005 f1
= df
->format(d1
, f1
, pos
);
2006 f2
= df
->format(d2
, f2
, pos
);
2007 if (f1
!= UnicodeString("-0.0")) {
2008 errln(UnicodeString("") + d1
+ UnicodeString(" x \"") + df
->toPattern(temp
) + "\" is formatted as \"" + f1
+ '"');
2010 if (f2
!= UnicodeString("-0.0")) {
2011 errln(UnicodeString("") + d2
+ UnicodeString(" x \"") + df
->toPattern(temp
) + "\" is formatted as \"" + f2
+ '"');
2018 // Not applicable, since no serialization in C++
2019 /*class myformat implements Serializable
2021 DateFormat _dateFormat = DateFormat.getDateInstance();
2025 GregorianCalendar calendar = new GregorianCalendar();
2026 Date t = calendar.getTime();
2027 String nowStr = _dateFormat.format(t);
2034 * NumberFormat cannot format Double.MAX_VALUE
2036 // TODO: make this test actually test something
2038 NumberFormatRegressionTest::Test4162198(void)
2040 // for some reason, DBL_MAX will not round trip. (bug in sprintf/atof)
2041 double dbl
= INT32_MAX
* 1000.0;
2042 UErrorCode status
= U_ZERO_ERROR
;
2043 NumberFormat
*f
= NumberFormat::createInstance(status
);
2044 if(U_FAILURE(status
)) {
2045 errln("Couldn't create number format");
2048 f
->setMaximumFractionDigits(INT32_MAX
);
2049 f
->setMaximumIntegerDigits(INT32_MAX
);
2052 logln(UnicodeString("The number ") + dbl
+ " formatted to " + s
);
2055 f
->parse(s
, n
, status
);
2056 if(U_FAILURE(status
))
2057 errln("Couldn't parse!");
2058 //} catch (java.text.ParseException e) {
2059 // errln("Caught a ParseException:");
2060 // e.printStackTrace();
2063 //logln("The string " + s + " parsed as " + n);
2065 // {dlf} The old code assumes n is a double, but it isn't any more...
2066 // Formattable apparently does not and never did interconvert... too bad.
2067 //if(n.getDouble() != dbl) {
2068 // errln("Round trip failure");
2070 if (n
.getInt64() != dbl
) {
2071 errln("Round trip failure");
2079 * NumberFormat does not parse negative zero.
2082 NumberFormatRegressionTest::Test4162852(void)
2084 UErrorCode status
= U_ZERO_ERROR
;
2085 for(int32_t i
=0; i
< 2; ++i
) {
2086 NumberFormat
*f
= (i
== 0) ? NumberFormat::createInstance(status
)
2087 : NumberFormat::createPercentInstance(status
);
2088 if(U_FAILURE(status
)) {
2089 errln("Couldn't create number format");
2097 f
->parse(s
, n
, status
);
2098 if(U_FAILURE(status
))
2099 errln("Couldn't parse!");
2100 double e
= n
.getDouble();
2101 logln(UnicodeString("") +
2103 '"' + s
+ '"' + " -> " + e
);
2104 #if (defined(OS390) && !defined(IEEE_754)) || defined(OS400)
2107 if (e
!= 0.0 || 1.0/e
> 0.0) {
2109 logln("Failed to parse negative zero");
2115 static double _u_abs(double a
) { return a
<0?-a
:a
; }
2118 * May 17 1999 sync up - liu
2120 * NumberFormat truncates data
2122 void NumberFormatRegressionTest::Test4167494(void) {
2123 UErrorCode status
= U_ZERO_ERROR
;
2124 NumberFormat
*fmt
= NumberFormat::createInstance(Locale::getUS(), status
);
2125 if (failure(status
, "NumberFormat::createInstance")){
2130 double a
= DBL_MAX
* 0.99; // DBL_MAX itself overflows to +Inf
2134 fmt
->parse(s
, num
, status
);
2135 failure(status
, "Parse");
2136 if (num
.getType() == Formattable::kDouble
&&
2137 _u_abs(num
.getDouble() - a
) / a
< 0.01) { // RT within 1%
2138 logln(UnicodeString("") + a
+ " -> \"" + s
+ "\" -> " +
2139 toString(num
) + " ok");
2141 errln(UnicodeString("") + a
+ " -> \"" + s
+ "\" -> " +
2142 toString(num
) + " FAIL");
2145 // We don't test Double.MIN_VALUE because the locale data for the US
2146 // currently doesn't specify enough digits to display Double.MIN_VALUE.
2147 // This is correct for now; however, we leave this here as a reminder
2148 // in case we want to address this later.
2154 * May 17 1999 sync up - liu
2156 * DecimalFormat.parse() fails when ParseIntegerOnly set to true
2158 void NumberFormatRegressionTest::Test4170798(void) {
2159 UErrorCode status
= U_ZERO_ERROR
;
2160 NumberFormat
*nf
= NumberFormat::createInstance(Locale::getUS(), status
);
2161 if (failure(status
, "NumberFormat::createInstance")){
2165 if(nf
->getDynamicClassID() != DecimalFormat::getStaticClassID()) {
2166 errln("DecimalFormat needed to continue");
2169 DecimalFormat
*df
= (DecimalFormat
*) nf
;
2170 df
->setParseIntegerOnly(TRUE
);
2172 ParsePosition
pos(0);
2173 df
->parse("-0.0", n
, pos
);
2174 if (n
.getType() != Formattable::kLong
2175 || n
.getLong() != 0) {
2176 errln(UnicodeString("FAIL: parse(\"-0.0\") returns ") + toString(n
));
2182 * May 17 1999 sync up - liu
2183 * toPattern only puts the first grouping separator in.
2185 void NumberFormatRegressionTest::Test4176114(void) {
2186 const char* DATA
[] = {
2188 "000", "#000", // No grouping
2189 "#000", "#000", // No grouping
2193 "00,000", "#00,000",
2194 "000,000", "#,000,000",
2195 "0,000,000,000,000.0000", "#0,000,000,000,000.0000", // Reported
2197 int DATA_length
= (int)(sizeof(DATA
) / sizeof(DATA
[0]));
2198 UErrorCode status
= U_ZERO_ERROR
;
2200 for (int i
=0; i
<DATA_length
; i
+=2) {
2201 DecimalFormat
df(DATA
[i
], status
);
2202 failure(status
, "DecimalFormat constructor");
2204 UnicodeString
exp(DATA
[i
+1]);
2206 errln(UnicodeString("FAIL: ") + DATA
[i
] + " -> " +
2207 s
+ ", want " + exp
);
2213 * May 17 1999 sync up - liu
2215 * DecimalFormat is incorrectly rounding numbers like 1.2501 to 1.2
2217 void NumberFormatRegressionTest::Test4179818(void) {
2218 const char* DATA
[] = {
2219 // Input Pattern Expected output
2220 "1.2511", "#.#", "1.3",
2221 "1.2501", "#.#", "1.3",
2224 int DATA_length
= (int)(sizeof(DATA
) / sizeof(DATA
[0]));
2230 UErrorCode status
= U_ZERO_ERROR
;
2231 DecimalFormatSymbols
sym(Locale::getUS(), status
);
2232 failure(status
, "Construct DecimalFormatSymbols");
2233 DecimalFormat
fmt("#", sym
, status
);
2234 failure(status
, "Construct DecimalFormat");
2235 for (int i
=0; i
<DATA_length
; i
+=3) {
2236 double in
= DOUBLE
[i
/3];
2237 UnicodeString
pat(DATA
[i
+1]);
2238 UnicodeString
exp(DATA
[i
+2]);
2239 fmt
.applyPattern(pat
, status
);
2240 failure(status
, "applyPattern");
2243 fmt
.format(in
, out
, pos
);
2245 logln(UnicodeString("Ok: ") + in
+ " x " + pat
+ " = " + out
);
2247 errln(UnicodeString("FAIL: ") + in
+ " x " + pat
+ " = " + out
+
2248 ", expected " + exp
);
2254 * May 17 1999 sync up - liu
2255 * Some DecimalFormatSymbols changes are not picked up by DecimalFormat.
2256 * This includes the minus sign, currency symbol, international currency
2257 * symbol, percent, and permille. This is filed as bugs 4212072 and
2260 void NumberFormatRegressionTest::Test4212072(void) {
2261 UErrorCode status
= U_ZERO_ERROR
;
2262 DecimalFormatSymbols
sym(Locale::getUS(), status
);
2264 failure(status
, "DecimalFormatSymbols ct", Locale::getUS());
2265 DecimalFormat
fmt(UnicodeString("#"), sym
, status
);
2266 failure(status
, "DecimalFormat ct", Locale::getUS());
2271 sym
.setSymbol(DecimalFormatSymbols::kMinusSignSymbol
, (UChar
)0x5e);
2272 fmt
.setDecimalFormatSymbols(sym
);
2274 if (fmt
.format((int32_t)-1, s
, pos
) != UNICODE_STRING("^1", 2)) {
2275 errln(UnicodeString("FAIL: -1 x (minus=^) -> ") + s
+
2279 if (fmt
.getNegativePrefix(s
) != UnicodeString((UChar
)0x5e)) {
2280 errln(UnicodeString("FAIL: (minus=^).getNegativePrefix -> ") +
2283 sym
.setSymbol(DecimalFormatSymbols::kMinusSignSymbol
, (UChar
)0x2d);
2285 fmt
.applyPattern(UnicodeString("#%"), status
);
2286 failure(status
, "applyPattern percent");
2287 sym
.setSymbol(DecimalFormatSymbols::kPercentSymbol
, (UChar
)0x5e);
2288 fmt
.setDecimalFormatSymbols(sym
);
2290 if (fmt
.format(0.25, s
, pos
) != UNICODE_STRING("25^", 3)) {
2291 errln(UnicodeString("FAIL: 0.25 x (percent=^) -> ") + s
+
2295 if (fmt
.getPositiveSuffix(s
) != UnicodeString((UChar
)0x5e)) {
2296 errln(UnicodeString("FAIL: (percent=^).getPositiveSuffix -> ") +
2299 sym
.setSymbol(DecimalFormatSymbols::kPercentSymbol
, (UChar
)0x25);
2301 fmt
.applyPattern(str("#\\u2030"), status
);
2302 failure(status
, "applyPattern permill");
2303 sym
.setSymbol(DecimalFormatSymbols::kPerMillSymbol
, (UChar
)0x5e);
2304 fmt
.setDecimalFormatSymbols(sym
);
2306 if (fmt
.format(0.25, s
, pos
) != UNICODE_STRING("250^", 4)) {
2307 errln(UnicodeString("FAIL: 0.25 x (permill=^) -> ") + s
+
2311 if (fmt
.getPositiveSuffix(s
) != UnicodeString((UChar
)0x5e)) {
2312 errln(UnicodeString("FAIL: (permill=^).getPositiveSuffix -> ") +
2315 sym
.setSymbol(DecimalFormatSymbols::kPerMillSymbol
, (UChar
)0x2030);
2317 fmt
.applyPattern(str("\\u00A4#.00"), status
);
2318 failure(status
, "applyPattern currency");
2319 sym
.setSymbol(DecimalFormatSymbols::kCurrencySymbol
, "usd");
2320 fmt
.setDecimalFormatSymbols(sym
);
2322 if (fmt
.format(12.5, s
, pos
) != UnicodeString("usd12.50")) {
2323 errln(UnicodeString("FAIL: 12.5 x (currency=usd) -> ") + s
+
2327 if (fmt
.getPositivePrefix(s
) != UnicodeString("usd")) {
2328 errln(UnicodeString("FAIL: (currency=usd).getPositivePrefix -> ") +
2331 sym
.setSymbol(DecimalFormatSymbols::kCurrencySymbol
, "$");
2333 fmt
.applyPattern(str("\\u00A4\\u00A4#.00"), status
);
2334 failure(status
, "applyPattern intl currency");
2335 sym
.setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
, "DOL");
2336 fmt
.setDecimalFormatSymbols(sym
);
2338 if (fmt
.format(12.5, s
, pos
) != UnicodeString("DOL12.50")) {
2339 errln(UnicodeString("FAIL: 12.5 x (intlcurrency=DOL) -> ") + s
+
2343 if (fmt
.getPositivePrefix(s
) != UnicodeString("DOL")) {
2344 errln(UnicodeString("FAIL: (intlcurrency=DOL).getPositivePrefix -> ") +
2347 sym
.setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
, "USD");
2349 // Since the pattern logic has changed, make sure that patterns round
2350 // trip properly. Test stream in/out integrity too.
2352 const Locale
* avail
= NumberFormat::getAvailableLocales(n
);
2353 static const char* type
[] = {
2358 for (int i
=0; i
<n
; ++i
) {
2359 for (int j
=0; j
<3; ++j
) {
2360 status
= U_ZERO_ERROR
;
2364 nf
= NumberFormat::createInstance(avail
[i
], status
);
2365 failure(status
, "createInstance", avail
[i
]);
2368 nf
= NumberFormat::createCurrencyInstance(avail
[i
], status
);
2369 failure(status
, "createCurrencyInstance", avail
[i
]);
2372 nf
= NumberFormat::createPercentInstance(avail
[i
], status
);
2373 failure(status
, "createPercentInstance", avail
[i
]);
2376 if (U_FAILURE(status
)) {
2379 DecimalFormat
*df
= (DecimalFormat
*) nf
;
2381 // Test toPattern/applyPattern round trip
2384 DecimalFormatSymbols
symb(avail
[i
], status
);
2385 failure(status
, "Construct DecimalFormatSymbols", avail
[i
]);
2386 DecimalFormat
f2(pat
, symb
, status
);
2388 UnicodeString("Construct DecimalFormat(") + pat
+ ")")) {
2393 errln(UnicodeString("FAIL: ") + type
[j
] + avail
[i
].getDisplayName(l
) +
2395 "\" -> \"" + f2
.toPattern(p
) + "\"");
2398 // Test toLocalizedPattern/applyLocalizedPattern round trip
2399 df
->toLocalizedPattern(pat
);
2400 f2
.applyLocalizedPattern(pat
, status
);
2402 UnicodeString("applyLocalizedPattern(") + pat
+ ")", avail
[i
]);
2403 if (U_FAILURE(status
)) {
2407 // Make sure we set the currency attributes appropriately
2408 if (j
== 1) { // Currency format
2409 f2
.setCurrency(f2
.getCurrency(), status
);
2412 UnicodeString("setCurrency() for (") + pat
+ ")", avail
[i
]);
2413 if (U_FAILURE(status
)) {
2419 errln(UnicodeString("FAIL: ") + type
[j
] + avail
[i
].getDisplayName(l
) +
2420 " -> localized \"" + pat
+
2421 "\" -> \"" + f2
.toPattern(p
) + "\"");
2426 // Test writeObject/readObject round trip
2427 // NOT ON ICU -- Java only
2433 * May 17 1999 sync up - liu
2434 * DecimalFormat.parse() fails for mulipliers 2^n.
2436 void NumberFormatRegressionTest::Test4216742(void) {
2437 UErrorCode status
= U_ZERO_ERROR
;
2438 DecimalFormat
*fmt
= (DecimalFormat
*) NumberFormat::createInstance(Locale::getUS(), status
);
2439 if (failure(status
, "createInstance", Locale::getUS())){
2443 int32_t DATA
[] = { INT32_MIN
, INT32_MAX
, -100000000, 100000000 };
2444 int DATA_length
= (int)(sizeof(DATA
) / sizeof(DATA
[0]));
2445 for (int i
=0; i
<DATA_length
; ++i
) {
2446 UnicodeString
str((UnicodeString
)"" + DATA
[i
]);
2447 for (int m
= 1; m
<= 100; m
++) {
2448 fmt
->setMultiplier(m
);
2450 fmt
->parse(str
, num
, status
);
2451 failure(status
, "parse", Locale::getUS());
2452 if (num
.getType() != Formattable::kLong
&&
2453 num
.getType() != Formattable::kDouble
) {
2454 errln(UnicodeString("FAIL: Wanted number, got ") +
2457 double d
= num
.getType() == Formattable::kDouble
?
2458 num
.getDouble() : (double) num
.getLong();
2459 if (d
> 0 != DATA
[i
] > 0) {
2460 errln(UnicodeString("\"") + str
+ "\" parse(x " +
2461 fmt
->getMultiplier() +
2462 ") => " + toString(num
));
2471 * May 17 1999 sync up - liu
2472 * DecimalFormat formats 1.001 to "1.00" instead of "1" with 2 fraction
2475 void NumberFormatRegressionTest::Test4217661(void) {
2476 const double D
[] = { 0.001, 1.001, 0.006, 1.006 };
2477 const char* S
[] = { "0", "1", "0.01", "1.01" };
2478 int D_length
= (int)(sizeof(D
) / sizeof(D
[0]));
2479 UErrorCode status
= U_ZERO_ERROR
;
2480 NumberFormat
*fmt
= NumberFormat::createInstance(Locale::getUS(), status
);
2481 if (failure(status
, "createInstance", Locale::getUS())){
2485 fmt
->setMaximumFractionDigits(2);
2486 for (int i
=0; i
<D_length
; i
++) {
2488 fmt
->format(D
[i
], s
);
2489 if (s
!= UnicodeString(S
[i
])) {
2490 errln(UnicodeString("FAIL: Got ") + s
+ ", exp " + S
[i
]);
2497 * alphaWorks upgrade
2499 void NumberFormatRegressionTest::Test4161100(void) {
2500 UErrorCode status
= U_ZERO_ERROR
;
2501 NumberFormat
*nf
= NumberFormat::createInstance(Locale::getUS(), status
);
2502 if (failure(status
, "createInstance", Locale::getUS())){
2506 nf
->setMinimumFractionDigits(1);
2507 nf
->setMaximumFractionDigits(1);
2512 logln(UnicodeString() + a
+ " x " +
2513 ((DecimalFormat
*) nf
)->toPattern(pat
) + " = " + s
);
2514 if (s
!= UnicodeString("-0.1")) {
2521 * June 16 1999 sync up - liu
2522 * Formatting .5 rounds to "1" instead of "0". (Regression in 1.2.2 RC1)
2524 void NumberFormatRegressionTest::Test4243011(void) {
2525 UErrorCode status
= U_ZERO_ERROR
;
2526 DecimalFormatSymbols
sym(Locale::getUS(), status
);
2527 failure(status
, "DecimalFormatSymbols ct", Locale::getUS());
2528 DecimalFormat
fmt(UnicodeString("0."), sym
, status
);
2529 failure(status
, "DecimalFormat ct", Locale::getUS());
2531 const double NUM
[] = { -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5 };
2532 const char* STR
[] = { "-2.", "-2.", "-0.", "0.", "2.", "2.", "4.", "4." };
2533 int32_t N
= (int32_t)(sizeof(NUM
) / sizeof(NUM
[0]));
2535 for (int32_t i
=0; i
<N
; ++i
) {
2537 UnicodeString
exp(STR
[i
]);
2539 fmt
.format(NUM
[i
], str
, pos
);
2541 logln(UnicodeString("Ok ") + NUM
[i
] + " x 0. = " + str
);
2543 errln(UnicodeString("FAIL ") + NUM
[i
] + " x 0. = " + str
+
2550 * June 16 1999 sync up - liu
2551 * format(0.0) gives "0.1" if preceded by parse("99.99").
2552 * (Regression in 1.2.2 RC1)
2554 void NumberFormatRegressionTest::Test4243108(void) {
2555 UErrorCode status
= U_ZERO_ERROR
;
2556 DecimalFormatSymbols
sym(Locale::getUS(), status
);
2557 failure(status
, "DecimalFormatSymbols ct", Locale::getUS());
2558 DecimalFormat
fmt(UnicodeString("#.#"), sym
, status
);
2559 failure(status
, "DecimalFormat ct", Locale::getUS());
2564 fmt
.format(0.0, str
, pos
);
2565 UnicodeString
exp("0");
2567 logln(UnicodeString("Ok 0.0 x #.# = ") + str
);
2569 errln(UnicodeString("FAIL 0.0 x #.# = ") + str
+
2575 fmt
.parse(str
, val
, status
);
2576 failure(status
, "DecimalFormat.parse(99.99)", Locale::getUS());
2577 if (val
.getType() == Formattable::kDouble
&&
2578 val
.getDouble() == 99.99) {
2579 logln(UnicodeString("Ok 99.99 / #.# = ") + toString(val
));
2581 errln(UnicodeString("FAIL 99.99 / #.# = ") + toString(val
) +
2586 fmt
.format(0.0, str
, pos
);
2588 logln(UnicodeString("Ok 0.0 x #.# = ") + str
);
2590 errln(UnicodeString("FAIL 0.0 x #.# = ") + str
+
2597 * DateFormat should call setIntegerParseOnly(TRUE) on adopted
2598 * NumberFormat objects.
2600 void NumberFormatRegressionTest::TestJ691(void) {
2601 UErrorCode status
= U_ZERO_ERROR
;
2602 Locale
loc("fr", "CH");
2604 // set up the input date string & expected output
2605 UnicodeString
udt("11.10.2000", "");
2606 UnicodeString
exp("11.10.00", "");
2608 // create a Calendar for this locale
2609 Calendar
*cal
= Calendar::createInstance(loc
, status
);
2610 if (U_FAILURE(status
)) {
2611 errln("FAIL: Calendar::createInstance() returned " + (UnicodeString
)u_errorName(status
));
2615 // create a NumberFormat for this locale
2616 NumberFormat
*nf
= NumberFormat::createInstance(loc
, status
);
2617 if (U_FAILURE(status
)) {
2618 errln("FAIL: NumberFormat::createInstance() returned " + (UnicodeString
)u_errorName(status
));
2622 // *** Here's the key: We don't want to have to do THIS:
2623 // nf->setParseIntegerOnly(TRUE);
2625 // create the DateFormat
2626 DateFormat
*df
= DateFormat::createDateInstance(DateFormat::kShort
, loc
);
2627 if (U_FAILURE(status
)) {
2628 errln("FAIL: DateFormat::createInstance() returned " + (UnicodeString
)u_errorName(status
));
2632 df
->adoptCalendar(cal
);
2633 df
->adoptNumberFormat(nf
);
2635 // set parsing to lenient & parse
2636 df
->setLenient(TRUE
);
2637 UDate ulocdat
= df
->parse(udt
, status
);
2639 // format back to a string
2640 UnicodeString outString
;
2641 df
->format(ulocdat
, outString
);
2643 if (outString
!= exp
) {
2644 errln("FAIL: " + udt
+ " => " + outString
);
2650 #endif /* #if !UCONFIG_NO_FORMATTING */