1 /***********************************************************************
2 * Copyright (c) 1997-2011, 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
);
173 default: name
= ""; break;
178 NumberFormatRegressionTest::failure(UErrorCode status
, const UnicodeString
& msg
, const Locale
& l
, UBool possibleDataError
)
180 if(U_FAILURE(status
)) {
181 if (possibleDataError
) {
182 dataerrln(UnicodeString("FAIL: ", "") + msg
183 + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status
), "") + UnicodeString(l
.getName(),""));
185 errcheckln(status
, UnicodeString("FAIL: ", "") + msg
186 + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status
), "") + UnicodeString(l
.getName(),""));
195 NumberFormatRegressionTest::failure(UErrorCode status
, const UnicodeString
& msg
, const char *l
, UBool possibleDataError
)
197 if(U_FAILURE(status
)) {
198 if (possibleDataError
) {
199 dataerrln(UnicodeString("FAIL: ", "") + msg
200 + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status
), "") + UnicodeString(l
, ""));
202 errcheckln(status
, UnicodeString("FAIL: ", "") + msg
203 + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status
), "") + UnicodeString(l
, ""));
212 NumberFormatRegressionTest::failure(UErrorCode status
, const UnicodeString
& msg
, UBool possibleDataError
)
214 if(U_FAILURE(status
)) {
215 if (possibleDataError
) {
216 dataerrln(UnicodeString("FAIL: ", "") + msg
217 + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status
), ""));
219 errcheckln(status
, UnicodeString("FAIL: ", "") + msg
220 + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status
), ""));
229 * Convert Java-style strings with \u Unicode escapes into UnicodeString objects
231 inline UnicodeString
str(const char *input
)
233 return CharsToUnicodeString(input
);
237 * NumberFormat.equals comparing with null should always return false.
239 // {sfb} kind of silly in C++, just checking for new success
240 void NumberFormatRegressionTest::Test4075713(void)
243 MyNumberFormatTest
*tmp
= new MyNumberFormatTest();
245 logln("NumberFormat.equals passed");
246 /*} catch (NullPointerException e) {
247 errln("(new MyNumberFormatTest()).equals(null) throws unexpected exception");
254 * NumberFormat.equals comparing two obj equal even the setGroupingUsed
257 void NumberFormatRegressionTest::Test4074620(void)
260 MyNumberFormatTest
*nf1
= new MyNumberFormatTest();
261 MyNumberFormatTest
*nf2
= new MyNumberFormatTest();
263 nf1
->setGroupingUsed(FALSE
);
264 nf2
->setGroupingUsed(TRUE
);
267 errln("Test for bug 4074620 failed");
269 logln("Test for bug 4074620 passed.");
277 * DecimalFormat.format() incorrectly uses maxFractionDigits setting.
280 void NumberFormatRegressionTest::Test4088161 (void)
282 UErrorCode status
= U_ZERO_ERROR
;
283 DecimalFormat
*df
= new DecimalFormat(status
);
284 if (!failure(status
, "new DecimalFormat", "")) {
286 df
->setMinimumFractionDigits(0);
287 df
->setMaximumFractionDigits(16);
289 FieldPosition
fp1(0);
290 logln(UnicodeString("d = ") + d
);
291 logln("maxFractionDigits = " + df
->getMaximumFractionDigits());
293 logln(" format(d) = '" + df
->format(d
, sBuf1
, fp1
) + "'");
294 df
->setMaximumFractionDigits(17);
296 FieldPosition
fp2(0);
297 logln("maxFractionDigits = " + df
->getMaximumFractionDigits());
298 sBuf2
= df
->format(d
, sBuf2
, fp2
);
300 errln(" format(d) = '" + sBuf2
+ "'");
307 * DecimalFormatSymbols should be cloned in the ctor DecimalFormat.
308 * DecimalFormat(String, DecimalFormatSymbols).
310 void NumberFormatRegressionTest::Test4087245 (void)
312 UErrorCode status
= U_ZERO_ERROR
;
313 DecimalFormatSymbols
*symbols
= new DecimalFormatSymbols(status
);
314 failure(status
, "new DecimalFormatSymbols", "");
315 // {sfb} One note about this test: if you pass in a pointer
316 // to the symbols, they are adopted and this test will fail,
317 // even though that is the correct behavior. To test the cloning
318 // of the symbols, it is necessary to pass in a reference to the symbols
319 DecimalFormat
*df
= new DecimalFormat("#,##0.0", *symbols
, status
);
320 failure(status
, "new DecimalFormat with symbols", "");
324 FieldPosition
pos(FieldPosition::DONT_CARE
);
325 logln(UnicodeString("format(") + n
+ ") = " +
326 df
->format(n
, buf1
, pos
));
327 symbols
->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
, UnicodeString((UChar
)0x70)); // change value of field
328 logln(UnicodeString("format(") + n
+ ") = " +
329 df
->format(n
, buf2
, pos
));
331 errln("Test for bug 4087245 failed");
338 * DecimalFormat.format() incorrectly formats 0.0
340 void NumberFormatRegressionTest::Test4087535 (void)
342 UErrorCode status
= U_ZERO_ERROR
;
343 DecimalFormat
*df
= new DecimalFormat(status
);
344 failure(status
, "new DecimalFormat", "");
345 df
->setMinimumIntegerDigits(0);
348 UnicodeString buffer
;
349 FieldPosition
pos(FieldPosition::DONT_CARE
);
350 buffer
= df
->format(n
, buffer
, pos
);
351 if (buffer
.length() == 0)
352 errln(/*n + */": '" + buffer
+ "'");
354 buffer
= df
->format(n
, buffer
, pos
);
355 if (buffer
.length() == 0)
356 errln(/*n + */": '" + buffer
+ "'");
362 * DecimalFormat.format fails when groupingSize is set to 0.
364 // {sfb} how do I tell if this worked? --> FieldPosition doesn't change ??
365 void NumberFormatRegressionTest::Test4088503 (void)
367 UErrorCode status
= U_ZERO_ERROR
;
368 DecimalFormat
*df
= new DecimalFormat(status
);
369 failure(status
, "new DecimalFormat", "");
370 df
->setGroupingSize(0);
372 FieldPosition
fp(FieldPosition::DONT_CARE
);
374 logln(df
->format((int32_t)123, sBuf
, fp
));
375 //if(fp == FieldPosition(0))
376 // errln("Test for bug 4088503 failed.");
377 /*} catch (Exception foo) {
378 errln("Test for bug 4088503 failed.");
384 * NumberFormat.getCurrencyInstance is wrong.
386 void NumberFormatRegressionTest::Test4066646 (void)
388 assignFloatValue(2.04f
);
389 assignFloatValue(2.03f
);
390 assignFloatValue(2.02f
);
391 assignFloatValue(0.0f
);
395 NumberFormatRegressionTest::assignFloatValue(float returnfloat
)
397 logln(UnicodeString(" VALUE ") + returnfloat
);
398 UErrorCode status
= U_ZERO_ERROR
;
399 NumberFormat
*nfcommon
= NumberFormat::createCurrencyInstance(Locale::getUS(), status
);
400 if (failure(status
, "NumberFormat::createCurrencyInstance", Locale::getUS(), TRUE
)){
404 nfcommon
->setGroupingUsed(FALSE
);
406 UnicodeString stringValue
;
407 stringValue
= nfcommon
->format(returnfloat
, stringValue
);
408 logln(" DISPLAYVALUE " + stringValue
);
410 nfcommon
->parse(stringValue
, result
, status
);
411 failure(status
, "nfcommon->parse", Locale::getUS());
412 float floatResult
= (float) (result
.getType() == Formattable::kDouble
413 ? result
.getDouble() : result
.getLong());
414 if( uprv_fabs(floatResult
- returnfloat
) > 0.0001)
415 //String stringValue = nfcommon.format(returnfloat).substring(1);
416 //if (Float.valueOf(stringValue).floatValue() != returnfloat)
417 errln(UnicodeString("FAIL: expected ") + returnfloat
+ ", got " + floatResult
+ " (" + stringValue
+")");
421 } // End Of assignFloatValue()
424 * DecimalFormat throws exception when parsing "0"
426 void NumberFormatRegressionTest::Test4059870(void)
428 UErrorCode status
= U_ZERO_ERROR
;
429 DecimalFormat
*format
= new DecimalFormat("00", status
);
430 failure(status
, "new Decimalformat", Locale::getUS());
434 format
->parse(UnicodeString("0"), result
, status
);
435 failure(status
, "format->parse", Locale::getUS());
438 catch (Exception e) {
439 errln("Test for bug 4059870 failed : " + e);
445 * DecimalFormatSymbol.equals should always return false when
446 * comparing with null.
448 // {sfb} this is silly in C++
449 void NumberFormatRegressionTest::Test4083018 (void)
451 UErrorCode status
= U_ZERO_ERROR
;
452 DecimalFormatSymbols
*dfs
= new DecimalFormatSymbols(status
);
453 failure(status
, "new DecimalFormatSymbols", Locale::getUS());
456 logln("Test Passed!");
458 errln("Test for bug 4083018 failed");
459 /*} catch (Exception foo) {
460 errln("Test for bug 4083018 failed => Message : " + foo.getMessage());
467 * DecimalFormat does not round up correctly.
469 void NumberFormatRegressionTest::Test4071492 (void)
471 double x
= 0.00159999;
472 UErrorCode status
= U_ZERO_ERROR
;
473 NumberFormat
*nf
= NumberFormat::createInstance(status
);
474 if (failure(status
, "NumberFormat::createInstance", Locale::getUS(), TRUE
)) {
478 nf
->setMaximumFractionDigits(4);
480 FieldPosition
pos(FieldPosition::DONT_CARE
);
481 out
= nf
->format(x
, out
, pos
);
482 logln("0.00159999 formats with 4 fractional digits to " + out
);
483 UnicodeString
expected("0.0016");
485 errln("FAIL: Expected " + expected
);
491 * A space as a group separator for localized pattern causes
492 * wrong format. WorkAround : use non-breaking space.
494 void NumberFormatRegressionTest::Test4086575(void)
496 UErrorCode status
= U_ZERO_ERROR
;
497 NumberFormat
*nf1
= NumberFormat::createInstance(Locale::getFrance(), status
);
499 // TODO: There is not a good way to find out that the creation of this number format has
500 // failed. Major rewiring of format construction proposed.
501 if(U_FAILURE(status
)) {
502 dataerrln("Something is wrong with French number format - it should not fallback. Exitting - %s", u_errorName(status
));
506 failure(status
, "NumberFormat::createInstance", Locale::getFrance());
508 // C++ workaround to make sure cast works
509 DecimalFormat
*nf
= dynamic_cast<DecimalFormat
*>(nf1
);
511 errln("NumberFormat::createInstance returned incorrect type.");
516 logln("nf toPattern1: " + nf
->toPattern(temp
));
517 logln("nf toLocPattern1: " + nf
->toLocalizedPattern(temp
));
519 // No group separator
520 logln("...applyLocalizedPattern ###,00;(###,00) ");
521 nf
->applyLocalizedPattern(UnicodeString("###,00;(###,00)"), status
);
522 failure(status
, "nf->applyLocalizedPattern", Locale::getFrance());
523 logln("nf toPattern2: " + nf
->toPattern(temp
));
524 logln("nf toLocPattern2: " + nf
->toLocalizedPattern(temp
));
526 FieldPosition
pos(FieldPosition::DONT_CARE
);
527 logln("nf: " + nf
->format((int32_t)1234, temp
, pos
)); // 1234,00
528 logln("nf: " + nf
->format((int32_t)-1234, temp
, pos
)); // (1234,00)
530 // Space as group separator
532 logln("...applyLocalizedPattern # ###,00;(# ###,00) ");
534 //nf->applyLocalizedPattern("#\u00a0###,00;(#\u00a0###,00)");
536 0x23, 0x00a0, 0x23, 0x23, 0x23, 0x2c, 0x30, 0x30, 0x3b,
537 0x28, 0x23, 0x00a0, 0x23, 0x23, 0x23, 0x2c, 0x30, 0x30, 0x29
539 UnicodeString
pat(patChars
, 19, 19);
540 nf
->applyLocalizedPattern(pat
, status
);
541 failure(status
, "nf->applyLocalizedPattern", Locale::getFrance());
542 logln("nf toPattern2: " + nf
->toPattern(temp
));
543 logln("nf toLocPattern2: " + nf
->toLocalizedPattern(temp
));
544 UnicodeString buffer
;
545 buffer
= nf
->format((int32_t)1234, buffer
, pos
);
546 //if (buffer != UnicodeString("1\u00a0234,00"))
548 0x31, 0x00a0, 0x32, 0x33, 0x34, 0x2c, 0x30, 0x30
550 UnicodeString
cc(c
, 8, 8);
552 errln("nf : " + buffer
); // Expect 1 234,00
555 buffer
= nf
->format((int32_t)-1234, buffer
, pos
);
557 0x28, 0x31, 0x00a0, 0x32, 0x33, 0x34, 0x2c, 0x30, 0x30, 0x29
559 UnicodeString
cc1(c1
, 10, 10);
561 errln("nf : " + buffer
); // Expect (1 234,00)
563 // Erroneously prints:
570 * DecimalFormat.parse returns wrong value
572 // {sfb} slightly converted into a round-trip test, since in C++
573 // there is no Double.toString()
574 void NumberFormatRegressionTest::Test4068693(void)
576 logln("----- Test Application -----");
577 ParsePosition
pos(0);
578 UErrorCode status
= U_ZERO_ERROR
;
579 DecimalFormat
*df
= new DecimalFormat(status
);
580 if(U_FAILURE(status
)) {
581 errcheckln(status
, "Error creating DecimalFormat: %s", u_errorName(status
));
585 failure(status
, "new DecimalFormat");
587 //Double d = (Double)df.parse("123.55456", pos=new ParsePosition(0));
588 df
->parse(UnicodeString("123.55456"), d
, pos
);
589 //if (!d.toString().equals("123.55456")) {
591 df
->setMaximumFractionDigits(999);
592 df
->setMaximumIntegerDigits(999);
593 FieldPosition
fp(FieldPosition::DONT_CARE
);
594 dstr
= df
->format(d
.getDouble(), dstr
, fp
);
595 if (dstr
!= UnicodeString("123.55456")) {
596 errln(UnicodeString("Result -> ") + d
.getDouble());
602 /* @bug 4069754, 4067878
603 * null pointer thrown when accessing a deserialized DecimalFormat
606 // {sfb} doesn't apply in C++
607 void NumberFormatRegressionTest::Test4069754(void)
610 myformat it = new myformat();
612 FileOutputStream ostream = new FileOutputStream("t.tmp");
613 ObjectOutputStream p = new ObjectOutputStream(ostream);
618 FileInputStream istream = new FileInputStream("t.tmp");
619 ObjectInputStream p2 = new ObjectInputStream(istream);
620 myformat it2 = (myformat)p2.readObject();
624 } catch (Exception foo) {
625 errln("Test for bug 4069754 or 4057878 failed => Exception: " + foo.getMessage());
630 * DecimalFormat.applyPattern(String) allows illegal patterns
632 void NumberFormatRegressionTest::Test4087251 (void)
634 UErrorCode status
= U_ZERO_ERROR
;
635 DecimalFormat
*df
= new DecimalFormat(status
);
636 if(U_FAILURE(status
)) {
637 errcheckln(status
, "Error creating DecimalFormat: %s", u_errorName(status
));
641 failure(status
, "new DecimalFormat");
643 df
->applyPattern(UnicodeString("#.#.#"), status
);
644 if( ! U_FAILURE(status
))
645 errln("df->applyPattern with illegal pattern didn't fail");
647 logln("toPattern() returns \"" + df
->toPattern(temp
) + "\"");
648 //errln("applyPattern(\"#.#.#\") doesn't throw IllegalArgumentException");
649 /*} catch (IllegalArgumentException e) {
650 logln("Caught Illegal Argument Error !");
652 // Second test; added 5/11/98 when reported to fail on 1.2b3
654 df
->applyPattern("#0.0#0#0", status
);
655 if( ! U_FAILURE(status
))
656 errln("df->applyPattern with illegal pattern didn't fail");
657 logln("toPattern() returns \"" + df
->toPattern(temp
) + "\"");
658 //errln("applyPattern(\"#0.0#0#0\") doesn't throw IllegalArgumentException");
659 /*} catch (IllegalArgumentException e) {
660 logln("Ok - IllegalArgumentException for #0.0#0#0");
667 * DecimalFormat.format() loses precision
669 void NumberFormatRegressionTest::Test4090489 (void)
671 // {sfb} sprintf doesn't correctly handle the double, so there is nothing
672 // that NumberFormat can do. For some reason, it does not format the last 1.
674 /* UErrorCode status = U_ZERO_ERROR;
675 DecimalFormat *df = new DecimalFormat(status);
676 failure(status, "new DecimalFormat");
677 df->setMinimumFractionDigits(10);
678 df->setMaximumFractionDigits(999);
679 df->setGroupingUsed(FALSE);
680 double d = 1.000000000000001E7;
681 //BigDecimal bd = new BigDecimal(d);
684 logln(UnicodeString("d = ") + d);
685 //logln("BigDecimal.toString(): " + bd.toString());
686 df->format(d, sb, fp);
687 if (sb != "10000000.0000000100") {
688 errln("DecimalFormat.format(): " + sb);
694 * DecimalFormat.format() loses precision
696 void NumberFormatRegressionTest::Test4090504 (void)
699 logln(UnicodeString("d = ") + d
);
700 UErrorCode status
= U_ZERO_ERROR
;
701 DecimalFormat
*df
= new DecimalFormat(status
);
702 if(U_FAILURE(status
)) {
703 errcheckln(status
, "Error creating DecimalFormat: %s", u_errorName(status
));
707 failure(status
, "new DecimalFormat");
709 FieldPosition
fp(FieldPosition::DONT_CARE
);
711 for (int i
= 17; i
<= 20; i
++) {
712 df
->setMaximumFractionDigits(i
);
713 //sb = new StringBuffer("");
715 logln(" getMaximumFractionDigits() = " + i
);
716 logln(" formated: " + df
->format(d
, sb
, fp
));
718 /*} catch (Exception foo) {
719 errln("Bug 4090504 regression test failed. Message : " + foo.getMessage());
725 * DecimalFormat.parse(String str, ParsePosition pp) loses precision
727 void NumberFormatRegressionTest::Test4095713 (void)
729 UErrorCode status
= U_ZERO_ERROR
;
730 DecimalFormat
*df
= new DecimalFormat(status
);
731 if(U_FAILURE(status
)) {
732 errcheckln(status
, "Error creating DecimalFormat: %s", u_errorName(status
));
736 failure(status
, "new DecimalFormat");
737 UnicodeString
str("0.1234");
739 //Double d1 = new Double(str);
740 //Double d2 = (Double) df.parse(str, new ParsePosition(0));
743 df
->parse(str
, d2
, pp
);
744 logln(UnicodeString("") + d1
);
745 if (d2
.getDouble() != d1
)
746 errln(UnicodeString("Bug 4095713 test failed, new double value : ") + d2
.getDouble());
751 * DecimalFormat.parse() fails when multiplier is not set to 1
753 // {sfb} not sure what to do with this one
754 void NumberFormatRegressionTest::Test4092561 (void)
756 UErrorCode status
= U_ZERO_ERROR
;
757 DecimalFormat
*df
= new DecimalFormat(status
);
758 if(U_FAILURE(status
)) {
759 errcheckln(status
, "Error creating DecimalFormat: %s", u_errorName(status
));
763 failure(status
, "new DecimalFormat");
765 // {sfb} going to cheat here and use sprintf ??
767 /*UnicodeString str = Long.toString(Long.MIN_VALUE);
768 logln("Long.MIN_VALUE : " + df.parse(str, new ParsePosition(0)).toString());
769 df.setMultiplier(100);
770 Number num = df.parse(str, new ParsePosition(0));
771 if (num.doubleValue() != -9.223372036854776E16)
772 errln("Bug 4092561 test failed when multiplier is set to not 1.");
778 * DecimalFormat: Negative format ignored.
780 void NumberFormatRegressionTest::Test4092480 (void)
782 UErrorCode status
= U_ZERO_ERROR
;
783 DecimalFormat
*dfFoo
= new DecimalFormat(UnicodeString("000"), status
);
784 if(U_FAILURE(status
)) {
785 errcheckln(status
, "Error creating DecimalFormat: %s", u_errorName(status
));
789 failure(status
, "new DecimalFormat");
792 dfFoo
->applyPattern("0000;-000", status
);
793 failure(status
, "dfFoo->applyPattern");
795 if (dfFoo
->toPattern(temp
) != UnicodeString("#0000"))
796 errln("dfFoo.toPattern : " + dfFoo
->toPattern(temp
));
797 FieldPosition
pos(FieldPosition::DONT_CARE
);
798 logln(dfFoo
->format((int32_t)42, temp
, pos
));
799 logln(dfFoo
->format((int32_t)-42, temp
, pos
));
800 dfFoo
->applyPattern("000;-000", status
);
801 failure(status
, "dfFoo->applyPattern");
802 if (dfFoo
->toPattern(temp
) != UnicodeString("#000"))
803 errln("dfFoo.toPattern : " + dfFoo
->toPattern(temp
));
804 logln(dfFoo
->format((int32_t)42,temp
, pos
));
805 logln(dfFoo
->format((int32_t)-42, temp
, pos
));
807 dfFoo
->applyPattern("000;-0000", status
);
808 failure(status
, "dfFoo->applyPattern");
809 if (dfFoo
->toPattern(temp
) != UnicodeString("#000"))
810 errln("dfFoo.toPattern : " + dfFoo
->toPattern(temp
));
811 logln(dfFoo
->format((int32_t)42, temp
, pos
));
812 logln(dfFoo
->format((int32_t)-42, temp
, pos
));
814 dfFoo
->applyPattern("0000;-000", status
);
815 failure(status
, "dfFoo->applyPattern");
816 if (dfFoo
->toPattern(temp
) != UnicodeString("#0000"))
817 errln("dfFoo.toPattern : " + dfFoo
->toPattern(temp
));
818 logln(dfFoo
->format((int32_t)42, temp
, pos
));
819 logln(dfFoo
->format((int32_t)-42, temp
, pos
));
820 /*} catch (Exception foo) {
821 errln("Message " + foo.getMessage());
827 * NumberFormat.getCurrencyInstance() produces format that uses
828 * decimal separator instead of monetary decimal separator.
830 * Rewrote this test not to depend on the actual pattern. Pattern should
831 * never contain the monetary separator! Decimal separator in pattern is
832 * interpreted as monetary separator if currency symbol is seen!
834 void NumberFormatRegressionTest::Test4087244 (void) {
835 UErrorCode status
= U_ZERO_ERROR
;
837 uloc_canonicalize("pt_PT_PREEURO", loc
, 256, &status
);
838 Locale
*de
= new Locale(loc
);
839 NumberFormat
*nf
= NumberFormat::createCurrencyInstance(*de
, status
);
840 if(U_FAILURE(status
)) {
841 dataerrln("Error creating DecimalFormat: %s", u_errorName(status
));
845 DecimalFormat
*df
= dynamic_cast<DecimalFormat
*>(nf
);
847 errln("expected DecimalFormat!");
850 const DecimalFormatSymbols
*sym
= df
->getDecimalFormatSymbols();
851 UnicodeString decSep
= sym
->getSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
);
852 UnicodeString monSep
= sym
->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
);
853 if (decSep
== monSep
) {
854 errln("ERROR in test: want decimal sep != monetary sep");
857 df
->setMinimumIntegerDigits(1);
858 df
->setMinimumFractionDigits(2);
861 df
->format(1.23, str
, pos
);
862 UnicodeString
monStr("1x23");
863 monStr
.replace((int32_t)1, 1, monSep
);
864 UnicodeString
decStr("1x23");
865 decStr
.replace((int32_t)1, 1, decSep
);
866 if (str
.indexOf(monStr
) >= 0 && str
.indexOf(decStr
) < 0) {
867 logln(UnicodeString("OK: 1.23 -> \"") + str
+ "\" contains \"" +
868 monStr
+ "\" and not \"" + decStr
+ '"');
870 errln(UnicodeString("FAIL: 1.23 -> \"") + str
+ "\", should contain \"" +
872 "\" and not \"" + decStr
+ '"');
878 * Number format data rounding errors for locale FR
880 void NumberFormatRegressionTest::Test4070798 (void)
882 NumberFormat
*formatter
;
883 UnicodeString tempString
;
886 String expectedDefault = "-5\u00a0789,987";
887 String expectedCurrency = "5\u00a0789,98\u00a0F";
888 String expectedPercent = "-578\u00a0998%";
891 0x2d, 0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x38, 0x38
894 0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x39, 0x00a0, 0x46
897 0x2d, 0x35, 0x37, 0x38, 0x00a0, 0x39, 0x39, 0x39, 0x00a0, 0x25
899 UnicodeString
expectedDefault(chars1
, 10, 10);
900 UnicodeString
expectedCurrency(chars2
, 10, 10);
901 UnicodeString
expectedPercent(chars3
, 10, 10);
903 UErrorCode status
= U_ZERO_ERROR
;
905 int len
= uloc_canonicalize("fr_FR_PREEURO", loc
, 256, &status
);
906 formatter
= NumberFormat::createInstance(Locale(loc
), status
);
907 if(U_FAILURE(status
)) {
908 dataerrln("Error creating DecimalFormat: %s", u_errorName(status
));
912 failure(status
, "NumberFormat::createNumberInstance", loc
);
913 tempString
= formatter
->format (-5789.9876, tempString
);
915 if (tempString
== expectedDefault
) {
916 logln ("Bug 4070798 default test passed.");
918 errln(UnicodeString("Failed:") +
919 " Expected " + expectedDefault
+
920 " Received " + tempString
);
923 len
= uloc_canonicalize("fr_FR_PREEURO", loc
, 256, &status
);
924 formatter
= NumberFormat::createCurrencyInstance(loc
, status
);
925 failure(status
, "NumberFormat::createCurrencyInstance", loc
);
927 tempString
= formatter
->format( 5789.9876, tempString
);
929 if (tempString
== expectedCurrency
) {
930 logln ("Bug 4070798 currency test passed.");
932 errln(UnicodeString("Failed:") +
933 " Expected " + expectedCurrency
+
934 " Received " + tempString
);
938 uloc_canonicalize("fr_FR_PREEURO", loc
, 256, &status
);
939 formatter
= NumberFormat::createPercentInstance(Locale(loc
), status
);
940 failure(status
, "NumberFormat::createPercentInstance", loc
);
942 tempString
= formatter
->format (-5789.9876, tempString
);
944 if (tempString
== expectedPercent
) {
945 logln ("Bug 4070798 percentage test passed.");
947 errln(UnicodeString("Failed:") +
948 " Expected " + expectedPercent
+
949 " Received " + tempString
);
955 * Data rounding errors for French (Canada) locale
957 void NumberFormatRegressionTest::Test4071005 (void)
959 NumberFormat
*formatter
;
960 UnicodeString tempString
;
962 String expectedDefault = "-5\u00a0789,987";
963 String expectedCurrency = "5\u00a0789,98\u00a0$";
964 String expectedPercent = "-578\u00a0998%";
967 0x2d, 0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x38, 0x38
970 0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x39, 0x00a0, 0x24
973 0x2d, 0x35, 0x37, 0x38, 0x00a0, 0x39, 0x39, 0x39, 0x00a0, 0x25
975 UnicodeString
expectedDefault(chars1
, 10, 10);
976 UnicodeString
expectedCurrency(chars2
, 10, 10);
977 UnicodeString
expectedPercent(chars3
, 10, 10);
979 UErrorCode status
= U_ZERO_ERROR
;
980 formatter
= NumberFormat::createInstance(Locale::getCanadaFrench(), status
);
981 if (failure(status
, "NumberFormat::createNumberInstance", Locale::getCanadaFrench(), TRUE
)){
985 tempString
= formatter
->format (-5789.9876, tempString
);
987 if (tempString
== expectedDefault
) {
988 logln ("Bug 4071005 default test passed.");
990 errln(UnicodeString("Failed:") +
991 " Expected " + expectedDefault
+
992 " Received " + tempString
);
996 formatter
= NumberFormat::createCurrencyInstance(Locale::getCanadaFrench(), status
);
997 failure(status
, "NumberFormat::createCurrencyInstance", Locale::getCanadaFrench());
999 tempString
= formatter
->format( 5789.9876, tempString
);
1001 if (tempString
== expectedCurrency
) {
1002 logln ("Bug 4071005 currency test assed.");
1004 errln(UnicodeString("Failed:") +
1005 " Expected " + expectedCurrency
+
1006 " Received " + tempString
);
1010 formatter
= NumberFormat::createPercentInstance(Locale::getCanadaFrench(), status
);
1011 failure(status
, "NumberFormat::createPercentInstance", Locale::getCanadaFrench());
1012 tempString
.remove();
1013 tempString
= formatter
->format (-5789.9876, tempString
);
1015 if (tempString
== expectedPercent
) {
1016 logln ("Bug 4071005 percentage test passed.");
1018 errln(UnicodeString("Failed:") +
1019 " Expected " + expectedPercent
+
1020 " Received " + tempString
);
1027 * Data rounding errors for German (Germany) locale
1029 void NumberFormatRegressionTest::Test4071014 (void)
1031 NumberFormat
*formatter
;
1032 UnicodeString tempString
;
1034 String expectedDefault = "-5.789,987";
1035 String expectedCurrency = "5.789,98 DM";
1036 String expectedPercent = "-578.998%";
1038 UnicodeString
expectedDefault("-5.789,988");
1039 UnicodeString
expectedCurrency("5.789,99\\u00A0DM");
1040 UnicodeString
expectedPercent("-578.999\\u00A0%");
1042 expectedCurrency
= expectedCurrency
.unescape();
1043 expectedPercent
= expectedPercent
.unescape();
1045 UErrorCode status
= U_ZERO_ERROR
;
1047 uloc_canonicalize("de_DE_PREEURO", loc
, 256, &status
);
1048 formatter
= NumberFormat::createInstance(Locale(loc
), status
);
1049 if (failure(status
, "NumberFormat::createNumberInstance", loc
, TRUE
)){
1053 tempString
.remove();
1054 tempString
= formatter
->format (-5789.9876, tempString
);
1056 if (tempString
== expectedDefault
) {
1057 logln ("Bug 4071014 default test passed.");
1059 errln(UnicodeString("Failed:") +
1060 " Expected " + expectedDefault
+
1061 " Received " + tempString
);
1064 uloc_canonicalize("de_DE_PREEURO", loc
, 256, &status
);
1065 formatter
= NumberFormat::createCurrencyInstance(Locale(loc
), status
);
1066 failure(status
, "NumberFormat::createCurrencyInstance", loc
);
1067 tempString
.remove();
1068 tempString
= formatter
->format( 5789.9876, tempString
);
1070 if (tempString
== expectedCurrency
) {
1071 logln ("Bug 4071014 currency test assed.");
1073 errln(UnicodeString("Failed:") +
1074 " Expected " + expectedCurrency
+
1075 " Received " + tempString
);
1079 formatter
= NumberFormat::createPercentInstance(Locale::getGermany(), status
);
1080 failure(status
, "NumberFormat::createPercentInstance", Locale::getGermany());
1081 tempString
.remove();
1082 tempString
= formatter
->format (-5789.9876, tempString
);
1084 if (tempString
== expectedPercent
) {
1085 logln ("Bug 4071014 percentage test passed.");
1087 errln(UnicodeString("Failed:") +
1088 " Expected " + expectedPercent
+
1089 " Received " + tempString
);
1095 * Data rounding errors for Italian locale number formats
1097 void NumberFormatRegressionTest::Test4071859 (void)
1099 NumberFormat
*formatter
;
1100 UnicodeString tempString
;
1102 String expectedDefault = "-5.789,987";
1103 String expectedCurrency = "-L.\\u00A05.789,98";
1104 String expectedPercent = "-578.998%";
1106 UnicodeString
expectedDefault("-5.789,988");
1107 UnicodeString
expectedCurrency("-IT\\u20A4\\u00A05.790", -1, US_INV
);
1108 UnicodeString
expectedPercent("-578.999%");
1109 expectedCurrency
= expectedCurrency
.unescape();
1111 UErrorCode status
= U_ZERO_ERROR
;
1113 uloc_canonicalize("it_IT_PREEURO", loc
, 256, &status
);
1114 formatter
= NumberFormat::createInstance(Locale(loc
), status
);
1115 if (failure(status
, "NumberFormat::createNumberInstance", TRUE
)){
1119 tempString
= formatter
->format (-5789.9876, tempString
);
1121 if (tempString
== expectedDefault
) {
1122 logln ("Bug 4071859 default test passed.");
1124 errln(UnicodeString("Failed:") +
1125 " Expected " + expectedDefault
+
1126 " Received " + tempString
);
1129 uloc_canonicalize("it_IT_PREEURO", loc
, 256, &status
);
1130 formatter
= NumberFormat::createCurrencyInstance(Locale(loc
), status
);
1131 failure(status
, "NumberFormat::createCurrencyInstance");
1132 tempString
.remove();
1133 tempString
= formatter
->format( -5789.9876, tempString
);
1135 if (tempString
== expectedCurrency
) {
1136 logln ("Bug 4071859 currency test assed.");
1138 errln(UnicodeString("Failed:") +
1139 " Expected " + expectedCurrency
+
1140 " Received " + tempString
);
1143 uloc_canonicalize("it_IT_PREEURO", loc
, 256, &status
);
1144 formatter
= NumberFormat::createPercentInstance(Locale(loc
), status
);
1145 failure(status
, "NumberFormat::createPercentInstance");
1146 tempString
.remove();
1147 tempString
= formatter
->format (-5789.9876, tempString
);
1149 if (tempString
== expectedPercent
) {
1150 logln ("Bug 4071859 percentage test passed.");
1152 errln(UnicodeString("Failed:") +
1153 " Expected " + expectedPercent
+
1154 " Received " + tempString
);
1160 * Test rounding for nearest even.
1162 void NumberFormatRegressionTest::Test4093610(void)
1164 UErrorCode status
= U_ZERO_ERROR
;
1165 DecimalFormat
*df
= new DecimalFormat("#0.#", status
);
1166 if (!failure(status
, "new DecimalFormat")) {
1167 UnicodeString
s("12.4");
1168 roundingTest(df
, 12.35, s
);
1169 roundingTest(df
, 12.45, s
);
1171 roundingTest(df
, 12.452,s
);
1173 roundingTest(df
, 12.55, s
);
1174 roundingTest(df
, 12.65, s
);
1176 roundingTest(df
, 12.652,s
);
1178 roundingTest(df
, 12.75, s
);
1179 roundingTest(df
, 12.752,s
);
1180 roundingTest(df
, 12.85, s
);
1182 roundingTest(df
, 12.852,s
);
1184 roundingTest(df
, 12.95, s
);
1185 roundingTest(df
, 12.952,s
);
1191 void NumberFormatRegressionTest::roundingTest(DecimalFormat
*df
, double x
, UnicodeString
& expected
)
1194 FieldPosition
pos(FieldPosition::DONT_CARE
);
1195 out
= df
->format(x
, out
, pos
);
1196 logln(UnicodeString("") + x
+ " formats with 1 fractional digits to " + out
);
1197 if (out
!= expected
)
1198 errln("FAIL: Expected " + expected
);
1201 * Tests the setMaximumFractionDigits limit.
1203 void NumberFormatRegressionTest::Test4098741(void)
1206 UErrorCode status
= U_ZERO_ERROR
;
1207 NumberFormat
*fmt
= NumberFormat::createPercentInstance(status
);
1208 if (U_FAILURE(status
)) {
1209 dataerrln("Error calling NumberFormat::createPercentInstance");
1214 fmt
->setMaximumFractionDigits(20);
1216 logln(fmt
->format(.001, temp
));
1217 /*} catch (Exception foo) {
1218 errln("Bug 4098471 failed with exception thrown : " + foo.getMessage());
1223 * Tests illegal pattern exception.
1224 * Fix comment : HShih A31 Part1 will not be fixed and javadoc needs to be updated.
1225 * Part2 has been fixed.
1227 void NumberFormatRegressionTest::Test4074454(void)
1230 UErrorCode status
= U_ZERO_ERROR
;
1231 DecimalFormat
*fmt
= new DecimalFormat("#,#00.00;-#.#", status
);
1232 if(U_FAILURE(status
)) {
1233 errcheckln(status
, "Error creating DecimalFormat: %s", u_errorName(status
));
1237 failure(status
, "new DecimalFormat");
1238 logln("Inconsistent negative pattern is fine.");
1239 DecimalFormat
*newFmt
= new DecimalFormat("#,#00.00 p''ieces;-#,#00.00 p''ieces", status
);
1240 failure(status
, "new DecimalFormat");
1241 UnicodeString tempString
;
1242 FieldPosition
pos(FieldPosition::DONT_CARE
);
1243 tempString
= newFmt
->format(3456.78, tempString
, pos
);
1244 if (tempString
!= UnicodeString("3,456.78 p'ieces"))
1245 dataerrln("Failed! 3456.78 p'ieces expected, but got : " + tempString
);
1246 /*} catch (Exception foo) {
1247 errln("An exception was thrown for any inconsistent negative pattern.");
1254 * Tests all different comments.
1255 * Response to some comments :
1256 * [1] DecimalFormat.parse API documentation is more than just one line.
1257 * This is not a reproducable doc error in 116 source code.
1258 * [2] See updated javadoc.
1260 * [4] NumberFormat.parse(String, ParsePosition) : If parsing fails,
1261 * a null object will be returned. The unchanged parse position also
1262 * reflects an error.
1263 * NumberFormat.parse(String) : If parsing fails, an ParseException
1265 * See updated javadoc for more details.
1266 * [5] See updated javadoc.
1267 * [6] See updated javadoc.
1268 * [7] This is a correct behavior if the DateFormat object is linient.
1269 * Otherwise, an IllegalArgumentException will be thrown when formatting
1270 * "January 35". See GregorianCalendar class javadoc for more details.
1272 void NumberFormatRegressionTest::Test4099404(void)
1275 UErrorCode status
= U_ZERO_ERROR
;
1276 DecimalFormat
*fmt
= new DecimalFormat(UnicodeString("000.0#0"), status
);
1277 if(! U_FAILURE(status
))
1278 errln(UnicodeString("Bug 4099404 failed applying illegal pattern \"000.0#0\""));
1279 /*} catch (Exception foo) {
1280 logln("Bug 4099404 pattern \"000.0#0\" passed");
1285 fmt
= new DecimalFormat(UnicodeString("0#0.000"), status
);
1286 if( !U_FAILURE(status
))
1287 errln("Bug 4099404 failed applying illegal pattern \"0#0.000\"");
1288 /*} catch (Exception foo) {
1289 logln("Bug 4099404 pattern \"0#0.000\" passed");
1295 * DecimalFormat.applyPattern doesn't set minimum integer digits
1297 void NumberFormatRegressionTest::Test4101481(void)
1299 UErrorCode status
= U_ZERO_ERROR
;
1300 DecimalFormat
*sdf
= new DecimalFormat(UnicodeString("#,##0"), status
);
1301 if(U_FAILURE(status
)) {
1302 errcheckln(status
, "Error creating DecimalFormat: %s", u_errorName(status
));
1306 failure(status
, "new DecimalFormat");
1307 if (sdf
->getMinimumIntegerDigits() != 1)
1308 errln("Minimum integer digits : " + sdf
->getMinimumIntegerDigits());
1311 /* @bug 4052223 (API addition request A27)
1312 * Tests ParsePosition.setErrorPosition() and ParsePosition.getErrorPosition().
1314 void NumberFormatRegressionTest::Test4052223(void)
1317 UErrorCode status
= U_ZERO_ERROR
;
1318 DecimalFormat
*fmt
= new DecimalFormat(UnicodeString("#,#00.00"), status
);
1319 if(U_FAILURE(status
)) {
1320 errcheckln(status
, "Error creating DecimalFormat: %s", u_errorName(status
));
1324 failure(status
, "new DecimalFormat");
1326 fmt
->parse(UnicodeString("abc3"), num
, status
);
1327 if(! U_FAILURE(status
))
1328 errln(UnicodeString("Bug 4052223 failed : can't parse string \"a\". Got ") /*+ num*/);
1329 /*} catch (ParseException foo) {
1330 logln("Caught expected ParseException : " + foo.getMessage() + " at index : " + foo.getErrorOffset());
1335 * API tests for API addition request A9.
1337 void NumberFormatRegressionTest::Test4061302(void)
1339 UErrorCode status
= U_ZERO_ERROR
;
1340 DecimalFormatSymbols
*fmt
= new DecimalFormatSymbols(status
);
1341 failure(status
, "new DecimalFormatSymbols");
1342 UnicodeString
currency(fmt
->getSymbol(DecimalFormatSymbols::kCurrencySymbol
));
1343 UnicodeString
intlCurrency(fmt
->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
));
1344 UnicodeString
monDecSeparator(fmt
->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
));
1345 if (currency
== UnicodeString("") ||
1346 intlCurrency
== UnicodeString("") ||
1347 monDecSeparator
== UnicodeString(""))
1349 errln("getCurrencySymbols failed, got empty string.");
1351 UnicodeString monDecSeparatorStr
;
1352 monDecSeparatorStr
.append(monDecSeparator
);
1353 logln((UnicodeString
)"Before set ==> Currency : " + currency
+(UnicodeString
)" Intl Currency : " + intlCurrency
+ (UnicodeString
)" Monetary Decimal Separator : " + monDecSeparatorStr
);
1354 fmt
->setSymbol(DecimalFormatSymbols::kCurrencySymbol
, UnicodeString("XYZ"));
1355 fmt
->setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
, UnicodeString("ABC"));
1356 fmt
->setSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
, UnicodeString((UChar
)0x002A/*'*'*/));
1357 currency
= fmt
->getSymbol(DecimalFormatSymbols::kCurrencySymbol
);
1358 intlCurrency
= fmt
->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
);
1359 monDecSeparator
= fmt
->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
);
1360 if (currency
!= UnicodeString("XYZ") ||
1361 intlCurrency
!= UnicodeString("ABC") ||
1362 monDecSeparator
!= UnicodeString((UChar
)0x002A/*'*'*/)) {
1363 errln("setCurrencySymbols failed.");
1365 monDecSeparatorStr
.remove();
1366 monDecSeparatorStr
.append(monDecSeparator
);
1367 logln("After set ==> Currency : " + currency
+ " Intl Currency : " + intlCurrency
+ " Monetary Decimal Separator : " + monDecSeparatorStr
);
1372 * API tests for API addition request A23. FieldPosition.getBeginIndex and
1373 * FieldPosition.getEndIndex.
1375 void NumberFormatRegressionTest::Test4062486(void)
1377 UErrorCode status
= U_ZERO_ERROR
;
1378 DecimalFormat
*fmt
= new DecimalFormat(UnicodeString("#,##0.00"), status
);
1379 failure(status
, "new DecimalFormat");
1380 UnicodeString formatted
;
1381 FieldPosition
field(0);
1382 double num
= 1234.5;
1383 fmt
->format(num
, formatted
, field
);
1384 if (field
.getBeginIndex() != 0 && field
.getEndIndex() != 5)
1385 errln(UnicodeString("Format 1234.5 failed. Begin index: ") /*+ field.getBeginIndex() + " End index: " + field.getEndIndex()*/);
1386 field
.setBeginIndex(7);
1387 field
.setEndIndex(4);
1388 if (field
.getBeginIndex() != 7 && field
.getEndIndex() != 4)
1389 errln("Set begin/end field indexes failed. Begin index: " /*+ field.getBeginIndex() + " End index: " + field.getEndIndex()*/);
1395 * DecimalFormat.parse incorrectly works with a group separator.
1397 void NumberFormatRegressionTest::Test4108738(void)
1399 UErrorCode status
= U_ZERO_ERROR
;
1400 DecimalFormatSymbols
*syms
= new DecimalFormatSymbols(Locale::getUS(), status
);
1401 failure(status
, "new DecimalFormatSymbols");
1402 DecimalFormat
*df
= new DecimalFormat("#,##0.###", syms
, status
);
1403 if(U_FAILURE(status
)) {
1404 errcheckln(status
, "Error creating DecimalFormat: %s", u_errorName(status
));
1408 failure(status
, "new DecimalFormat");
1409 UnicodeString
text("1.222,111");
1411 ParsePosition
pp(0);
1412 df
->parse(text
, num
, pp
);
1414 // {sfb} how to do this (again) ?
1415 // shouldn't just be another round-trip test, should it?
1417 FieldPosition
pos(FieldPosition::DONT_CARE
);
1418 temp
= df
->format(num
.getDouble(), temp
, pos
);
1419 //if (!num.toString().equals("1.222"))
1420 if (temp
!= UnicodeString("1.222"))
1421 //errln("\"" + text + "\" is parsed as " + num);
1422 errln("\"" + text
+ "\" is parsed as " + temp
);
1423 text
= UnicodeString("1.222x111");
1424 pp
= ParsePosition(0);
1425 df
->parse(text
, num
, pp
);
1427 temp
= df
->format(num
.getDouble(), temp
, pos
);
1428 //if (!num.toString().equals("1.222"))
1429 if (temp
!= UnicodeString("1.222"))
1430 errln("\"" + text
+ "\" is parsed as " + temp
);
1436 * DecimalFormat.format() incorrectly formats negative doubles.
1438 void NumberFormatRegressionTest::Test4106658(void)
1440 UErrorCode status
= U_ZERO_ERROR
;
1441 DecimalFormat
*df
= new DecimalFormat(status
); // Corrected; see 4147706
1442 if(U_FAILURE(status
)) {
1443 errcheckln(status
, "Error creating DecimalFormat: %s", u_errorName(status
));
1447 failure(status
, "new DecimalFormat");
1448 volatile double d1
= 0.0; // volatile to prevent code optimization
1449 double d2
= -0.0001;
1450 UnicodeString buffer
;
1452 FieldPosition
pos(FieldPosition::DONT_CARE
);
1455 d1
= 0.0 * -1.0; // old HPUX compiler ignores volatile keyword
1457 d1
*= -1.0; // Some compilers have a problem with defining -0.0
1459 logln("pattern: \"" + df
->toPattern(temp
) + "\"");
1460 df
->format(d1
, buffer
, pos
);
1461 if (buffer
!= UnicodeString("-0")) // Corrected; see 4147706
1462 errln(UnicodeString("") + d1
+ " is formatted as " + buffer
);
1464 df
->format(d2
, buffer
, pos
);
1465 if (buffer
!= UnicodeString("-0")) // Corrected; see 4147706
1466 errln(UnicodeString("") + d2
+ " is formatted as " + buffer
);
1472 * DecimalFormat.parse returns 0 if string parameter is incorrect.
1474 void NumberFormatRegressionTest::Test4106662(void)
1476 UErrorCode status
= U_ZERO_ERROR
;
1477 DecimalFormat
*df
= new DecimalFormat(status
);
1478 if(U_FAILURE(status
)) {
1479 errcheckln(status
, "Error creating DecimalFormat: %s", u_errorName(status
));
1483 failure(status
, "new DecimalFormat");
1484 UnicodeString
text("x");
1485 ParsePosition
pos1(0), pos2(0);
1488 logln("pattern: \"" + df
->toPattern(temp
) + "\"");
1490 df
->parse(text
, num
, pos1
);
1491 if (pos1
== ParsePosition(0)/*num != null*/) {
1492 errln(UnicodeString("Test Failed: \"") + text
+ "\" is parsed as " /*+ num*/);
1495 df
= new DecimalFormat(UnicodeString("$###.00"), status
);
1496 failure(status
, "new DecimalFormat");
1497 df
->parse(UnicodeString("$"), num
, pos2
);
1498 if (pos2
== ParsePosition(0) /*num != null*/){
1499 errln(UnicodeString("Test Failed: \"$\" is parsed as ") /*+ num*/);
1505 /* @bug 4114639 (duplicate of 4106662)
1506 * NumberFormat.parse doesn't return null
1508 void NumberFormatRegressionTest::Test4114639(void)
1510 UErrorCode status
= U_ZERO_ERROR
;
1511 NumberFormat
*format
= NumberFormat::createInstance(status
);
1512 if(U_FAILURE(status
)) {
1513 dataerrln("Error creating DecimalFormat: %s", u_errorName(status
));
1517 failure(status
, "NumberFormat::createInstance");
1518 UnicodeString
text("time 10:x");
1519 ParsePosition
pos(8);
1521 format
->parse(text
, result
, pos
);
1522 if (/*result != null*/pos
.getErrorIndex() != 8)
1523 errln(UnicodeString("Should return null but got : ") /*+ result*/); // Should be null; it isn't
1529 * TODO: this test does not work because we need to use a 64 bit number and a
1530 * a double only MAY only have 52 bits of precision.
1531 * DecimalFormat.format(long n) fails if n * multiplier > MAX_LONG.
1533 void NumberFormatRegressionTest::Test4106664(void)
1535 UErrorCode status
= U_ZERO_ERROR
;
1536 DecimalFormat
*df
= new DecimalFormat(status
);
1537 if(U_FAILURE(status
)) {
1538 errcheckln(status
, "Error creating DecimalFormat: %s", u_errorName(status
));
1542 failure(status
, "new DecimalFormat");
1543 // {sfb} long in java is 64 bits
1544 /*long*/double n
= 1234567890123456.0;
1545 /*int*/int32_t m
= 12345678;
1546 // {sfb} will this work?
1547 //BigInteger bigN = BigInteger.valueOf(n);
1548 //bigN = bigN.multiply(BigInteger.valueOf(m));
1549 double bigN
= n
* m
;
1550 df
->setMultiplier(m
);
1551 df
->setGroupingUsed(FALSE
);
1553 FieldPosition
pos(FieldPosition::DONT_CARE
);
1554 logln("formated: " +
1555 df
->format(n
, temp
, pos
));
1558 sprintf(buf
, "%g", bigN
);
1559 //logln("expected: " + bigN.toString());
1560 logln(UnicodeString("expected: ") + buf
);
1564 /* @bug 4106667 (duplicate of 4106658)
1565 * DecimalFormat.format incorrectly formats -0.0.
1567 void NumberFormatRegressionTest::Test4106667(void)
1569 UErrorCode status
= U_ZERO_ERROR
;
1570 DecimalFormat
*df
= new DecimalFormat(status
);
1571 if(U_FAILURE(status
)) {
1572 errcheckln(status
, "Error creating DecimalFormat: %s", u_errorName(status
));
1576 failure(status
, "new DecimalFormat");
1577 UChar foo
[] = { 0x002B };
1578 UnicodeString
bar(foo
, 1, 1);
1579 volatile double d
= 0.0; // volatile to prevent code optimization
1581 UnicodeString buffer
;
1582 FieldPosition
pos(FieldPosition::DONT_CARE
);
1584 logln("pattern: \"" + df
->toPattern(temp
) + "\"");
1586 d
= 0.0 * -1.0; // old HPUX compiler ignores volatile keyword
1588 d
*= -1.0; // Some compilers have a problem with defining -0.0
1590 df
->setPositivePrefix(/*"+"*/bar
);
1591 df
->format(d
, buffer
, pos
);
1592 if (buffer
!= UnicodeString("-0")) // Corrected; see 4147706
1593 errln(/*d + */UnicodeString(" is formatted as ") + buffer
);
1599 * DecimalFormat.setMaximumIntegerDigits() works incorrectly.
1602 # define MAX_INT_DIGITS 70
1604 # define MAX_INT_DIGITS 128
1607 void NumberFormatRegressionTest::Test4110936(void)
1609 UErrorCode status
= U_ZERO_ERROR
;
1610 NumberFormat
*nf
= NumberFormat::createInstance(status
);
1611 if(U_FAILURE(status
)) {
1612 dataerrln("Error creating DecimalFormat: %s", u_errorName(status
));
1616 failure(status
, "NumberFormat::createInstance");
1617 nf
->setMaximumIntegerDigits(MAX_INT_DIGITS
);
1618 logln("setMaximumIntegerDigits(MAX_INT_DIGITS)");
1619 if (nf
->getMaximumIntegerDigits() != MAX_INT_DIGITS
)
1620 errln("getMaximumIntegerDigits() returns " +
1621 nf
->getMaximumIntegerDigits());
1627 * Locale data should use generic currency symbol
1629 * 1) Make sure that all currency formats use the generic currency symbol.
1630 * 2) Make sure we get the same results using the generic symbol or a
1633 void NumberFormatRegressionTest::Test4122840(void)
1636 const Locale
*locales
= Locale::getAvailableLocales(count
);
1638 for (int i
= 0; i
< count
; i
++) {
1639 UErrorCode status
= U_ZERO_ERROR
;
1640 ResourceBundle
*rb
= new ResourceBundle(
1641 NULL
/*"java.text.resources.LocaleElements"*/,
1642 locales
[i
], status
);
1643 failure(status
, "new ResourceBundle");
1644 ResourceBundle numPat
= rb
->getWithFallback("NumberElements", status
);
1645 failure(status
, "rb.get(NumberElements)");
1646 numPat
= numPat
.getWithFallback("latn",status
);
1647 failure(status
, "rb.get(latn)");
1648 numPat
= numPat
.getWithFallback("patterns",status
);
1649 failure(status
, "rb.get(patterns)");
1650 numPat
= numPat
.getWithFallback("currencyFormat",status
);
1651 failure(status
, "rb.get(currencyFormat)");
1653 // Get the currency pattern for this locale. We have to fish it
1654 // out of the ResourceBundle directly, since DecimalFormat.toPattern
1655 // will return the localized symbol, not \00a4
1657 UnicodeString pattern
= numPat
.getString(status
);
1658 failure(status
, "rb->getString()");
1660 UChar fo
[] = { 0x00A4 };
1661 UnicodeString
foo(fo
, 1, 1);
1663 //if (pattern.indexOf("\u00A4") == -1 ) {
1664 if (pattern
.indexOf(foo
) == -1 ) {
1665 errln(UnicodeString("Currency format for ") + UnicodeString(locales
[i
].getName()) +
1666 " does not contain generic currency symbol:" +
1670 // Create a DecimalFormat using the pattern we got and format a number
1671 DecimalFormatSymbols
*symbols
= new DecimalFormatSymbols(locales
[i
], status
);
1672 failure(status
, "new DecimalFormatSymbols");
1673 DecimalFormat
*fmt1
= new DecimalFormat(pattern
, *symbols
, status
);
1674 failure(status
, "new DecimalFormat");
1676 UnicodeString result1
;
1677 FieldPosition
pos(FieldPosition::DONT_CARE
);
1678 result1
= fmt1
->format(1.111, result1
, pos
);
1681 // Now substitute in the locale's currency symbol and create another
1682 // pattern. We have to skip locales where the currency symbol
1683 // contains decimal separators, because that confuses things
1685 UChar ba
[] = { 0x002E/*'.'*/ };
1686 UnicodeString
bar(ba
, 1, 1);
1688 if (symbols
->getSymbol(DecimalFormatSymbols::kCurrencySymbol
).indexOf(bar
) == -1) {
1689 // {sfb} Also, switch the decimal separator to the monetary decimal
1690 // separator to mimic the behavior of a currency format
1691 symbols
->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
,
1692 symbols
->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
));
1694 UnicodeString
buf(pattern
);
1695 for (int j
= 0; j
< buf
.length(); j
++) {
1696 if (buf
[j
] == 0x00a4 ) {
1697 if(buf
[j
+ 1] == 0x00a4) {
1698 // {sfb} added to support double currency marker (intl currency sign)
1699 buf
.replace(j
, /*j+*/2, symbols
->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
));
1700 j
+= symbols
->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
).length();
1703 buf
.replace(j
, /*j+*/1, symbols
->getSymbol(DecimalFormatSymbols::kCurrencySymbol
));
1704 j
+= symbols
->getSymbol(DecimalFormatSymbols::kCurrencySymbol
).length() - 1;
1709 DecimalFormat
*fmt2
= new DecimalFormat(buf
, *symbols
, status
);
1710 failure(status
, "new DecimalFormat");
1712 // Get the currency (if there is one) so we can set the rounding and fraction
1713 const UChar
*currency
= fmt1
->getCurrency();
1714 if (*currency
!= 0) {
1715 double rounding
= ucurr_getRoundingIncrement(currency
, &status
);
1716 int32_t frac
= ucurr_getDefaultFractionDigits(currency
, &status
);
1717 if (U_SUCCESS(status
)) {
1718 fmt2
->setRoundingIncrement(rounding
);
1719 fmt2
->setMinimumFractionDigits(frac
);
1720 fmt2
->setMaximumFractionDigits(frac
);
1723 failure(status
, "Fetching currency rounding/fractions");
1727 UnicodeString result2
;
1728 fmt2
->format(1.111, result2
, pos
);
1730 if (result1
!= result2
) {
1731 errln("Results for " + (UnicodeString
)(locales
[i
].getName()) + " differ: " +
1732 result1
+ " vs " + result2
);
1745 * DecimalFormat.format() delivers wrong string.
1747 void NumberFormatRegressionTest::Test4125885(void)
1749 UErrorCode status
= U_ZERO_ERROR
;
1750 double rate
= 12.34;
1751 DecimalFormat
*formatDec
= new DecimalFormat ("000.00", status
);
1752 if(U_FAILURE(status
)) {
1753 errcheckln(status
, "Error creating DecimalFormat: %s", u_errorName(status
));
1757 failure(status
, "new DecimalFormat");
1759 logln("toPattern: " + formatDec
->toPattern(temp
));
1760 UnicodeString rateString
;
1761 FieldPosition
pos(FieldPosition::DONT_CARE
);
1762 rateString
= formatDec
->format(rate
, rateString
, pos
);
1763 if (rateString
!= UnicodeString("012.34"))
1764 errln("result : " + rateString
+ " expected : 012.34");
1766 delete formatDec
;// = null;
1767 formatDec
= new DecimalFormat ("+000.00%;-000.00%", status
);
1768 failure(status
, "new DecimalFormat");
1769 logln("toPattern: " + formatDec
->toPattern(temp
));
1770 rateString
.remove();
1771 rateString
= formatDec
->format(rate
, rateString
, pos
);
1772 if (rateString
!= UnicodeString("+012.34%"))
1773 errln("result : " + rateString
+ " expected : +012.34%");
1780 * DecimalFormat produces extra zeros when formatting numbers.
1782 void NumberFormatRegressionTest::Test4134034(void)
1784 UErrorCode status
= U_ZERO_ERROR
;
1785 DecimalFormat
*nf
= new DecimalFormat("##,###,###.00", status
);
1786 if (!failure(status
, "new DecimalFormat")) {
1788 FieldPosition
pos(FieldPosition::DONT_CARE
);
1789 f
= nf
->format(9.02, f
, pos
);
1790 if (f
== UnicodeString("9.02"))
1793 errln("9.02 -> " + f
+ "; want 9.02");
1796 f
= nf
->format((int32_t)0, f
, pos
);
1797 if (f
== UnicodeString(".00"))
1800 errln("0 -> " + f
+ "; want .00");
1808 * CANNOT REPRODUCE - This bug could not be reproduced. It may be
1809 * a duplicate of 4134034.
1811 * JDK 1.1.6 Bug, did NOT occur in 1.1.5
1812 * Possibly related to bug 4125885.
1814 * This class demonstrates a regression in version 1.1.6
1815 * of DecimalFormat class.
1818 * Value 1.2 Format #.00 Result '01.20' !!!wrong
1819 * Value 1.2 Format 0.00 Result '001.20' !!!wrong
1820 * Value 1.2 Format 00.00 Result '0001.20' !!!wrong
1821 * Value 1.2 Format #0.0# Result '1.2'
1822 * Value 1.2 Format #0.00 Result '001.20' !!!wrong
1825 * Value 1.2 Format #.00 Result '1.20'
1826 * Value 1.2 Format 0.00 Result '1.20'
1827 * Value 1.2 Format 00.00 Result '01.20'
1828 * Value 1.2 Format #0.0# Result '1.2'
1829 * Value 1.2 Format #0.00 Result '1.20'
1831 void NumberFormatRegressionTest::Test4134300(void) {
1832 UnicodeString DATA
[] = {
1833 // Pattern Expected string
1834 UnicodeString("#.00"), UnicodeString("1.20"),
1835 UnicodeString("0.00"), UnicodeString("1.20"),
1836 UnicodeString("00.00"), UnicodeString("01.20"),
1837 UnicodeString("#0.0#"), UnicodeString("1.2"),
1838 UnicodeString("#0.00"), UnicodeString("1.20")
1841 for (int i
=0; i
< 10; i
+=2) {
1842 UnicodeString result
;
1843 UErrorCode status
= U_ZERO_ERROR
;
1844 DecimalFormat
*df
= new DecimalFormat(DATA
[i
], status
);
1845 if (!failure(status
, "new DecimalFormat")) {
1846 FieldPosition
pos(FieldPosition::DONT_CARE
);
1847 result
= df
->format(1.2, result
, pos
);
1848 if (result
!= DATA
[i
+1]) {
1849 errln("Fail: 1.2 x " + DATA
[i
] + " = " + result
+
1850 "; want " + DATA
[i
+1]);
1853 logln("Ok: 1.2 x " + DATA
[i
] + " = " + result
);
1863 * Empty pattern produces double negative prefix.
1865 void NumberFormatRegressionTest::Test4140009(void)
1867 UErrorCode status
= U_ZERO_ERROR
;
1868 DecimalFormatSymbols
*syms
= new DecimalFormatSymbols(Locale::getEnglish(), status
);
1869 failure(status
, "new DecimalFormatSymbols");
1870 DecimalFormat
*f
= new DecimalFormat(UnicodeString(""), syms
, status
);
1871 if (!failure(status
, "new DecimalFormat")) {
1873 FieldPosition
pos(FieldPosition::DONT_CARE
);
1874 s
= f
->format(123.456, s
, pos
);
1875 if (s
!= UnicodeString("123.456"))
1876 errln("Fail: Format empty pattern x 123.456 => " + s
);
1878 s
= f
->format(-123.456, s
, pos
);
1879 if (s
!= UnicodeString("-123.456"))
1880 errln("Fail: Format empty pattern x -123.456 => " + s
);
1887 * BigDecimal numbers get their fractions truncated by NumberFormat.
1889 // {sfb} not pertinent in C++ ??
1890 void NumberFormatRegressionTest::Test4141750(void) {
1892 UnicodeString str("12345.67");
1893 BigDecimal bd = new BigDecimal(str);
1894 String sd = NumberFormat.getInstance(Locale.US).format(bd);
1895 if (!sd.endsWith("67")) errln("Fail: " + str + " x format -> " + sd);
1897 catch (Exception e) {
1898 errln(e.toString());
1899 e.printStackTrace();
1905 * DecimalFormat toPattern() doesn't quote special characters or handle
1908 void NumberFormatRegressionTest::Test4145457() {
1910 UErrorCode status
= U_ZERO_ERROR
;
1911 NumberFormat
*nff
= NumberFormat::createInstance(status
);
1912 if (failure(status
, "NumberFormat::createInstance", TRUE
)){
1916 DecimalFormat
*nf
= dynamic_cast<DecimalFormat
*>(nff
);
1918 errln("DecimalFormat needed to continue");
1922 DecimalFormatSymbols
*sym
= (DecimalFormatSymbols
*) nf
->getDecimalFormatSymbols();
1923 sym
->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
, (UChar
)/*'\''*/0x0027);
1924 nf
->setDecimalFormatSymbols(*sym
);
1925 double pi
= 3.14159;
1927 UnicodeString PATS
[] = {
1928 UnicodeString("#.00 'num''ber'"), UnicodeString("''#.00''")
1931 for (int32_t i
=0; i
<2; ++i
) {
1932 nf
->applyPattern(PATS
[i
], status
);
1933 failure(status
, "nf->applyPattern");
1935 FieldPosition
pos(FieldPosition::DONT_CARE
);
1936 out
= nf
->format(pi
, out
, pos
);
1938 pat
= nf
->toPattern(pat
);
1940 ParsePosition
pp(0);
1941 nf
->parse(out
, num
, pp
);
1942 double val
= num
.getDouble();
1944 nf
->applyPattern(pat
, status
);
1945 failure(status
, "nf->applyPattern");
1947 out2
= nf
->format(pi
, out2
, pos
);
1949 pat2
= nf
->toPattern(pat2
);
1951 nf
->parse(out2
, num
, pp
);
1952 double val2
= num
.getDouble();
1955 errln("Fail with \"" + PATS
[i
] + "\": Patterns should concur, \"" +
1956 pat
+ "\" vs. \"" + pat2
+ "\"");
1958 logln("Ok \"" + PATS
[i
] + "\" toPattern() -> \"" + pat
+ '"');
1960 if (val
== val2
&& out
== out2
) {
1961 logln(UnicodeString("Ok ") + pi
+ " x \"" + PATS
[i
] + "\" -> \"" +
1962 out
+ "\" -> " + val
+ " -> \"" +
1963 out2
+ "\" -> " + val2
);
1966 errln(UnicodeString("Fail ") + pi
+ " x \"" + PATS
[i
] + "\" -> \"" +
1967 out
+ "\" -> " + val
+ " -> \"" +
1968 out2
+ "\" -> " + val2
);
1972 catch (ParseException e) {
1973 errln("Fail: " + e);
1974 e.printStackTrace();
1982 * DecimalFormat.applyPattern() sets minimum integer digits incorrectly.
1984 * This bug is a duplicate of 4139344, which is a duplicate of 4134300
1986 void NumberFormatRegressionTest::Test4147295(void)
1988 UErrorCode status
= U_ZERO_ERROR
;
1989 DecimalFormat
*sdf
= new DecimalFormat(status
);
1990 UnicodeString
pattern("#,###");
1991 logln("Applying pattern \"" + pattern
+ "\"");
1992 sdf
->applyPattern(pattern
, status
);
1993 if (!failure(status
, "sdf->applyPattern")) {
1994 int minIntDig
= sdf
->getMinimumIntegerDigits();
1995 if (minIntDig
!= 0) {
1996 errln("Test failed");
1997 errln(" Minimum integer digits : " + minIntDig
);
1999 errln(" new pattern: " + sdf
->toPattern(temp
));
2001 logln("Test passed");
2002 logln(" Minimum integer digits : " + minIntDig
);
2010 * DecimalFormat formats -0.0 as +0.0
2011 * See also older related bug 4106658, 4106667
2013 void NumberFormatRegressionTest::Test4147706(void)
2015 UErrorCode status
= U_ZERO_ERROR
;
2016 DecimalFormat
*df
= new DecimalFormat("#,##0.0##", status
);
2017 failure(status
, "new DecimalFormat");
2018 DecimalFormatSymbols
*syms
= new DecimalFormatSymbols(Locale::getEnglish(), status
);
2019 if (!failure(status
, "new DecimalFormatSymbols")) {
2021 UnicodeString f2
, temp
;
2022 FieldPosition
pos(FieldPosition::DONT_CARE
);
2023 volatile double d1
= 0.0; // volatile to prevent code optimization
2024 double d2
= -0.0001;
2027 d1
= 0.0 * -1.0; // old HPUX compiler ignores volatile keyword
2029 d1
*= -1.0; // Some compilers have a problem with defining -0.0
2031 df
->adoptDecimalFormatSymbols(syms
);
2032 f1
= df
->format(d1
, f1
, pos
);
2033 f2
= df
->format(d2
, f2
, pos
);
2034 if (f1
!= UnicodeString("-0.0")) {
2035 errln(UnicodeString("") + d1
+ UnicodeString(" x \"") + df
->toPattern(temp
) + "\" is formatted as \"" + f1
+ '"');
2037 if (f2
!= UnicodeString("-0.0")) {
2038 errln(UnicodeString("") + d2
+ UnicodeString(" x \"") + df
->toPattern(temp
) + "\" is formatted as \"" + f2
+ '"');
2046 // Not applicable, since no serialization in C++
2047 /*class myformat implements Serializable
2049 DateFormat _dateFormat = DateFormat.getDateInstance();
2053 GregorianCalendar calendar = new GregorianCalendar();
2054 Date t = calendar.getTime();
2055 String nowStr = _dateFormat.format(t);
2062 * NumberFormat cannot format Double.MAX_VALUE
2064 // TODO: make this test actually test something
2066 NumberFormatRegressionTest::Test4162198(void)
2068 // for some reason, DBL_MAX will not round trip. (bug in sprintf/atof)
2069 double dbl
= INT32_MAX
* 1000.0;
2070 UErrorCode status
= U_ZERO_ERROR
;
2071 NumberFormat
*f
= NumberFormat::createInstance(status
);
2072 if(U_FAILURE(status
)) {
2073 dataerrln("Couldn't create number format - %s", u_errorName(status
));
2076 f
->setMaximumFractionDigits(INT32_MAX
);
2077 f
->setMaximumIntegerDigits(INT32_MAX
);
2080 logln(UnicodeString("The number ") + dbl
+ " formatted to " + s
);
2083 f
->parse(s
, n
, status
);
2084 if(U_FAILURE(status
))
2085 errln("Couldn't parse!");
2086 //} catch (java.text.ParseException e) {
2087 // errln("Caught a ParseException:");
2088 // e.printStackTrace();
2091 //logln("The string " + s + " parsed as " + n);
2093 // {dlf} The old code assumes n is a double, but it isn't any more...
2094 // Formattable apparently does not and never did interconvert... too bad.
2095 //if(n.getDouble() != dbl) {
2096 // errln("Round trip failure");
2098 if (n
.getInt64() != dbl
) {
2099 errln("Round trip failure");
2107 * NumberFormat does not parse negative zero.
2110 NumberFormatRegressionTest::Test4162852(void)
2112 UErrorCode status
= U_ZERO_ERROR
;
2113 for(int32_t i
=0; i
< 2; ++i
) {
2114 NumberFormat
*f
= (i
== 0) ? NumberFormat::createInstance(status
)
2115 : NumberFormat::createPercentInstance(status
);
2116 if(U_FAILURE(status
)) {
2117 dataerrln("Couldn't create number format - %s", u_errorName(status
));
2125 f
->parse(s
, n
, status
);
2126 if(U_FAILURE(status
))
2127 errln("Couldn't parse!");
2128 double e
= n
.getDouble();
2129 logln(UnicodeString("") +
2131 '"' + s
+ '"' + " -> " + e
);
2132 #if (defined(OS390) && !defined(IEEE_754)) || defined(OS400)
2135 if (e
!= 0.0 || 1.0/e
> 0.0) {
2137 logln("Failed to parse negative zero");
2143 static double _u_abs(double a
) { return a
<0?-a
:a
; }
2146 * May 17 1999 sync up - liu
2148 * NumberFormat truncates data
2150 void NumberFormatRegressionTest::Test4167494(void) {
2151 UErrorCode status
= U_ZERO_ERROR
;
2152 NumberFormat
*fmt
= NumberFormat::createInstance(Locale::getUS(), status
);
2153 if (failure(status
, "NumberFormat::createInstance", TRUE
)){
2158 double a
= DBL_MAX
* 0.99; // DBL_MAX itself overflows to +Inf
2162 fmt
->parse(s
, num
, status
);
2163 failure(status
, "Parse");
2164 if (num
.getType() == Formattable::kDouble
&&
2165 _u_abs(num
.getDouble() - a
) / a
< 0.01) { // RT within 1%
2166 logln(UnicodeString("") + a
+ " -> \"" + s
+ "\" -> " +
2167 toString(num
) + " ok");
2169 errln(UnicodeString("") + a
+ " -> \"" + s
+ "\" -> " +
2170 toString(num
) + " FAIL");
2173 // We don't test Double.MIN_VALUE because the locale data for the US
2174 // currently doesn't specify enough digits to display Double.MIN_VALUE.
2175 // This is correct for now; however, we leave this here as a reminder
2176 // in case we want to address this later.
2182 * May 17 1999 sync up - liu
2184 * DecimalFormat.parse() fails when ParseIntegerOnly set to true
2186 void NumberFormatRegressionTest::Test4170798(void) {
2187 UErrorCode status
= U_ZERO_ERROR
;
2188 NumberFormat
*nf
= NumberFormat::createInstance(Locale::getUS(), status
);
2189 if (failure(status
, "NumberFormat::createInstance", TRUE
)){
2193 DecimalFormat
*df
= dynamic_cast<DecimalFormat
*>(nf
);
2195 errln("DecimalFormat needed to continue");
2198 df
->setParseIntegerOnly(TRUE
);
2200 ParsePosition
pos(0);
2201 df
->parse("-0.0", n
, pos
);
2202 if (n
.getType() != Formattable::kLong
2203 || n
.getLong() != 0) {
2204 errln(UnicodeString("FAIL: parse(\"-0.0\") returns ") + toString(n
));
2210 * May 17 1999 sync up - liu
2211 * toPattern only puts the first grouping separator in.
2213 void NumberFormatRegressionTest::Test4176114(void) {
2214 const char* DATA
[] = {
2216 "000", "#000", // No grouping
2217 "#000", "#000", // No grouping
2221 "00,000", "#00,000",
2222 "000,000", "#,000,000",
2223 "0,000,000,000,000.0000", "#0,000,000,000,000.0000", // Reported
2225 int DATA_length
= (int)(sizeof(DATA
) / sizeof(DATA
[0]));
2226 UErrorCode status
= U_ZERO_ERROR
;
2228 for (int i
=0; i
<DATA_length
; i
+=2) {
2229 DecimalFormat
df(DATA
[i
], status
);
2230 if (!failure(status
, "DecimalFormat constructor")) {
2232 UnicodeString
exp(DATA
[i
+1]);
2234 errln(UnicodeString("FAIL: ") + DATA
[i
] + " -> " +
2235 s
+ ", want " + exp
);
2242 * May 17 1999 sync up - liu
2244 * DecimalFormat is incorrectly rounding numbers like 1.2501 to 1.2
2246 void NumberFormatRegressionTest::Test4179818(void) {
2247 const char* DATA
[] = {
2248 // Input Pattern Expected output
2249 "1.2511", "#.#", "1.3",
2250 "1.2501", "#.#", "1.3",
2253 int DATA_length
= (int)(sizeof(DATA
) / sizeof(DATA
[0]));
2259 UErrorCode status
= U_ZERO_ERROR
;
2260 DecimalFormatSymbols
sym(Locale::getUS(), status
);
2261 failure(status
, "Construct DecimalFormatSymbols");
2262 DecimalFormat
fmt("#", sym
, status
);
2263 if (!failure(status
, "Construct DecimalFormat")) {
2264 for (int i
=0; i
<DATA_length
; i
+=3) {
2265 double in
= DOUBLE
[i
/3];
2266 UnicodeString
pat(DATA
[i
+1]);
2267 UnicodeString
exp(DATA
[i
+2]);
2268 fmt
.applyPattern(pat
, status
);
2269 failure(status
, "applyPattern");
2272 fmt
.format(in
, out
, pos
);
2274 logln(UnicodeString("Ok: ") + in
+ " x " + pat
+ " = " + out
);
2276 errln(UnicodeString("FAIL: ") + in
+ " x " + pat
+ " = " + out
+
2277 ", expected " + exp
);
2284 * May 17 1999 sync up - liu
2285 * Some DecimalFormatSymbols changes are not picked up by DecimalFormat.
2286 * This includes the minus sign, currency symbol, international currency
2287 * symbol, percent, and permille. This is filed as bugs 4212072 and
2290 void NumberFormatRegressionTest::Test4212072(void) {
2291 UErrorCode status
= U_ZERO_ERROR
;
2292 DecimalFormatSymbols
sym(Locale::getUS(), status
);
2294 failure(status
, "DecimalFormatSymbols ct", Locale::getUS());
2295 DecimalFormat
fmt(UnicodeString("#"), sym
, status
);
2296 if(failure(status
, "DecimalFormat ct", Locale::getUS())) {
2303 sym
.setSymbol(DecimalFormatSymbols::kMinusSignSymbol
, (UChar
)0x5e);
2304 fmt
.setDecimalFormatSymbols(sym
);
2306 if (fmt
.format((int32_t)-1, s
, pos
) != UNICODE_STRING("^1", 2)) {
2307 errln(UnicodeString("FAIL: -1 x (minus=^) -> ") + s
+
2311 if (fmt
.getNegativePrefix(s
) != UnicodeString((UChar
)0x5e)) {
2312 errln(UnicodeString("FAIL: (minus=^).getNegativePrefix -> ") +
2315 sym
.setSymbol(DecimalFormatSymbols::kMinusSignSymbol
, (UChar
)0x2d);
2317 fmt
.applyPattern(UnicodeString("#%"), status
);
2318 failure(status
, "applyPattern percent");
2319 sym
.setSymbol(DecimalFormatSymbols::kPercentSymbol
, (UChar
)0x5e);
2320 fmt
.setDecimalFormatSymbols(sym
);
2322 if (fmt
.format(0.25, s
, pos
) != UNICODE_STRING("25^", 3)) {
2323 errln(UnicodeString("FAIL: 0.25 x (percent=^) -> ") + s
+
2327 if (fmt
.getPositiveSuffix(s
) != UnicodeString((UChar
)0x5e)) {
2328 errln(UnicodeString("FAIL: (percent=^).getPositiveSuffix -> ") +
2331 sym
.setSymbol(DecimalFormatSymbols::kPercentSymbol
, (UChar
)0x25);
2333 fmt
.applyPattern(str("#\\u2030"), status
);
2334 failure(status
, "applyPattern permill");
2335 sym
.setSymbol(DecimalFormatSymbols::kPerMillSymbol
, (UChar
)0x5e);
2336 fmt
.setDecimalFormatSymbols(sym
);
2338 if (fmt
.format(0.25, s
, pos
) != UNICODE_STRING("250^", 4)) {
2339 errln(UnicodeString("FAIL: 0.25 x (permill=^) -> ") + s
+
2343 if (fmt
.getPositiveSuffix(s
) != UnicodeString((UChar
)0x5e)) {
2344 errln(UnicodeString("FAIL: (permill=^).getPositiveSuffix -> ") +
2347 sym
.setSymbol(DecimalFormatSymbols::kPerMillSymbol
, (UChar
)0x2030);
2349 fmt
.applyPattern(str("\\u00A4#.00"), status
);
2350 failure(status
, "applyPattern currency");
2351 sym
.setSymbol(DecimalFormatSymbols::kCurrencySymbol
, "usd");
2352 fmt
.setDecimalFormatSymbols(sym
);
2354 if (fmt
.format(12.5, s
, pos
) != UnicodeString("usd12.50")) {
2355 errln(UnicodeString("FAIL: 12.5 x (currency=usd) -> ") + s
+
2359 if (fmt
.getPositivePrefix(s
) != UnicodeString("usd")) {
2360 errln(UnicodeString("FAIL: (currency=usd).getPositivePrefix -> ") +
2363 sym
.setSymbol(DecimalFormatSymbols::kCurrencySymbol
, "$");
2365 fmt
.applyPattern(str("\\u00A4\\u00A4#.00"), status
);
2366 failure(status
, "applyPattern intl currency");
2367 sym
.setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
, "DOL");
2368 fmt
.setDecimalFormatSymbols(sym
);
2370 if (fmt
.format(12.5, s
, pos
) != UnicodeString("DOL12.50")) {
2371 errln(UnicodeString("FAIL: 12.5 x (intlcurrency=DOL) -> ") + s
+
2375 if (fmt
.getPositivePrefix(s
) != UnicodeString("DOL")) {
2376 errln(UnicodeString("FAIL: (intlcurrency=DOL).getPositivePrefix -> ") +
2379 sym
.setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
, "USD");
2381 // Since the pattern logic has changed, make sure that patterns round
2382 // trip properly. Test stream in/out integrity too.
2384 const Locale
* avail
= NumberFormat::getAvailableLocales(n
);
2385 static const char* type
[] = {
2390 for (int i
=0; i
<n
; ++i
) {
2391 for (int j
=0; j
<3; ++j
) {
2392 status
= U_ZERO_ERROR
;
2396 nf
= NumberFormat::createInstance(avail
[i
], status
);
2397 failure(status
, "createInstance", avail
[i
]);
2400 nf
= NumberFormat::createCurrencyInstance(avail
[i
], status
);
2401 failure(status
, "createCurrencyInstance", avail
[i
]);
2404 nf
= NumberFormat::createPercentInstance(avail
[i
], status
);
2405 failure(status
, "createPercentInstance", avail
[i
]);
2408 if (U_FAILURE(status
)) {
2411 DecimalFormat
*df
= (DecimalFormat
*) nf
;
2413 // Test toPattern/applyPattern round trip
2416 DecimalFormatSymbols
symb(avail
[i
], status
);
2417 failure(status
, "Construct DecimalFormatSymbols", avail
[i
]);
2418 DecimalFormat
f2(pat
, symb
, status
);
2420 UnicodeString("Construct DecimalFormat(") + pat
+ ")")) {
2425 errln(UnicodeString("FAIL: ") + type
[j
] + avail
[i
].getDisplayName(l
) +
2427 "\" -> \"" + f2
.toPattern(p
) + "\"");
2430 logln(UnicodeString("PASS: ") + type
[j
] + avail
[i
].getDisplayName(l
) +
2435 // Test toLocalizedPattern/applyLocalizedPattern round trip
2436 df
->toLocalizedPattern(pat
);
2437 f2
.applyLocalizedPattern(pat
, status
);
2439 UnicodeString("applyLocalizedPattern(") + pat
+ ")", avail
[i
]);
2440 if (U_FAILURE(status
)) {
2444 // Make sure we set the currency attributes appropriately
2445 if (j
== 1) { // Currency format
2446 f2
.setCurrency(f2
.getCurrency(), status
);
2449 UnicodeString("setCurrency() for (") + pat
+ ")", avail
[i
]);
2450 if (U_FAILURE(status
)) {
2456 errln(UnicodeString("FAIL: ") + type
[j
] + avail
[i
].getDisplayName(l
) +
2457 " -> localized \"" + pat
+
2458 "\" -> \"" + f2
.toPattern(p
) + "\"");
2463 // Test writeObject/readObject round trip
2464 // NOT ON ICU -- Java only
2470 * May 17 1999 sync up - liu
2471 * DecimalFormat.parse() fails for mulipliers 2^n.
2473 void NumberFormatRegressionTest::Test4216742(void) {
2474 UErrorCode status
= U_ZERO_ERROR
;
2475 DecimalFormat
*fmt
= (DecimalFormat
*) NumberFormat::createInstance(Locale::getUS(), status
);
2476 if (failure(status
, "createInstance", Locale::getUS(), TRUE
)){
2480 int32_t DATA
[] = { INT32_MIN
, INT32_MAX
, -100000000, 100000000 };
2481 int DATA_length
= (int)(sizeof(DATA
) / sizeof(DATA
[0]));
2482 for (int i
=0; i
<DATA_length
; ++i
) {
2483 UnicodeString
str((UnicodeString
)"" + DATA
[i
]);
2484 for (int m
= 1; m
<= 100; m
++) {
2485 fmt
->setMultiplier(m
);
2487 fmt
->parse(str
, num
, status
);
2488 failure(status
, "parse", Locale::getUS());
2489 if (num
.getType() != Formattable::kLong
&&
2490 num
.getType() != Formattable::kDouble
) {
2491 errln(UnicodeString("FAIL: Wanted number, got ") +
2494 double d
= num
.getType() == Formattable::kDouble
?
2495 num
.getDouble() : (double) num
.getLong();
2496 if ((d
> 0) != (DATA
[i
] > 0)) {
2497 errln(UnicodeString("\"") + str
+ "\" parse(x " +
2498 fmt
->getMultiplier() +
2499 ") => " + toString(num
));
2508 * May 17 1999 sync up - liu
2509 * DecimalFormat formats 1.001 to "1.00" instead of "1" with 2 fraction
2512 void NumberFormatRegressionTest::Test4217661(void) {
2513 const double D
[] = { 0.001, 1.001, 0.006, 1.006 };
2514 const char* S
[] = { "0", "1", "0.01", "1.01" };
2515 int D_length
= (int)(sizeof(D
) / sizeof(D
[0]));
2516 UErrorCode status
= U_ZERO_ERROR
;
2517 NumberFormat
*fmt
= NumberFormat::createInstance(Locale::getUS(), status
);
2518 if (failure(status
, "createInstance", Locale::getUS(), TRUE
)){
2522 fmt
->setMaximumFractionDigits(2);
2523 for (int i
=0; i
<D_length
; i
++) {
2525 fmt
->format(D
[i
], s
);
2526 if (s
!= UnicodeString(S
[i
])) {
2527 errln(UnicodeString("FAIL: Got ") + s
+ ", exp " + S
[i
]);
2534 * alphaWorks upgrade
2536 void NumberFormatRegressionTest::Test4161100(void) {
2537 UErrorCode status
= U_ZERO_ERROR
;
2538 NumberFormat
*nf
= NumberFormat::createInstance(Locale::getUS(), status
);
2539 if (failure(status
, "createInstance", Locale::getUS(), TRUE
)){
2543 nf
->setMinimumFractionDigits(1);
2544 nf
->setMaximumFractionDigits(1);
2549 logln(UnicodeString() + a
+ " x " +
2550 ((DecimalFormat
*) nf
)->toPattern(pat
) + " = " + s
);
2551 if (s
!= UnicodeString("-0.1")) {
2558 * June 16 1999 sync up - liu
2559 * Formatting .5 rounds to "1" instead of "0". (Regression in 1.2.2 RC1)
2561 void NumberFormatRegressionTest::Test4243011(void) {
2562 UErrorCode status
= U_ZERO_ERROR
;
2563 DecimalFormatSymbols
sym(Locale::getUS(), status
);
2564 failure(status
, "DecimalFormatSymbols ct", Locale::getUS());
2565 DecimalFormat
fmt(UnicodeString("0."), sym
, status
);
2567 if (!failure(status
, "DecimalFormat ct", Locale::getUS())) {
2568 const double NUM
[] = { -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5 };
2569 const char* STR
[] = { "-2.", "-2.", "-0.", "0.", "2.", "2.", "4.", "4." };
2570 int32_t N
= (int32_t)(sizeof(NUM
) / sizeof(NUM
[0]));
2572 for (int32_t i
=0; i
<N
; ++i
) {
2574 UnicodeString
exp(STR
[i
]);
2576 fmt
.format(NUM
[i
], str
, pos
);
2578 logln(UnicodeString("Ok ") + NUM
[i
] + " x 0. = " + str
);
2580 errln(UnicodeString("FAIL ") + NUM
[i
] + " x 0. = " + str
+
2588 * June 16 1999 sync up - liu
2589 * format(0.0) gives "0.1" if preceded by parse("99.99").
2590 * (Regression in 1.2.2 RC1)
2592 void NumberFormatRegressionTest::Test4243108(void) {
2593 UErrorCode status
= U_ZERO_ERROR
;
2594 DecimalFormatSymbols
sym(Locale::getUS(), status
);
2595 failure(status
, "DecimalFormatSymbols ct", Locale::getUS());
2596 DecimalFormat
fmt(UnicodeString("#.#"), sym
, status
);
2597 if (failure(status
, "DecimalFormat ct", Locale::getUS())) {
2604 fmt
.format(0.0, str
, pos
);
2605 UnicodeString
exp("0");
2607 logln(UnicodeString("Ok 0.0 x #.# = ") + str
);
2609 errln(UnicodeString("FAIL 0.0 x #.# = ") + str
+
2615 fmt
.parse(str
, val
, status
);
2616 failure(status
, "DecimalFormat.parse(99.99)", Locale::getUS());
2617 if (val
.getType() == Formattable::kDouble
&&
2618 val
.getDouble() == 99.99) {
2619 logln(UnicodeString("Ok 99.99 / #.# = ") + toString(val
));
2621 errln(UnicodeString("FAIL 99.99 / #.# = ") + toString(val
) +
2626 fmt
.format(0.0, str
, pos
);
2628 logln(UnicodeString("Ok 0.0 x #.# = ") + str
);
2630 errln(UnicodeString("FAIL 0.0 x #.# = ") + str
+
2637 * DateFormat should call setIntegerParseOnly(TRUE) on adopted
2638 * NumberFormat objects.
2640 void NumberFormatRegressionTest::TestJ691(void) {
2641 UErrorCode status
= U_ZERO_ERROR
;
2642 Locale
loc("fr", "CH");
2644 // set up the input date string & expected output
2645 UnicodeString
udt("11.10.2000", "");
2646 UnicodeString
exp("11.10.00", "");
2648 // create a Calendar for this locale
2649 Calendar
*cal
= Calendar::createInstance(loc
, status
);
2650 if (U_FAILURE(status
)) {
2651 dataerrln("FAIL: Calendar::createInstance() returned " + (UnicodeString
)u_errorName(status
));
2655 // create a NumberFormat for this locale
2656 NumberFormat
*nf
= NumberFormat::createInstance(loc
, status
);
2657 if (U_FAILURE(status
)) {
2658 dataerrln("FAIL: NumberFormat::createInstance() returned " + (UnicodeString
)u_errorName(status
));
2662 // *** Here's the key: We don't want to have to do THIS:
2663 // nf->setParseIntegerOnly(TRUE);
2665 // create the DateFormat
2666 DateFormat
*df
= DateFormat::createDateInstance(DateFormat::kShort
, loc
);
2667 if (U_FAILURE(status
)) {
2668 errln("FAIL: DateFormat::createInstance() returned " + (UnicodeString
)u_errorName(status
));
2672 df
->adoptCalendar(cal
);
2673 df
->adoptNumberFormat(nf
);
2675 // set parsing to lenient & parse
2676 df
->setLenient(TRUE
);
2677 UDate ulocdat
= df
->parse(udt
, status
);
2679 // format back to a string
2680 UnicodeString outString
;
2681 df
->format(ulocdat
, outString
);
2683 if (outString
!= exp
) {
2684 errln("FAIL: " + udt
+ " => " + outString
);
2690 //---------------------------------------------------------------------------
2692 // Error Checking / Reporting macros
2694 //---------------------------------------------------------------------------
2695 #define TEST_CHECK_STATUS(status) \
2696 if (U_FAILURE(status)) {\
2697 errln("File %s, Line %d. status=%s\n", __FILE__, __LINE__, u_errorName(status));\
2701 #define TEST_ASSERT(expr) \
2702 if ((expr)==FALSE) {\
2703 errln("File %s, line %d: Assertion Failed: " #expr "\n", __FILE__, __LINE__);\
2707 // Ticket 8199: Parse failure for numbers in the range of 1E10 - 1E18
2709 void NumberFormatRegressionTest::Test8199(void) {
2710 UErrorCode status
= U_ZERO_ERROR
;
2711 NumberFormat
*nf
= NumberFormat::createInstance(Locale::getEnglish(), status
);
2712 TEST_CHECK_STATUS(status
);
2714 // Note: Retrieving parsed values from a Formattable as a reduced-precision type
2715 // should always truncate, no other rounding scheme.
2717 UnicodeString numStr
= "1000000000.6"; // 9 zeroes
2719 nf
->parse(numStr
, val
, status
);
2720 TEST_CHECK_STATUS(status
);
2721 TEST_ASSERT(Formattable::kDouble
== val
.getType());
2722 TEST_ASSERT(1000000000 == val
.getInt64(status
));
2723 TEST_CHECK_STATUS(status
);
2724 TEST_ASSERT(1000000000.6 == val
.getDouble(status
));
2725 TEST_CHECK_STATUS(status
);
2727 numStr
= "100000000000000001.1"; // approx 1E17, parses as a double rather
2728 // than int64 because of the fraction
2729 // even though int64 is more precise.
2730 nf
->parse(numStr
, val
, status
);
2731 TEST_CHECK_STATUS(status
);
2732 TEST_ASSERT(Formattable::kDouble
== val
.getType());
2733 TEST_ASSERT(100000000000000001LL == val
.getInt64(status
));
2734 TEST_CHECK_STATUS(status
);
2735 TEST_ASSERT(100000000000000000.0 == val
.getDouble(status
));
2736 TEST_CHECK_STATUS(status
);
2738 numStr
= "1E17"; // Parses with the internal decimal number having non-zero exponent
2739 nf
->parse(numStr
, val
, status
);
2740 TEST_CHECK_STATUS(status
);
2741 TEST_ASSERT(Formattable::kInt64
== val
.getType());
2742 TEST_ASSERT(100000000000000000LL == val
.getInt64());
2743 TEST_ASSERT(1.0E17
== val
.getDouble(status
));
2744 TEST_CHECK_STATUS(status
);
2746 numStr
= "9223372036854775807"; // largest int64_t
2747 nf
->parse(numStr
, val
, status
);
2748 TEST_CHECK_STATUS(status
);
2749 TEST_ASSERT(Formattable::kInt64
== val
.getType());
2750 TEST_ASSERT(9223372036854775807LL == val
.getInt64());
2751 // In the following check, note that a substantial range of integers will
2752 // convert to the same double value. There are also platform variations
2753 // in the rounding at compile time of double constants.
2754 TEST_ASSERT(9223372036854775808.0 >= val
.getDouble(status
));
2755 TEST_ASSERT(9223372036854774700.0 <= val
.getDouble(status
));
2756 TEST_CHECK_STATUS(status
);
2758 numStr
= "-9223372036854775808"; // smallest int64_t
2759 nf
->parse(numStr
, val
, status
);
2760 TEST_CHECK_STATUS(status
);
2761 TEST_ASSERT(Formattable::kInt64
== val
.getType());
2762 // TEST_ASSERT(-9223372036854775808LL == val.getInt64()); // Compiler chokes on constant.
2763 TEST_ASSERT((int64_t)0x8000000000000000LL
== val
.getInt64());
2764 TEST_ASSERT(-9223372036854775808.0 == val
.getDouble(status
));
2765 TEST_CHECK_STATUS(status
);
2767 numStr
= "9223372036854775808"; // largest int64_t + 1
2768 nf
->parse(numStr
, val
, status
);
2769 TEST_CHECK_STATUS(status
);
2770 TEST_ASSERT(Formattable::kDouble
== val
.getType());
2771 TEST_ASSERT(9223372036854775807LL == val
.getInt64(status
));
2772 TEST_ASSERT(status
== U_INVALID_FORMAT_ERROR
);
2773 status
= U_ZERO_ERROR
;
2774 TEST_ASSERT(9223372036854775810.0 == val
.getDouble(status
));
2775 TEST_CHECK_STATUS(status
);
2777 numStr
= "-9223372036854775809"; // smallest int64_t - 1
2778 nf
->parse(numStr
, val
, status
);
2779 TEST_CHECK_STATUS(status
);
2780 TEST_ASSERT(Formattable::kDouble
== val
.getType());
2781 // TEST_ASSERT(-9223372036854775808LL == val.getInt64(status)); // spurious compiler warnings
2782 TEST_ASSERT((int64_t)0x8000000000000000LL
== val
.getInt64(status
));
2783 TEST_ASSERT(status
== U_INVALID_FORMAT_ERROR
);
2784 status
= U_ZERO_ERROR
;
2785 TEST_ASSERT(-9223372036854775810.0 == val
.getDouble(status
));
2786 TEST_CHECK_STATUS(status
);
2788 // Test values near the limit of where doubles can represent all integers.
2789 // The implementation strategy of getInt64() changes at this boundary.
2790 // Strings to be parsed include a decimal fraction to force them to be
2791 // parsed as doubles rather than ints. The fraction is discarded
2792 // from the parsed double value because it is beyond what can be represented.
2794 status
= U_ZERO_ERROR
;
2795 numStr
= "9007199254740991.1"; // largest 53 bit int
2796 nf
->parse(numStr
, val
, status
);
2797 TEST_CHECK_STATUS(status
);
2798 // printf("getInt64() returns %lld\n", val.getInt64(status));
2799 TEST_ASSERT(Formattable::kDouble
== val
.getType());
2800 TEST_ASSERT(9007199254740991LL == val
.getInt64(status
));
2801 TEST_ASSERT(9007199254740991.0 == val
.getDouble(status
));
2802 TEST_CHECK_STATUS(status
);
2804 status
= U_ZERO_ERROR
;
2805 numStr
= "9007199254740992.1"; // 54 bits for the int part.
2806 nf
->parse(numStr
, val
, status
);
2807 TEST_CHECK_STATUS(status
);
2808 TEST_ASSERT(Formattable::kDouble
== val
.getType());
2809 TEST_ASSERT(9007199254740992LL == val
.getInt64(status
));
2810 TEST_ASSERT(9007199254740992.0 == val
.getDouble(status
));
2811 TEST_CHECK_STATUS(status
);
2813 status
= U_ZERO_ERROR
;
2814 numStr
= "9007199254740993.1"; // 54 bits for the int part. Double will round
2815 nf
->parse(numStr
, val
, status
); // the ones digit, putting it up to ...994
2816 TEST_CHECK_STATUS(status
);
2817 TEST_ASSERT(Formattable::kDouble
== val
.getType());
2818 TEST_ASSERT(9007199254740993LL == val
.getInt64(status
));
2819 TEST_ASSERT(9007199254740994.0 == val
.getDouble(status
));
2820 TEST_CHECK_STATUS(status
);
2826 #endif /* #if !UCONFIG_NO_FORMATTING */