1 /********************************************************************
3 * Copyright (c) 1997-2003, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ********************************************************************/
7 #include "unicode/utypes.h"
9 #if !UCONFIG_NO_FORMATTING
13 #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 int32_t gMyNumberFormatTestClassID
;
22 UClassID
MyNumberFormatTest::getDynamicClassID() const
24 return (UClassID
)&gMyNumberFormatTestClassID
;
28 // *****************************************************************************
29 // class NumberFormatRegressionTest
30 // *****************************************************************************
32 #define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break
35 NumberFormatRegressionTest::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* /*par*/ )
37 // if (exec) logln((UnicodeString)"TestSuite NumberFormatRegressionTest");
101 default: name
= ""; break;
106 NumberFormatRegressionTest::failure(UErrorCode status
, const UnicodeString
& msg
)
108 if(U_FAILURE(status
)) {
109 errln(UnicodeString("FAIL: ", "") + msg
110 + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status
), ""));
118 * Convert Java-style strings with \u Unicode escapes into UnicodeString objects
120 inline UnicodeString
str(const char *input
)
122 return CharsToUnicodeString(input
);
126 * NumberFormat.equals comparing with null should always return false.
128 // {sfb} kind of silly in C++, just checking for new success
129 void NumberFormatRegressionTest::Test4075713(void)
132 MyNumberFormatTest
*tmp
= new MyNumberFormatTest();
134 logln("NumberFormat.equals passed");
135 /*} catch (NullPointerException e) {
136 errln("(new MyNumberFormatTest()).equals(null) throws unexpected exception");
143 * NumberFormat.equals comparing two obj equal even the setGroupingUsed
146 void NumberFormatRegressionTest::Test4074620(void)
149 MyNumberFormatTest
*nf1
= new MyNumberFormatTest();
150 MyNumberFormatTest
*nf2
= new MyNumberFormatTest();
152 nf1
->setGroupingUsed(FALSE
);
153 nf2
->setGroupingUsed(TRUE
);
156 errln("Test for bug 4074620 failed");
158 logln("Test for bug 4074620 passed.");
166 * DecimalFormat.format() incorrectly uses maxFractionDigits setting.
169 void NumberFormatRegressionTest::Test4088161 (void)
171 UErrorCode status
= U_ZERO_ERROR
;
172 DecimalFormat
*df
= new DecimalFormat(status
);
173 failure(status
, "new DecimalFormat");
175 df
->setMinimumFractionDigits(0);
176 df
->setMaximumFractionDigits(16);
178 FieldPosition
fp1(0);
179 logln(UnicodeString("d = ") + d
);
180 logln("maxFractionDigits = " + df
->getMaximumFractionDigits());
182 logln(" format(d) = '" + df
->format(d
, sBuf1
, fp1
) + "'");
183 df
->setMaximumFractionDigits(17);
185 FieldPosition
fp2(0);
186 logln("maxFractionDigits = " + df
->getMaximumFractionDigits());
187 sBuf2
= df
->format(d
, sBuf2
, fp2
);
189 errln(" format(d) = '" + sBuf2
+ "'");
195 * DecimalFormatSymbols should be cloned in the ctor DecimalFormat.
196 * DecimalFormat(String, DecimalFormatSymbols).
198 void NumberFormatRegressionTest::Test4087245 (void)
200 UErrorCode status
= U_ZERO_ERROR
;
201 DecimalFormatSymbols
*symbols
= new DecimalFormatSymbols(status
);
202 failure(status
, "new DecimalFormatSymbols");
203 // {sfb} One note about this test: if you pass in a pointer
204 // to the symbols, they are adopted and this test will fail,
205 // even though that is the correct behavior. To test the cloning
206 // of the symbols, it is necessary to pass in a reference to the symbols
207 DecimalFormat
*df
= new DecimalFormat("#,##0.0", *symbols
, status
);
208 failure(status
, "new DecimalFormat with symbols");
212 FieldPosition
pos(FieldPosition::DONT_CARE
);
213 logln(UnicodeString("format(") + n
+ ") = " +
214 df
->format(n
, buf1
, pos
));
215 symbols
->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
, UnicodeString((UChar
)0x70)); // change value of field
216 logln(UnicodeString("format(") + n
+ ") = " +
217 df
->format(n
, buf2
, pos
));
219 errln("Test for bug 4087245 failed");
226 * DecimalFormat.format() incorrectly formats 0.0
228 void NumberFormatRegressionTest::Test4087535 (void)
230 UErrorCode status
= U_ZERO_ERROR
;
231 DecimalFormat
*df
= new DecimalFormat(status
);
232 failure(status
, "new DecimalFormat");
233 df
->setMinimumIntegerDigits(0);
236 UnicodeString buffer
;
237 FieldPosition
pos(FieldPosition::DONT_CARE
);
238 buffer
= df
->format(n
, buffer
, pos
);
239 if (buffer
.length() == 0)
240 errln(/*n + */": '" + buffer
+ "'");
242 buffer
= df
->format(n
, buffer
, pos
);
243 if (buffer
.length() == 0)
244 errln(/*n + */": '" + buffer
+ "'");
250 * DecimalFormat.format fails when groupingSize is set to 0.
252 // {sfb} how do I tell if this worked? --> FieldPosition doesn't change ??
253 void NumberFormatRegressionTest::Test4088503 (void)
255 UErrorCode status
= U_ZERO_ERROR
;
256 DecimalFormat
*df
= new DecimalFormat(status
);
257 failure(status
, "new DecimalFormat");
258 df
->setGroupingSize(0);
260 FieldPosition
fp(FieldPosition::DONT_CARE
);
262 logln(df
->format((int32_t)123, sBuf
, fp
));
263 //if(fp == FieldPosition(0))
264 // errln("Test for bug 4088503 failed.");
265 /*} catch (Exception foo) {
266 errln("Test for bug 4088503 failed.");
272 * NumberFormat.getCurrencyInstance is wrong.
274 void NumberFormatRegressionTest::Test4066646 (void)
276 assignFloatValue(2.04f
);
277 assignFloatValue(2.03f
);
278 assignFloatValue(2.02f
);
279 assignFloatValue(0.0f
);
283 NumberFormatRegressionTest::assignFloatValue(float returnfloat
)
285 logln(UnicodeString(" VALUE ") + returnfloat
);
286 UErrorCode status
= U_ZERO_ERROR
;
287 NumberFormat
*nfcommon
= NumberFormat::createCurrencyInstance(Locale::getUS(), status
);
288 failure(status
, "NumberFormat::createCurrencyInstance");
289 nfcommon
->setGroupingUsed(FALSE
);
291 UnicodeString stringValue
;
292 stringValue
= nfcommon
->format(returnfloat
, stringValue
);
293 logln(" DISPLAYVALUE " + stringValue
);
295 nfcommon
->parse(stringValue
, result
, status
);
296 failure(status
, "nfcommon->parse");
297 float floatResult
= (float) (result
.getType() == Formattable::kDouble
298 ? result
.getDouble() : result
.getLong());
299 if( uprv_fabs(floatResult
- returnfloat
) > 0.0001)
300 //String stringValue = nfcommon.format(returnfloat).substring(1);
301 //if (Float.valueOf(stringValue).floatValue() != returnfloat)
302 errln(UnicodeString("FAIL: expected ") + returnfloat
+ ", got " + floatResult
+ " (" + stringValue
+")");
306 } // End Of assignFloatValue()
309 * DecimalFormat throws exception when parsing "0"
311 void NumberFormatRegressionTest::Test4059870(void)
313 UErrorCode status
= U_ZERO_ERROR
;
314 DecimalFormat
*format
= new DecimalFormat("00", status
);
315 failure(status
, "new Decimalformat");
319 format
->parse(UnicodeString("0"), result
, status
);
320 failure(status
, "format->parse");
323 catch (Exception e) {
324 errln("Test for bug 4059870 failed : " + e);
330 * DecimalFormatSymbol.equals should always return false when
331 * comparing with null.
333 // {sfb} this is silly in C++
334 void NumberFormatRegressionTest::Test4083018 (void)
336 UErrorCode status
= U_ZERO_ERROR
;
337 DecimalFormatSymbols
*dfs
= new DecimalFormatSymbols(status
);
338 failure(status
, "new DecimalFormatSymbols");
341 logln("Test Passed!");
343 errln("Test for bug 4083018 failed");
344 /*} catch (Exception foo) {
345 errln("Test for bug 4083018 failed => Message : " + foo.getMessage());
352 * DecimalFormat does not round up correctly.
354 void NumberFormatRegressionTest::Test4071492 (void)
356 double x
= 0.00159999;
357 UErrorCode status
= U_ZERO_ERROR
;
358 NumberFormat
*nf
= NumberFormat::createInstance(status
);
359 failure(status
, "NumberFormat::createInstance");
360 nf
->setMaximumFractionDigits(4);
362 FieldPosition
pos(FieldPosition::DONT_CARE
);
363 out
= nf
->format(x
, out
, pos
);
364 logln("0.00159999 formats with 4 fractional digits to " + out
);
365 UnicodeString
expected("0.0016");
367 errln("FAIL: Expected " + expected
);
373 * A space as a group separator for localized pattern causes
374 * wrong format. WorkAround : use non-breaking space.
376 void NumberFormatRegressionTest::Test4086575(void)
378 UErrorCode status
= U_ZERO_ERROR
;
379 NumberFormat
*nf1
= NumberFormat::createInstance(Locale::getFrance(), status
);
381 // TODO: There is not a good way to find out that the creation of this number format has
382 // failed. Major rewiring of format construction proposed.
383 if(U_FAILURE(status
)) {
384 errln("Something is wrong with French number format - it should not fallback. Exitting");
388 failure(status
, "NumberFormat::createInstance");
390 // C++ workaround to make sure cast works
391 // Wouldn't dynamic_cast<DecimalFormat*> be great?
392 if(nf1
->getDynamicClassID() != DecimalFormat::getStaticClassID()) {
393 errln("NumberFormat::createInstance returned incorrect type.");
397 DecimalFormat
*nf
= (DecimalFormat
*) nf1
;
399 logln("nf toPattern1: " + nf
->toPattern(temp
));
400 logln("nf toLocPattern1: " + nf
->toLocalizedPattern(temp
));
402 // No group separator
403 logln("...applyLocalizedPattern ###,00;(###,00) ");
404 nf
->applyLocalizedPattern(UnicodeString("###,00;(###,00)"), status
);
405 failure(status
, "nf->applyLocalizedPattern");
406 logln("nf toPattern2: " + nf
->toPattern(temp
));
407 logln("nf toLocPattern2: " + nf
->toLocalizedPattern(temp
));
409 FieldPosition
pos(FieldPosition::DONT_CARE
);
410 logln("nf: " + nf
->format((int32_t)1234, temp
, pos
)); // 1234,00
411 logln("nf: " + nf
->format((int32_t)-1234, temp
, pos
)); // (1234,00)
413 // Space as group separator
415 logln("...applyLocalizedPattern # ###,00;(# ###,00) ");
417 //nf->applyLocalizedPattern("#\u00a0###,00;(#\u00a0###,00)");
419 0x23, 0x00a0, 0x23, 0x23, 0x23, 0x2c, 0x30, 0x30, 0x3b,
420 0x28, 0x23, 0x00a0, 0x23, 0x23, 0x23, 0x2c, 0x30, 0x30, 0x29
422 UnicodeString
pat(patChars
, 19, 19);
423 nf
->applyLocalizedPattern(pat
, status
);
424 failure(status
, "nf->applyLocalizedPattern");
425 logln("nf toPattern2: " + nf
->toPattern(temp
));
426 logln("nf toLocPattern2: " + nf
->toLocalizedPattern(temp
));
427 UnicodeString buffer
;
428 buffer
= nf
->format((int32_t)1234, buffer
, pos
);
429 //if (buffer != UnicodeString("1\u00a0234,00"))
431 0x31, 0x00a0, 0x32, 0x33, 0x34, 0x2c, 0x30, 0x30
433 UnicodeString
cc(c
, 8, 8);
435 errln("nf : " + buffer
); // Expect 1 234,00
438 buffer
= nf
->format((int32_t)-1234, buffer
, pos
);
440 0x28, 0x31, 0x00a0, 0x32, 0x33, 0x34, 0x2c, 0x30, 0x30, 0x29
442 UnicodeString
cc1(c1
, 10, 10);
444 errln("nf : " + buffer
); // Expect (1 234,00)
446 // Erroneously prints:
453 * DecimalFormat.parse returns wrong value
455 // {sfb} slightly converted into a round-trip test, since in C++
456 // there is no Double.toString()
457 void NumberFormatRegressionTest::Test4068693(void)
459 logln("----- Test Application -----");
460 ParsePosition
pos(0);
461 UErrorCode status
= U_ZERO_ERROR
;
462 DecimalFormat
*df
= new DecimalFormat(status
);
463 if(U_FAILURE(status
)) {
464 errln("Error creating DecimalFormat: %s", u_errorName(status
));
468 failure(status
, "new DecimalFormat");
470 //Double d = (Double)df.parse("123.55456", pos=new ParsePosition(0));
471 df
->parse(UnicodeString("123.55456"), d
, pos
);
472 //if (!d.toString().equals("123.55456")) {
474 df
->setMaximumFractionDigits(999);
475 df
->setMaximumIntegerDigits(999);
476 FieldPosition
fp(FieldPosition::DONT_CARE
);
477 dstr
= df
->format(d
.getDouble(), dstr
, fp
);
478 if (dstr
!= UnicodeString("123.55456")) {
479 errln(UnicodeString("Result -> ") + d
.getDouble());
485 /* @bug 4069754, 4067878
486 * null pointer thrown when accessing a deserialized DecimalFormat
489 // {sfb} doesn't apply in C++
490 void NumberFormatRegressionTest::Test4069754(void)
493 myformat it = new myformat();
495 FileOutputStream ostream = new FileOutputStream("t.tmp");
496 ObjectOutputStream p = new ObjectOutputStream(ostream);
501 FileInputStream istream = new FileInputStream("t.tmp");
502 ObjectInputStream p2 = new ObjectInputStream(istream);
503 myformat it2 = (myformat)p2.readObject();
507 } catch (Exception foo) {
508 errln("Test for bug 4069754 or 4057878 failed => Exception: " + foo.getMessage());
513 * DecimalFormat.applyPattern(String) allows illegal patterns
515 void NumberFormatRegressionTest::Test4087251 (void)
517 UErrorCode status
= U_ZERO_ERROR
;
518 DecimalFormat
*df
= new DecimalFormat(status
);
519 if(U_FAILURE(status
)) {
520 errln("Error creating DecimalFormat: %s", u_errorName(status
));
524 failure(status
, "new DecimalFormat");
526 df
->applyPattern(UnicodeString("#.#.#"), status
);
527 if( ! U_FAILURE(status
))
528 errln("df->applyPattern with illegal pattern didn't fail");
530 logln("toPattern() returns \"" + df
->toPattern(temp
) + "\"");
531 //errln("applyPattern(\"#.#.#\") doesn't throw IllegalArgumentException");
532 /*} catch (IllegalArgumentException e) {
533 logln("Caught Illegal Argument Error !");
535 // Second test; added 5/11/98 when reported to fail on 1.2b3
537 df
->applyPattern("#0.0#0#0", status
);
538 if( ! U_FAILURE(status
))
539 errln("df->applyPattern with illegal pattern didn't fail");
540 logln("toPattern() returns \"" + df
->toPattern(temp
) + "\"");
541 //errln("applyPattern(\"#0.0#0#0\") doesn't throw IllegalArgumentException");
542 /*} catch (IllegalArgumentException e) {
543 logln("Ok - IllegalArgumentException for #0.0#0#0");
550 * DecimalFormat.format() loses precision
552 void NumberFormatRegressionTest::Test4090489 (void)
554 // {sfb} sprintf doesn't correctly handle the double, so there is nothing
555 // that NumberFormat can do. For some reason, it does not format the last 1.
557 /* UErrorCode status = U_ZERO_ERROR;
558 DecimalFormat *df = new DecimalFormat(status);
559 failure(status, "new DecimalFormat");
560 df->setMinimumFractionDigits(10);
561 df->setMaximumFractionDigits(999);
562 df->setGroupingUsed(FALSE);
563 double d = 1.000000000000001E7;
564 //BigDecimal bd = new BigDecimal(d);
567 logln(UnicodeString("d = ") + d);
568 //logln("BigDecimal.toString(): " + bd.toString());
569 df->format(d, sb, fp);
570 if (sb != "10000000.0000000100") {
571 errln("DecimalFormat.format(): " + sb);
577 * DecimalFormat.format() loses precision
579 void NumberFormatRegressionTest::Test4090504 (void)
582 logln(UnicodeString("d = ") + d
);
583 UErrorCode status
= U_ZERO_ERROR
;
584 DecimalFormat
*df
= new DecimalFormat(status
);
585 if(U_FAILURE(status
)) {
586 errln("Error creating DecimalFormat: %s", u_errorName(status
));
590 failure(status
, "new DecimalFormat");
592 FieldPosition
fp(FieldPosition::DONT_CARE
);
594 for (int i
= 17; i
<= 20; i
++) {
595 df
->setMaximumFractionDigits(i
);
596 //sb = new StringBuffer("");
598 logln(" getMaximumFractionDigits() = " + i
);
599 logln(" formated: " + df
->format(d
, sb
, fp
));
601 /*} catch (Exception foo) {
602 errln("Bug 4090504 regression test failed. Message : " + foo.getMessage());
608 * DecimalFormat.parse(String str, ParsePosition pp) loses precision
610 void NumberFormatRegressionTest::Test4095713 (void)
612 UErrorCode status
= U_ZERO_ERROR
;
613 DecimalFormat
*df
= new DecimalFormat(status
);
614 if(U_FAILURE(status
)) {
615 errln("Error creating DecimalFormat: %s", u_errorName(status
));
619 failure(status
, "new DecimalFOrmat");
620 UnicodeString
str("0.1234");
622 //Double d1 = new Double(str);
623 //Double d2 = (Double) df.parse(str, new ParsePosition(0));
626 df
->parse(str
, d2
, pp
);
627 logln(UnicodeString("") + d1
);
628 if (d2
.getDouble() != d1
)
629 errln(UnicodeString("Bug 4095713 test failed, new double value : ") + d2
.getDouble());
634 * DecimalFormat.parse() fails when multiplier is not set to 1
636 // {sfb} not sure what to do with this one
637 void NumberFormatRegressionTest::Test4092561 (void)
639 UErrorCode status
= U_ZERO_ERROR
;
640 DecimalFormat
*df
= new DecimalFormat(status
);
641 if(U_FAILURE(status
)) {
642 errln("Error creating DecimalFormat: %s", u_errorName(status
));
646 failure(status
, "new DecimalFormat");
648 // {sfb} going to cheat here and use sprintf ??
650 /*UnicodeString str = Long.toString(Long.MIN_VALUE);
651 logln("Long.MIN_VALUE : " + df.parse(str, new ParsePosition(0)).toString());
652 df.setMultiplier(100);
653 Number num = df.parse(str, new ParsePosition(0));
654 if (num.doubleValue() != -9.223372036854776E16)
655 errln("Bug 4092561 test failed when multiplier is set to not 1.");
661 * DecimalFormat: Negative format ignored.
663 void NumberFormatRegressionTest::Test4092480 (void)
665 UErrorCode status
= U_ZERO_ERROR
;
666 DecimalFormat
*dfFoo
= new DecimalFormat(UnicodeString("000"), status
);
667 if(U_FAILURE(status
)) {
668 errln("Error creating DecimalFormat: %s", u_errorName(status
));
672 failure(status
, "new DecimalFormat");
675 dfFoo
->applyPattern("0000;-000", status
);
676 failure(status
, "dfFoo->applyPattern");
678 if (dfFoo
->toPattern(temp
) != UnicodeString("#0000"))
679 errln("dfFoo.toPattern : " + dfFoo
->toPattern(temp
));
680 FieldPosition
pos(FieldPosition::DONT_CARE
);
681 logln(dfFoo
->format((int32_t)42, temp
, pos
));
682 logln(dfFoo
->format((int32_t)-42, temp
, pos
));
683 dfFoo
->applyPattern("000;-000", status
);
684 failure(status
, "dfFoo->applyPattern");
685 if (dfFoo
->toPattern(temp
) != UnicodeString("#000"))
686 errln("dfFoo.toPattern : " + dfFoo
->toPattern(temp
));
687 logln(dfFoo
->format((int32_t)42,temp
, pos
));
688 logln(dfFoo
->format((int32_t)-42, temp
, pos
));
690 dfFoo
->applyPattern("000;-0000", status
);
691 failure(status
, "dfFoo->applyPattern");
692 if (dfFoo
->toPattern(temp
) != UnicodeString("#000"))
693 errln("dfFoo.toPattern : " + dfFoo
->toPattern(temp
));
694 logln(dfFoo
->format((int32_t)42, temp
, pos
));
695 logln(dfFoo
->format((int32_t)-42, temp
, pos
));
697 dfFoo
->applyPattern("0000;-000", status
);
698 failure(status
, "dfFoo->applyPattern");
699 if (dfFoo
->toPattern(temp
) != UnicodeString("#0000"))
700 errln("dfFoo.toPattern : " + dfFoo
->toPattern(temp
));
701 logln(dfFoo
->format((int32_t)42, temp
, pos
));
702 logln(dfFoo
->format((int32_t)-42, temp
, pos
));
703 /*} catch (Exception foo) {
704 errln("Message " + foo.getMessage());
710 * NumberFormat.getCurrencyInstance() produces format that uses
711 * decimal separator instead of monetary decimal separator.
713 * Rewrote this test not to depend on the actual pattern. Pattern should
714 * never contain the monetary separator! Decimal separator in pattern is
715 * interpreted as monetary separator if currency symbol is seen!
717 void NumberFormatRegressionTest::Test4087244 (void) {
718 Locale
*de
= new Locale("pt","PT_PREEURO");
719 UErrorCode status
= U_ZERO_ERROR
;
720 NumberFormat
*nf
= NumberFormat::createCurrencyInstance(*de
, status
);
721 if(U_FAILURE(status
)) {
722 errln("Error creating DecimalFormat: %s", u_errorName(status
));
726 if (nf
->getDynamicClassID() != DecimalFormat::getStaticClassID()) {
727 errln("expected DecimalFormat!");
730 DecimalFormat
*df
= (DecimalFormat
*) nf
;
731 const DecimalFormatSymbols
*sym
= df
->getDecimalFormatSymbols();
732 UnicodeString decSep
= sym
->getSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
);
733 UnicodeString monSep
= sym
->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
);
734 if (decSep
== monSep
) {
735 errln("ERROR in test: want decimal sep != monetary sep");
738 df
->setMinimumIntegerDigits(1);
739 df
->setMinimumFractionDigits(2);
742 df
->format(1.23, str
, pos
);
743 UnicodeString
monStr("1x23");
744 monStr
.replace((int32_t)1, 1, monSep
);
745 UnicodeString
decStr("1x23");
746 decStr
.replace((int32_t)1, 1, decSep
);
747 if (str
.indexOf(monStr
) >= 0 && str
.indexOf(decStr
) < 0) {
748 logln(UnicodeString("OK: 1.23 -> \"") + str
+ "\" contains \"" +
749 monStr
+ "\" and not \"" + decStr
+ '"');
751 errln(UnicodeString("FAIL: 1.23 -> \"") + str
+ "\", should contain \"" +
753 "\" and not \"" + decStr
+ '"');
759 * Number format data rounding errors for locale FR
761 void NumberFormatRegressionTest::Test4070798 (void)
763 NumberFormat
*formatter
;
764 UnicodeString tempString
;
767 String expectedDefault = "-5\u00a0789,987";
768 String expectedCurrency = "5\u00a0789,98 F";
769 String expectedPercent = "-578\u00a0998%";
772 0x2d, 0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x38, 0x38
775 0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x39, 0x20, 0x46
778 0x2d, 0x35, 0x37, 0x38, 0x00a0, 0x39, 0x39, 0x39, 0x25
780 UnicodeString
expectedDefault(chars1
, 10, 10);
781 UnicodeString
expectedCurrency(chars2
, 10, 10);
782 UnicodeString
expectedPercent(chars3
, 9, 9);
784 UErrorCode status
= U_ZERO_ERROR
;
785 formatter
= NumberFormat::createInstance(Locale("fr_FR_PREEURO"), status
);
786 if(U_FAILURE(status
)) {
787 errln("Error creating DecimalFormat: %s", u_errorName(status
));
791 failure(status
, "NumberFormat::createNumberInstance");
792 tempString
= formatter
->format (-5789.9876, tempString
);
794 if (tempString
== expectedDefault
) {
795 logln ("Bug 4070798 default test passed.");
797 errln(UnicodeString("Failed:") +
798 " Expected " + expectedDefault
+
799 " Received " + tempString
);
803 formatter
= NumberFormat::createCurrencyInstance(Locale("fr_FR_PREEURO"), status
);
804 failure(status
, "NumberFormat::createCurrencyInstance");
806 tempString
= formatter
->format( 5789.9876, tempString
);
808 if (tempString
== expectedCurrency
) {
809 logln ("Bug 4070798 currency test passed.");
811 errln(UnicodeString("Failed:") +
812 " Expected " + expectedCurrency
+
813 " Received " + tempString
);
817 formatter
= NumberFormat::createPercentInstance(Locale("fr_FR_PREEURO"), status
);
818 failure(status
, "NumberFormat::createPercentInstance");
820 tempString
= formatter
->format (-5789.9876, tempString
);
822 if (tempString
== expectedPercent
) {
823 logln ("Bug 4070798 percentage test passed.");
825 errln(UnicodeString("Failed:") +
826 " Expected " + expectedPercent
+
827 " Received " + tempString
);
833 * Data rounding errors for French (Canada) locale
835 void NumberFormatRegressionTest::Test4071005 (void)
837 NumberFormat
*formatter
;
838 UnicodeString tempString
;
840 String expectedDefault = "-5\u00a0789,987";
841 String expectedCurrency = "5\u00a0789,98 $";
842 String expectedPercent = "-578\u00a0998%";
845 0x2d, 0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x38, 0x38
848 0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x39, 0x20, 0x24
851 0x2d, 0x35, 0x37, 0x38, 0x00a0, 0x39, 0x39, 0x39, 0x25
853 UnicodeString
expectedDefault(chars1
, 10, 10);
854 UnicodeString
expectedCurrency(chars2
, 10, 10);
855 UnicodeString
expectedPercent(chars3
, 9, 9);
857 UErrorCode status
= U_ZERO_ERROR
;
858 formatter
= NumberFormat::createInstance(Locale::getCanadaFrench(), status
);
859 failure(status
, "NumberFormat::createNumberInstance");
860 tempString
= formatter
->format (-5789.9876, tempString
);
862 if (tempString
== expectedDefault
) {
863 logln ("Bug 4071005 default test passed.");
865 errln(UnicodeString("Failed:") +
866 " Expected " + expectedDefault
+
867 " Received " + tempString
);
871 formatter
= NumberFormat::createCurrencyInstance(Locale::getCanadaFrench(), status
);
872 failure(status
, "NumberFormat::createCurrencyInstance");
874 tempString
= formatter
->format( 5789.9876, tempString
);
876 if (tempString
== expectedCurrency
) {
877 logln ("Bug 4071005 currency test assed.");
879 errln(UnicodeString("Failed:") +
880 " Expected " + expectedCurrency
+
881 " Received " + tempString
);
885 formatter
= NumberFormat::createPercentInstance(Locale::getCanadaFrench(), status
);
886 failure(status
, "NumberFormat::createPercentInstance");
888 tempString
= formatter
->format (-5789.9876, tempString
);
890 if (tempString
== expectedPercent
) {
891 logln ("Bug 4071005 percentage test passed.");
893 errln(UnicodeString("Failed:") +
894 " Expected " + expectedPercent
+
895 " Received " + tempString
);
902 * Data rounding errors for German (Germany) locale
904 void NumberFormatRegressionTest::Test4071014 (void)
906 NumberFormat
*formatter
;
907 UnicodeString tempString
;
909 String expectedDefault = "-5.789,987";
910 String expectedCurrency = "5.789,98 DM";
911 String expectedPercent = "-578.998%";
913 UnicodeString
expectedDefault("-5.789,988");
914 UnicodeString
expectedCurrency("5.789,99 DM");
915 UnicodeString
expectedPercent("-578.999%");
917 UErrorCode status
= U_ZERO_ERROR
;
918 formatter
= NumberFormat::createInstance(Locale("de_DE_PREEURO"), status
);
919 failure(status
, "NumberFormat::createNumberInstance");
921 tempString
= formatter
->format (-5789.9876, tempString
);
923 if (tempString
== expectedDefault
) {
924 logln ("Bug 4071014 default test passed.");
926 errln(UnicodeString("Failed:") +
927 " Expected " + expectedDefault
+
928 " Received " + tempString
);
932 formatter
= NumberFormat::createCurrencyInstance(Locale("de_DE_PREEURO"), status
);
933 failure(status
, "NumberFormat::createCurrencyInstance");
935 tempString
= formatter
->format( 5789.9876, tempString
);
937 if (tempString
== expectedCurrency
) {
938 logln ("Bug 4071014 currency test assed.");
940 errln(UnicodeString("Failed:") +
941 " Expected " + expectedCurrency
+
942 " Received " + tempString
);
946 formatter
= NumberFormat::createPercentInstance(Locale::getGermany(), status
);
947 failure(status
, "NumberFormat::createPercentInstance");
949 tempString
= formatter
->format (-5789.9876, tempString
);
951 if (tempString
== expectedPercent
) {
952 logln ("Bug 4071014 percentage test passed.");
954 errln(UnicodeString("Failed:") +
955 " Expected " + expectedPercent
+
956 " Received " + tempString
);
962 * Data rounding errors for Italian locale number formats
964 void NumberFormatRegressionTest::Test4071859 (void)
966 NumberFormat
*formatter
;
967 UnicodeString tempString
;
969 String expectedDefault = "-5.789,987";
970 String expectedCurrency = "-L. 5.789,98";
971 String expectedPercent = "-578.998%";
973 UnicodeString
expectedDefault("-5.789,988");
974 UnicodeString
expectedCurrency("-\\u20A4 5.790");
975 UnicodeString
expectedPercent("-578.999%");
976 expectedCurrency
= expectedCurrency
.unescape();
978 UErrorCode status
= U_ZERO_ERROR
;
979 formatter
= NumberFormat::createInstance(Locale("it_IT_PREEURO"), status
);
980 failure(status
, "NumberFormat::createNumberInstance");
981 tempString
= formatter
->format (-5789.9876, tempString
);
983 if (tempString
== expectedDefault
) {
984 logln ("Bug 4071859 default test passed.");
986 errln(UnicodeString("Failed:") +
987 " Expected " + expectedDefault
+
988 " Received " + tempString
);
992 formatter
= NumberFormat::createCurrencyInstance(Locale("it_IT_PREEURO"), status
);
993 failure(status
, "NumberFormat::createCurrencyInstance");
995 tempString
= formatter
->format( -5789.9876, tempString
);
997 if (tempString
== expectedCurrency
) {
998 logln ("Bug 4071859 currency test assed.");
1000 errln(UnicodeString("Failed:") +
1001 " Expected " + expectedCurrency
+
1002 " Received " + tempString
);
1006 formatter
= NumberFormat::createPercentInstance(Locale("it_IT_PREEURO"), status
);
1007 failure(status
, "NumberFormat::createPercentInstance");
1008 tempString
.remove();
1009 tempString
= formatter
->format (-5789.9876, tempString
);
1011 if (tempString
== expectedPercent
) {
1012 logln ("Bug 4071859 percentage test passed.");
1014 errln(UnicodeString("Failed:") +
1015 " Expected " + expectedPercent
+
1016 " Received " + tempString
);
1022 * Test rounding for nearest even.
1024 void NumberFormatRegressionTest::Test4093610(void)
1026 UErrorCode status
= U_ZERO_ERROR
;
1027 DecimalFormat
*df
= new DecimalFormat("#0.#", status
);
1028 failure(status
, "new DecimalFormat");
1029 UnicodeString
s("12.4");
1030 roundingTest(df
, 12.35, s
);
1031 roundingTest(df
, 12.45, s
);
1033 roundingTest(df
, 12.452,s
);
1035 roundingTest(df
, 12.55, s
);
1036 roundingTest(df
, 12.65, s
);
1038 roundingTest(df
, 12.652,s
);
1040 roundingTest(df
, 12.75, s
);
1041 roundingTest(df
, 12.752,s
);
1042 roundingTest(df
, 12.85, s
);
1044 roundingTest(df
, 12.852,s
);
1046 roundingTest(df
, 12.95, s
);
1047 roundingTest(df
, 12.952,s
);
1052 void NumberFormatRegressionTest::roundingTest(DecimalFormat
*df
, double x
, UnicodeString
& expected
)
1055 FieldPosition
pos(FieldPosition::DONT_CARE
);
1056 out
= df
->format(x
, out
, pos
);
1057 logln(UnicodeString("") + x
+ " formats with 1 fractional digits to " + out
);
1058 if (out
!= expected
)
1059 errln("FAIL: Expected " + expected
);
1062 * Tests the setMaximumFractionDigits limit.
1064 void NumberFormatRegressionTest::Test4098741(void)
1067 UErrorCode status
= U_ZERO_ERROR
;
1068 NumberFormat
*fmt
= NumberFormat::createPercentInstance(status
);
1069 fmt
->setMaximumFractionDigits(20);
1071 logln(fmt
->format(.001, temp
));
1072 /*} catch (Exception foo) {
1073 errln("Bug 4098471 failed with exception thrown : " + foo.getMessage());
1078 * Tests illegal pattern exception.
1079 * Fix comment : HShih A31 Part1 will not be fixed and javadoc needs to be updated.
1080 * Part2 has been fixed.
1082 void NumberFormatRegressionTest::Test4074454(void)
1085 UErrorCode status
= U_ZERO_ERROR
;
1086 DecimalFormat
*fmt
= new DecimalFormat("#,#00.00;-#.#", status
);
1087 if(U_FAILURE(status
)) {
1088 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1092 failure(status
, "new DecimalFormat");
1093 logln("Inconsistent negative pattern is fine.");
1094 DecimalFormat
*newFmt
= new DecimalFormat("#,#00.00 p''ieces;-#,#00.00 p''ieces", status
);
1095 failure(status
, "new DecimalFormat");
1096 UnicodeString tempString
;
1097 FieldPosition
pos(FieldPosition::DONT_CARE
);
1098 tempString
= newFmt
->format(3456.78, tempString
, pos
);
1099 if (tempString
!= UnicodeString("3,456.78 p'ieces"))
1100 errln("Failed! 3456.78 p'ieces expected, but got : " + tempString
);
1101 /*} catch (Exception foo) {
1102 errln("An exception was thrown for any inconsistent negative pattern.");
1109 * Tests all different comments.
1110 * Response to some comments :
1111 * [1] DecimalFormat.parse API documentation is more than just one line.
1112 * This is not a reproducable doc error in 116 source code.
1113 * [2] See updated javadoc.
1115 * [4] NumberFormat.parse(String, ParsePosition) : If parsing fails,
1116 * a null object will be returned. The unchanged parse position also
1117 * reflects an error.
1118 * NumberFormat.parse(String) : If parsing fails, an ParseException
1120 * See updated javadoc for more details.
1121 * [5] See updated javadoc.
1122 * [6] See updated javadoc.
1123 * [7] This is a correct behavior if the DateFormat object is linient.
1124 * Otherwise, an IllegalArgumentException will be thrown when formatting
1125 * "January 35". See GregorianCalendar class javadoc for more details.
1127 void NumberFormatRegressionTest::Test4099404(void)
1130 UErrorCode status
= U_ZERO_ERROR
;
1131 DecimalFormat
*fmt
= new DecimalFormat(UnicodeString("000.0#0"), status
);
1132 if(! U_FAILURE(status
))
1133 errln(UnicodeString("Bug 4099404 failed applying illegal pattern \"000.0#0\""));
1134 /*} catch (Exception foo) {
1135 logln("Bug 4099404 pattern \"000.0#0\" passed");
1140 fmt
= new DecimalFormat(UnicodeString("0#0.000"), status
);
1141 if( !U_FAILURE(status
))
1142 errln("Bug 4099404 failed applying illegal pattern \"0#0.000\"");
1143 /*} catch (Exception foo) {
1144 logln("Bug 4099404 pattern \"0#0.000\" passed");
1150 * DecimalFormat.applyPattern doesn't set minimum integer digits
1152 void NumberFormatRegressionTest::Test4101481(void)
1154 UErrorCode status
= U_ZERO_ERROR
;
1155 DecimalFormat
*sdf
= new DecimalFormat(UnicodeString("#,##0"), status
);
1156 if(U_FAILURE(status
)) {
1157 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1161 failure(status
, "new DecimalFormat");
1162 if (sdf
->getMinimumIntegerDigits() != 1)
1163 errln("Minimum integer digits : " + sdf
->getMinimumIntegerDigits());
1166 /* @bug 4052223 (API addition request A27)
1167 * Tests ParsePosition.setErrorPosition() and ParsePosition.getErrorPosition().
1169 void NumberFormatRegressionTest::Test4052223(void)
1172 UErrorCode status
= U_ZERO_ERROR
;
1173 DecimalFormat
*fmt
= new DecimalFormat(UnicodeString("#,#00.00"), status
);
1174 if(U_FAILURE(status
)) {
1175 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1179 failure(status
, "new DecimalFormat");
1181 fmt
->parse(UnicodeString("abc3"), num
, status
);
1182 if(! U_FAILURE(status
))
1183 errln(UnicodeString("Bug 4052223 failed : can't parse string \"a\". Got ") /*+ num*/);
1184 /*} catch (ParseException foo) {
1185 logln("Caught expected ParseException : " + foo.getMessage() + " at index : " + foo.getErrorOffset());
1190 * API tests for API addition request A9.
1192 void NumberFormatRegressionTest::Test4061302(void)
1194 UErrorCode status
= U_ZERO_ERROR
;
1195 DecimalFormatSymbols
*fmt
= new DecimalFormatSymbols(status
);
1196 failure(status
, "new DecimalFormatSymbols");
1197 UnicodeString
currency(fmt
->getSymbol(DecimalFormatSymbols::kCurrencySymbol
));
1198 UnicodeString
intlCurrency(fmt
->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
));
1199 UnicodeString
monDecSeparator(fmt
->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
));
1200 if (currency
== UnicodeString("") ||
1201 intlCurrency
== UnicodeString("") ||
1202 monDecSeparator
== UnicodeString(""))
1204 errln("getCurrencySymbols failed, got empty string.");
1206 UnicodeString monDecSeparatorStr
;
1207 monDecSeparatorStr
.append(monDecSeparator
);
1208 logln((UnicodeString
)"Before set ==> Currency : " + currency
+(UnicodeString
)" Intl Currency : " + intlCurrency
+ (UnicodeString
)" Monetary Decimal Separator : " + monDecSeparatorStr
);
1209 fmt
->setSymbol(DecimalFormatSymbols::kCurrencySymbol
, UnicodeString("XYZ"));
1210 fmt
->setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
, UnicodeString("ABC"));
1211 fmt
->setSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
, UnicodeString((UChar
)0x002A/*'*'*/));
1212 currency
= fmt
->getSymbol(DecimalFormatSymbols::kCurrencySymbol
);
1213 intlCurrency
= fmt
->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
);
1214 monDecSeparator
= fmt
->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
);
1215 if (currency
!= UnicodeString("XYZ") ||
1216 intlCurrency
!= UnicodeString("ABC") ||
1217 monDecSeparator
!= UnicodeString((UChar
)0x002A/*'*'*/)) {
1218 errln("setCurrencySymbols failed.");
1220 monDecSeparatorStr
.remove();
1221 monDecSeparatorStr
.append(monDecSeparator
);
1222 logln("After set ==> Currency : " + currency
+ " Intl Currency : " + intlCurrency
+ " Monetary Decimal Separator : " + monDecSeparatorStr
);
1227 * API tests for API addition request A23. FieldPosition.getBeginIndex and
1228 * FieldPosition.getEndIndex.
1230 void NumberFormatRegressionTest::Test4062486(void)
1232 UErrorCode status
= U_ZERO_ERROR
;
1233 DecimalFormat
*fmt
= new DecimalFormat(UnicodeString("#,##0.00"), status
);
1234 failure(status
, "new DecimalFormat");
1235 UnicodeString formatted
;
1236 FieldPosition
field(0);
1237 double num
= 1234.5;
1238 fmt
->format(num
, formatted
, field
);
1239 if (field
.getBeginIndex() != 0 && field
.getEndIndex() != 5)
1240 errln(UnicodeString("Format 1234.5 failed. Begin index: ") /*+ field.getBeginIndex() + " End index: " + field.getEndIndex()*/);
1241 field
.setBeginIndex(7);
1242 field
.setEndIndex(4);
1243 if (field
.getBeginIndex() != 7 && field
.getEndIndex() != 4)
1244 errln("Set begin/end field indexes failed. Begin index: " /*+ field.getBeginIndex() + " End index: " + field.getEndIndex()*/);
1250 * DecimalFormat.parse incorrectly works with a group separator.
1252 void NumberFormatRegressionTest::Test4108738(void)
1254 UErrorCode status
= U_ZERO_ERROR
;
1255 DecimalFormatSymbols
*syms
= new DecimalFormatSymbols(Locale::getUS(), status
);
1256 failure(status
, "new DecimalFormatSymbols");
1257 DecimalFormat
*df
= new DecimalFormat("#,##0.###", syms
, status
);
1258 if(U_FAILURE(status
)) {
1259 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1263 failure(status
, "new DecimalFormat");
1264 UnicodeString
text("1.222,111");
1266 ParsePosition
pp(0);
1267 df
->parse(text
, num
, pp
);
1269 // {sfb} how to do this (again) ?
1270 // shouldn't just be another round-trip test, should it?
1272 FieldPosition
pos(FieldPosition::DONT_CARE
);
1273 temp
= df
->format(num
.getDouble(), temp
, pos
);
1274 //if (!num.toString().equals("1.222"))
1275 if (temp
!= UnicodeString("1.222"))
1276 //errln("\"" + text + "\" is parsed as " + num);
1277 errln("\"" + text
+ "\" is parsed as " + temp
);
1278 text
= UnicodeString("1.222x111");
1279 pp
= ParsePosition(0);
1280 df
->parse(text
, num
, pp
);
1282 temp
= df
->format(num
.getDouble(), temp
, pos
);
1283 //if (!num.toString().equals("1.222"))
1284 if (temp
!= UnicodeString("1.222"))
1285 errln("\"" + text
+ "\" is parsed as " + temp
);
1291 * DecimalFormat.format() incorrectly formats negative doubles.
1293 void NumberFormatRegressionTest::Test4106658(void)
1295 UErrorCode status
= U_ZERO_ERROR
;
1296 DecimalFormat
*df
= new DecimalFormat(status
); // Corrected; see 4147706
1297 if(U_FAILURE(status
)) {
1298 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1302 failure(status
, "new DecimalFormat");
1303 volatile double d1
= 0.0; // volatile to prevent code optimization
1304 double d2
= -0.0001;
1305 UnicodeString buffer
;
1307 FieldPosition
pos(FieldPosition::DONT_CARE
);
1310 d1
= 0.0 * -1.0; // old HPUX compiler ignores volatile keyword
1312 d1
*= -1.0; // Some compilers have a problem with defining -0.0
1314 logln("pattern: \"" + df
->toPattern(temp
) + "\"");
1315 df
->format(d1
, buffer
, pos
);
1316 if (buffer
!= UnicodeString("-0")) // Corrected; see 4147706
1317 errln(UnicodeString("") + d1
+ " is formatted as " + buffer
);
1319 df
->format(d2
, buffer
, pos
);
1320 if (buffer
!= UnicodeString("-0")) // Corrected; see 4147706
1321 errln(UnicodeString("") + d2
+ " is formatted as " + buffer
);
1327 * DecimalFormat.parse returns 0 if string parameter is incorrect.
1329 void NumberFormatRegressionTest::Test4106662(void)
1331 UErrorCode status
= U_ZERO_ERROR
;
1332 DecimalFormat
*df
= new DecimalFormat(status
);
1333 if(U_FAILURE(status
)) {
1334 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1338 failure(status
, "new DecimalFormat");
1339 UnicodeString
text("x");
1340 ParsePosition
pos1(0), pos2(0);
1343 logln("pattern: \"" + df
->toPattern(temp
) + "\"");
1345 df
->parse(text
, num
, pos1
);
1346 if (pos1
== ParsePosition(0)/*num != null*/) {
1347 errln(UnicodeString("Test Failed: \"") + text
+ "\" is parsed as " /*+ num*/);
1350 df
= new DecimalFormat(UnicodeString("$###.00"), status
);
1351 failure(status
, "new DecimalFormat");
1352 df
->parse(UnicodeString("$"), num
, pos2
);
1353 if (pos2
== ParsePosition(0) /*num != null*/){
1354 errln(UnicodeString("Test Failed: \"$\" is parsed as ") /*+ num*/);
1360 /* @bug 4114639 (duplicate of 4106662)
1361 * NumberFormat.parse doesn't return null
1363 void NumberFormatRegressionTest::Test4114639(void)
1365 UErrorCode status
= U_ZERO_ERROR
;
1366 NumberFormat
*format
= NumberFormat::createInstance(status
);
1367 if(U_FAILURE(status
)) {
1368 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1372 failure(status
, "NumberFormat::createInstance");
1373 UnicodeString
text("time 10:x");
1374 ParsePosition
pos(8);
1376 format
->parse(text
, result
, pos
);
1377 if (/*result != null*/pos
.getErrorIndex() != 8)
1378 errln(UnicodeString("Should return null but got : ") /*+ result*/); // Should be null; it isn't
1384 * TODO: this test does not work because we need to use a 64 bit number and a
1385 * a double only MAY only have 52 bits of precision.
1386 * DecimalFormat.format(long n) fails if n * multiplier > MAX_LONG.
1388 void NumberFormatRegressionTest::Test4106664(void)
1390 UErrorCode status
= U_ZERO_ERROR
;
1391 DecimalFormat
*df
= new DecimalFormat(status
);
1392 if(U_FAILURE(status
)) {
1393 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1397 failure(status
, "new DecimalFormat");
1398 // {sfb} long in java is 64 bits
1399 /*long*/double n
= 1234567890123456.0;
1400 /*int*/int32_t m
= 12345678;
1401 // {sfb} will this work?
1402 //BigInteger bigN = BigInteger.valueOf(n);
1403 //bigN = bigN.multiply(BigInteger.valueOf(m));
1404 double bigN
= n
* m
;
1405 df
->setMultiplier(m
);
1406 df
->setGroupingUsed(FALSE
);
1408 FieldPosition
pos(FieldPosition::DONT_CARE
);
1409 logln("formated: " +
1410 df
->format(n
, temp
, pos
));
1413 sprintf(buf
, "%g", bigN
);
1414 //logln("expected: " + bigN.toString());
1415 logln(UnicodeString("expected: ") + buf
);
1419 /* @bug 4106667 (duplicate of 4106658)
1420 * DecimalFormat.format incorrectly formats -0.0.
1422 void NumberFormatRegressionTest::Test4106667(void)
1424 UErrorCode status
= U_ZERO_ERROR
;
1425 DecimalFormat
*df
= new DecimalFormat(status
);
1426 if(U_FAILURE(status
)) {
1427 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1431 failure(status
, "new DecimalFormat");
1432 UChar foo
[] = { 0x002B };
1433 UnicodeString
bar(foo
, 1, 1);
1434 volatile double d
= 0.0; // volatile to prevent code optimization
1436 UnicodeString buffer
;
1437 FieldPosition
pos(FieldPosition::DONT_CARE
);
1439 logln("pattern: \"" + df
->toPattern(temp
) + "\"");
1441 d
= 0.0 * -1.0; // old HPUX compiler ignores volatile keyword
1443 d
*= -1.0; // Some compilers have a problem with defining -0.0
1445 df
->setPositivePrefix(/*"+"*/bar
);
1446 df
->format(d
, buffer
, pos
);
1447 if (buffer
!= UnicodeString("-0")) // Corrected; see 4147706
1448 errln(/*d + */UnicodeString(" is formatted as ") + buffer
);
1454 * DecimalFormat.setMaximumIntegerDigits() works incorrectly.
1457 # define MAX_INT_DIGITS 70
1459 # define MAX_INT_DIGITS 128
1462 void NumberFormatRegressionTest::Test4110936(void)
1464 UErrorCode status
= U_ZERO_ERROR
;
1465 NumberFormat
*nf
= NumberFormat::createInstance(status
);
1466 if(U_FAILURE(status
)) {
1467 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1471 failure(status
, "NumberFormat::createInstance");
1472 nf
->setMaximumIntegerDigits(MAX_INT_DIGITS
);
1473 logln("setMaximumIntegerDigits(MAX_INT_DIGITS)");
1474 if (nf
->getMaximumIntegerDigits() != MAX_INT_DIGITS
)
1475 errln("getMaximumIntegerDigits() returns " +
1476 nf
->getMaximumIntegerDigits());
1482 * Locale data should use generic currency symbol
1484 * 1) Make sure that all currency formats use the generic currency symbol.
1485 * 2) Make sure we get the same results using the generic symbol or a
1488 void NumberFormatRegressionTest::Test4122840(void)
1491 const Locale
*locales
= Locale::getAvailableLocales(count
);
1493 for (int i
= 0; i
< count
; i
++) {
1494 UErrorCode status
= U_ZERO_ERROR
;
1495 ResourceBundle
*rb
= new ResourceBundle(
1496 u_getDataDirectory()/*"java.text.resources.LocaleElements"*/,
1497 locales
[i
], status
);
1498 failure(status
, "new ResourceBundle");
1499 ResourceBundle numPat
= rb
->get("NumberPatterns", status
);
1500 failure(status
, "new ResourceBundle(NumberPatterns)");
1502 // Get the currency pattern for this locale. We have to fish it
1503 // out of the ResourceBundle directly, since DecimalFormat.toPattern
1504 // will return the localized symbol, not \00a4
1506 UnicodeString pattern
= numPat
.getStringEx(1, status
);
1507 failure(status
, "rb->getStringArray");
1509 UChar fo
[] = { 0x00A4 };
1510 UnicodeString
foo(fo
, 1, 1);
1512 //if (pattern.indexOf("\u00A4") == -1 ) {
1513 if (pattern
.indexOf(foo
) == -1 ) {
1514 errln(UnicodeString("Currency format for ") + UnicodeString(locales
[i
].getName()) +
1515 " does not contain generic currency symbol:" +
1519 // Create a DecimalFormat using the pattern we got and format a number
1520 DecimalFormatSymbols
*symbols
= new DecimalFormatSymbols(locales
[i
], status
);
1521 failure(status
, "new DecimalFormatSymbols");
1522 DecimalFormat
*fmt1
= new DecimalFormat(pattern
, *symbols
, status
);
1523 failure(status
, "new DecimalFormat");
1525 UnicodeString result1
;
1526 FieldPosition
pos(FieldPosition::DONT_CARE
);
1527 result1
= fmt1
->format(1.111, result1
, pos
);
1530 // Now substitute in the locale's currency symbol and create another
1531 // pattern. We have to skip locales where the currency symbol
1532 // contains decimal separators, because that confuses things
1534 UChar ba
[] = { 0x002E/*'.'*/ };
1535 UnicodeString
bar(ba
, 1, 1);
1537 if (symbols
->getSymbol(DecimalFormatSymbols::kCurrencySymbol
).indexOf(bar
) == -1) {
1538 // {sfb} Also, switch the decimal separator to the monetary decimal
1539 // separator to mimic the behavior of a currency format
1540 symbols
->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
,
1541 symbols
->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
));
1543 UnicodeString
buf(pattern
);
1544 for (int j
= 0; j
< buf
.length(); j
++) {
1545 if (buf
[j
] == 0x00a4 ) {
1546 if(buf
[j
+ 1] == 0x00a4) {
1547 // {sfb} added to support double currency marker (intl currency sign)
1548 buf
.replace(j
, /*j+*/2, symbols
->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
));
1549 j
+= symbols
->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
).length();
1552 buf
.replace(j
, /*j+*/1, symbols
->getSymbol(DecimalFormatSymbols::kCurrencySymbol
));
1553 j
+= symbols
->getSymbol(DecimalFormatSymbols::kCurrencySymbol
).length() - 1;
1558 DecimalFormat
*fmt2
= new DecimalFormat(buf
, *symbols
, status
);
1559 failure(status
, "new DecimalFormat");
1561 UnicodeString result2
;
1562 fmt2
->format(1.111, result2
, pos
);
1564 if (result1
!= result2
) {
1565 errln("Results for " + (UnicodeString
)(locales
[i
].getName()) + " differ: " +
1566 result1
+ " vs " + result2
);
1579 * DecimalFormat.format() delivers wrong string.
1581 void NumberFormatRegressionTest::Test4125885(void)
1583 UErrorCode status
= U_ZERO_ERROR
;
1584 double rate
= 12.34;
1585 DecimalFormat
*formatDec
= new DecimalFormat ("000.00", status
);
1586 if(U_FAILURE(status
)) {
1587 errln("Error creating DecimalFormat: %s", u_errorName(status
));
1591 failure(status
, "new DecimalFormat");
1593 logln("toPattern: " + formatDec
->toPattern(temp
));
1594 UnicodeString rateString
;
1595 FieldPosition
pos(FieldPosition::DONT_CARE
);
1596 rateString
= formatDec
->format(rate
, rateString
, pos
);
1597 if (rateString
!= UnicodeString("012.34"))
1598 errln("result : " + rateString
+ " expected : 012.34");
1600 delete formatDec
;// = null;
1601 formatDec
= new DecimalFormat ("+000.00%;-000.00%", status
);
1602 failure(status
, "new DecimalFormat");
1603 logln("toPattern: " + formatDec
->toPattern(temp
));
1604 rateString
.remove();
1605 rateString
= formatDec
->format(rate
, rateString
, pos
);
1606 if (rateString
!= UnicodeString("+012.34%"))
1607 errln("result : " + rateString
+ " expected : +012.34%");
1614 * DecimalFormat produces extra zeros when formatting numbers.
1616 void NumberFormatRegressionTest::Test4134034(void)
1618 UErrorCode status
= U_ZERO_ERROR
;
1619 DecimalFormat
*nf
= new DecimalFormat("##,###,###.00", status
);
1620 failure(status
, "new DecimalFormat");
1623 FieldPosition
pos(FieldPosition::DONT_CARE
);
1624 f
= nf
->format(9.02, f
, pos
);
1625 if (f
== UnicodeString("9.02"))
1628 errln("9.02 -> " + f
+ "; want 9.02");
1631 f
= nf
->format((int32_t)0, f
, pos
);
1632 if (f
== UnicodeString(".00"))
1635 errln("0 -> " + f
+ "; want .00");
1642 * CANNOT REPRODUCE - This bug could not be reproduced. It may be
1643 * a duplicate of 4134034.
1645 * JDK 1.1.6 Bug, did NOT occur in 1.1.5
1646 * Possibly related to bug 4125885.
1648 * This class demonstrates a regression in version 1.1.6
1649 * of DecimalFormat class.
1652 * Value 1.2 Format #.00 Result '01.20' !!!wrong
1653 * Value 1.2 Format 0.00 Result '001.20' !!!wrong
1654 * Value 1.2 Format 00.00 Result '0001.20' !!!wrong
1655 * Value 1.2 Format #0.0# Result '1.2'
1656 * Value 1.2 Format #0.00 Result '001.20' !!!wrong
1659 * Value 1.2 Format #.00 Result '1.20'
1660 * Value 1.2 Format 0.00 Result '1.20'
1661 * Value 1.2 Format 00.00 Result '01.20'
1662 * Value 1.2 Format #0.0# Result '1.2'
1663 * Value 1.2 Format #0.00 Result '1.20'
1665 void NumberFormatRegressionTest::Test4134300(void) {
1666 UnicodeString DATA
[] = {
1667 // Pattern Expected string
1668 UnicodeString("#.00"), UnicodeString("1.20"),
1669 UnicodeString("0.00"), UnicodeString("1.20"),
1670 UnicodeString("00.00"), UnicodeString("01.20"),
1671 UnicodeString("#0.0#"), UnicodeString("1.2"),
1672 UnicodeString("#0.00"), UnicodeString("1.20")
1675 for (int i
=0; i
< 10; i
+=2) {
1676 UnicodeString result
;
1677 UErrorCode status
= U_ZERO_ERROR
;
1678 DecimalFormat
*df
= new DecimalFormat(DATA
[i
], status
);
1679 failure(status
, "new DecimalFormat");
1680 FieldPosition
pos(FieldPosition::DONT_CARE
);
1681 result
= df
->format(1.2, result
, pos
);
1682 if (result
!= DATA
[i
+1]) {
1683 errln("Fail: 1.2 x " + DATA
[i
] + " = " + result
+
1684 "; want " + DATA
[i
+1]);
1687 logln("Ok: 1.2 x " + DATA
[i
] + " = " + result
);
1696 * Empty pattern produces double negative prefix.
1698 void NumberFormatRegressionTest::Test4140009(void)
1700 UErrorCode status
= U_ZERO_ERROR
;
1701 DecimalFormatSymbols
*syms
= new DecimalFormatSymbols(Locale::getEnglish(), status
);
1702 failure(status
, "new DecimalFormatSymbols");
1703 DecimalFormat
*f
= new DecimalFormat(UnicodeString(""), syms
, status
);
1704 failure(status
, "new DecimalFormat");
1706 FieldPosition
pos(FieldPosition::DONT_CARE
);
1707 s
= f
->format(123.456, s
, pos
);
1708 if (s
!= UnicodeString("123.456"))
1709 errln("Fail: Format empty pattern x 123.456 => " + s
);
1711 s
= f
->format(-123.456, s
, pos
);
1712 if (s
!= UnicodeString("-123.456"))
1713 errln("Fail: Format empty pattern x -123.456 => " + s
);
1719 * BigDecimal numbers get their fractions truncated by NumberFormat.
1721 // {sfb} not pertinent in C++ ??
1722 void NumberFormatRegressionTest::Test4141750(void) {
1724 UnicodeString str("12345.67");
1725 BigDecimal bd = new BigDecimal(str);
1726 String sd = NumberFormat.getInstance(Locale.US).format(bd);
1727 if (!sd.endsWith("67")) errln("Fail: " + str + " x format -> " + sd);
1729 catch (Exception e) {
1730 errln(e.toString());
1731 e.printStackTrace();
1737 * DecimalFormat toPattern() doesn't quote special characters or handle
1740 void NumberFormatRegressionTest::Test4145457() {
1742 UErrorCode status
= U_ZERO_ERROR
;
1743 NumberFormat
*nff
= NumberFormat::createInstance(status
);
1744 failure(status
, "NumberFormat::createInstance");
1745 if(nff
->getDynamicClassID() != DecimalFormat::getStaticClassID()) {
1746 errln("DecimalFormat needed to continue");
1750 DecimalFormat
*nf
= (DecimalFormat
*)nff
;
1751 DecimalFormatSymbols
*sym
= (DecimalFormatSymbols
*) nf
->getDecimalFormatSymbols();
1752 sym
->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
, (UChar
)/*'\''*/0x0027);
1753 nf
->setDecimalFormatSymbols(*sym
);
1754 double pi
= 3.14159;
1756 UnicodeString PATS
[] = {
1757 UnicodeString("#.00 'num''ber'"), UnicodeString("''#.00''")
1760 for (int32_t i
=0; i
<2; ++i
) {
1761 nf
->applyPattern(PATS
[i
], status
);
1762 failure(status
, "nf->applyPattern");
1764 FieldPosition
pos(FieldPosition::DONT_CARE
);
1765 out
= nf
->format(pi
, out
, pos
);
1767 pat
= nf
->toPattern(pat
);
1769 ParsePosition
pp(0);
1770 nf
->parse(out
, num
, pp
);
1771 double val
= num
.getDouble();
1773 nf
->applyPattern(pat
, status
);
1774 failure(status
, "nf->applyPattern");
1776 out2
= nf
->format(pi
, out2
, pos
);
1778 pat2
= nf
->toPattern(pat2
);
1779 nf
->parse(out2
, num
, pp
);
1780 double val2
= num
.getDouble();
1783 errln("Fail with \"" + PATS
[i
] + "\": Patterns should concur, \"" +
1784 pat
+ "\" vs. \"" + pat2
+ "\"");
1786 logln("Ok \"" + PATS
[i
] + "\" toPattern() -> \"" + pat
+ '"');
1788 if (val
== val2
&& out
== out2
) {
1789 logln(UnicodeString("Ok ") + pi
+ " x \"" + PATS
[i
] + "\" -> \"" +
1790 out
+ "\" -> " + val
+ " -> \"" +
1791 out2
+ "\" -> " + val2
);
1794 errln(UnicodeString("Fail ") + pi
+ " x \"" + PATS
[i
] + "\" -> \"" +
1795 out
+ "\" -> " + val
+ " -> \"" +
1796 out2
+ "\" -> " + val2
);
1800 catch (ParseException e) {
1801 errln("Fail: " + e);
1802 e.printStackTrace();
1810 * DecimalFormat.applyPattern() sets minimum integer digits incorrectly.
1812 * This bug is a duplicate of 4139344, which is a duplicate of 4134300
1814 void NumberFormatRegressionTest::Test4147295(void)
1816 UErrorCode status
= U_ZERO_ERROR
;
1817 DecimalFormat
*sdf
= new DecimalFormat(status
);
1818 UnicodeString
pattern("#,###");
1819 logln("Applying pattern \"" + pattern
+ "\"");
1820 sdf
->applyPattern(pattern
, status
);
1821 failure(status
, "sdf->applyPattern");
1822 int minIntDig
= sdf
->getMinimumIntegerDigits();
1823 if (minIntDig
!= 0) {
1824 errln("Test failed");
1825 errln(" Minimum integer digits : " + minIntDig
);
1827 errln(" new pattern: " + sdf
->toPattern(temp
));
1829 logln("Test passed");
1830 logln(" Minimum integer digits : " + minIntDig
);
1837 * DecimalFormat formats -0.0 as +0.0
1838 * See also older related bug 4106658, 4106667
1840 void NumberFormatRegressionTest::Test4147706(void)
1842 UErrorCode status
= U_ZERO_ERROR
;
1843 DecimalFormat
*df
= new DecimalFormat("#,##0.0##", status
);
1844 failure(status
, "new DecimalFormat");
1845 DecimalFormatSymbols
*syms
= new DecimalFormatSymbols(Locale::getEnglish(), status
);
1846 failure(status
, "new DecimalFormatSymbols");
1848 UnicodeString f2
, temp
;
1849 FieldPosition
pos(FieldPosition::DONT_CARE
);
1850 volatile double d1
= 0.0; // volatile to prevent code optimization
1851 double d2
= -0.0001;
1854 d1
= 0.0 * -1.0; // old HPUX compiler ignores volatile keyword
1856 d1
*= -1.0; // Some compilers have a problem with defining -0.0
1858 df
->adoptDecimalFormatSymbols(syms
);
1859 f1
= df
->format(d1
, f1
, pos
);
1860 f2
= df
->format(d2
, f2
, pos
);
1861 if (f1
!= UnicodeString("-0.0")) {
1862 errln(UnicodeString("") + d1
+ UnicodeString(" x \"") + df
->toPattern(temp
) + "\" is formatted as \"" + f1
+ '"');
1864 if (f2
!= UnicodeString("-0.0")) {
1865 errln(UnicodeString("") + d2
+ UnicodeString(" x \"") + df
->toPattern(temp
) + "\" is formatted as \"" + f2
+ '"');
1872 // Not applicable, since no serialization in C++
1873 /*class myformat implements Serializable
1875 DateFormat _dateFormat = DateFormat.getDateInstance();
1879 GregorianCalendar calendar = new GregorianCalendar();
1880 Date t = calendar.getTime();
1881 String nowStr = _dateFormat.format(t);
1888 * NumberFormat cannot format Double.MAX_VALUE
1890 // TODO: make this test actually test something
1892 NumberFormatRegressionTest::Test4162198(void)
1894 // for some reason, DBL_MAX will not round trip. (bug in sprintf/atof)
1895 double dbl
= INT32_MAX
* 1000.0;
1896 UErrorCode status
= U_ZERO_ERROR
;
1897 NumberFormat
*f
= NumberFormat::createInstance(status
);
1898 if(U_FAILURE(status
)) {
1899 errln("Couldn't create number format");
1902 f
->setMaximumFractionDigits(INT32_MAX
);
1903 f
->setMaximumIntegerDigits(INT32_MAX
);
1906 logln(UnicodeString("The number ") + dbl
+ " formatted to " + s
);
1909 f
->parse(s
, n
, status
);
1910 if(U_FAILURE(status
))
1911 errln("Couldn't parse!");
1912 //} catch (java.text.ParseException e) {
1913 // errln("Caught a ParseException:");
1914 // e.printStackTrace();
1917 //logln("The string " + s + " parsed as " + n);
1919 if(n
.getDouble() != dbl
) {
1920 errln("Round trip failure");
1927 * NumberFormat does not parse negative zero.
1930 NumberFormatRegressionTest::Test4162852(void)
1932 UErrorCode status
= U_ZERO_ERROR
;
1933 for(int32_t i
=0; i
< 2; ++i
) {
1934 NumberFormat
*f
= (i
== 0) ? NumberFormat::createInstance(status
)
1935 : NumberFormat::createPercentInstance(status
);
1936 if(U_FAILURE(status
)) {
1937 errln("Couldn't create number format");
1945 f
->parse(s
, n
, status
);
1946 if(U_FAILURE(status
))
1947 errln("Couldn't parse!");
1948 double e
= n
.getDouble();
1949 logln(UnicodeString("") +
1951 '"' + s
+ '"' + " -> " + e
);
1952 #if (defined(OS390) && !defined(IEEE_754)) || defined(OS400)
1955 if (e
!= 0.0 || 1.0/e
> 0.0) {
1957 logln("Failed to parse negative zero");
1963 static double _u_abs(double a
) { return a
<0?-a
:a
; }
1966 * May 17 1999 sync up - liu
1968 * NumberFormat truncates data
1970 void NumberFormatRegressionTest::Test4167494(void) {
1971 UErrorCode status
= U_ZERO_ERROR
;
1972 NumberFormat
*fmt
= NumberFormat::createInstance(Locale::getUS(), status
);
1973 failure(status
, "NumberFormat::createInstance");
1975 double a
= DBL_MAX
* 0.99; // DBL_MAX itself overflows to +Inf
1979 fmt
->parse(s
, num
, status
);
1980 failure(status
, "Parse");
1981 if (num
.getType() == Formattable::kDouble
&&
1982 _u_abs(num
.getDouble() - a
) / a
< 0.01) { // RT within 1%
1983 logln(UnicodeString("") + a
+ " -> \"" + s
+ "\" -> " +
1984 toString(num
) + " ok");
1986 errln(UnicodeString("") + a
+ " -> \"" + s
+ "\" -> " +
1987 toString(num
) + " FAIL");
1990 // We don't test Double.MIN_VALUE because the locale data for the US
1991 // currently doesn't specify enough digits to display Double.MIN_VALUE.
1992 // This is correct for now; however, we leave this here as a reminder
1993 // in case we want to address this later.
1999 * May 17 1999 sync up - liu
2001 * DecimalFormat.parse() fails when ParseIntegerOnly set to true
2003 void NumberFormatRegressionTest::Test4170798(void) {
2004 UErrorCode status
= U_ZERO_ERROR
;
2005 NumberFormat
*nf
= NumberFormat::createInstance(Locale::getUS(), status
);
2006 failure(status
, "NumberFormat::createInstance");
2007 if(nf
->getDynamicClassID() != DecimalFormat::getStaticClassID()) {
2008 errln("DecimalFormat needed to continue");
2011 DecimalFormat
*df
= (DecimalFormat
*) nf
;
2012 df
->setParseIntegerOnly(TRUE
);
2014 ParsePosition
pos(0);
2015 df
->parse("-0.0", n
, pos
);
2016 if (n
.getType() != Formattable::kLong
2017 || n
.getLong() != 0) {
2018 errln(UnicodeString("FAIL: parse(\"-0.0\") returns ") + toString(n
));
2024 * May 17 1999 sync up - liu
2025 * toPattern only puts the first grouping separator in.
2027 void NumberFormatRegressionTest::Test4176114(void) {
2028 const char* DATA
[] = {
2030 "000", "#000", // No grouping
2031 "#000", "#000", // No grouping
2035 "00,000", "#00,000",
2036 "000,000", "#,000,000",
2037 "0,000,000,000,000.0000", "#0,000,000,000,000.0000", // Reported
2039 int DATA_length
= (int)(sizeof(DATA
) / sizeof(DATA
[0]));
2040 UErrorCode status
= U_ZERO_ERROR
;
2042 for (int i
=0; i
<DATA_length
; i
+=2) {
2043 DecimalFormat
df(DATA
[i
], status
);
2044 failure(status
, "DecimalFormat constructor");
2046 UnicodeString
exp(DATA
[i
+1]);
2048 errln(UnicodeString("FAIL: ") + DATA
[i
] + " -> " +
2049 s
+ ", want " + exp
);
2055 * May 17 1999 sync up - liu
2057 * DecimalFormat is incorrectly rounding numbers like 1.2501 to 1.2
2059 void NumberFormatRegressionTest::Test4179818(void) {
2060 const char* DATA
[] = {
2061 // Input Pattern Expected output
2062 "1.2511", "#.#", "1.3",
2063 "1.2501", "#.#", "1.3",
2066 int DATA_length
= (int)(sizeof(DATA
) / sizeof(DATA
[0]));
2072 UErrorCode status
= U_ZERO_ERROR
;
2073 DecimalFormatSymbols
sym(Locale::getUS(), status
);
2074 failure(status
, "Construct DecimalFormatSymbols");
2075 DecimalFormat
fmt("#", sym
, status
);
2076 failure(status
, "Construct DecimalFormat");
2077 for (int i
=0; i
<DATA_length
; i
+=3) {
2078 double in
= DOUBLE
[i
/3];
2079 UnicodeString
pat(DATA
[i
+1]);
2080 UnicodeString
exp(DATA
[i
+2]);
2081 fmt
.applyPattern(pat
, status
);
2082 failure(status
, "applyPattern");
2085 fmt
.format(in
, out
, pos
);
2087 logln(UnicodeString("Ok: ") + in
+ " x " + pat
+ " = " + out
);
2089 errln(UnicodeString("FAIL: ") + in
+ " x " + pat
+ " = " + out
+
2090 ", expected " + exp
);
2096 * May 17 1999 sync up - liu
2097 * Some DecimalFormatSymbols changes are not picked up by DecimalFormat.
2098 * This includes the minus sign, currency symbol, international currency
2099 * symbol, percent, and permille. This is filed as bugs 4212072 and
2102 void NumberFormatRegressionTest::Test4212072(void) {
2103 UErrorCode status
= U_ZERO_ERROR
;
2104 DecimalFormatSymbols
sym(Locale::getUS(), status
);
2106 failure(status
, "DecimalFormatSymbols ct");
2107 DecimalFormat
fmt(UnicodeString("#"), sym
, status
);
2108 failure(status
, "DecimalFormat ct");
2113 sym
.setSymbol(DecimalFormatSymbols::kMinusSignSymbol
, (UChar
)0x5e);
2114 fmt
.setDecimalFormatSymbols(sym
);
2116 if (fmt
.format((int32_t)-1, s
, pos
) != UNICODE_STRING("^1", 2)) {
2117 errln(UnicodeString("FAIL: -1 x (minus=^) -> ") + s
+
2121 if (fmt
.getNegativePrefix(s
) != UnicodeString((UChar
)0x5e)) {
2122 errln(UnicodeString("FAIL: (minus=^).getNegativePrefix -> ") +
2125 sym
.setSymbol(DecimalFormatSymbols::kMinusSignSymbol
, (UChar
)0x2d);
2127 fmt
.applyPattern(UnicodeString("#%"), status
);
2128 failure(status
, "applyPattern percent");
2129 sym
.setSymbol(DecimalFormatSymbols::kPercentSymbol
, (UChar
)0x5e);
2130 fmt
.setDecimalFormatSymbols(sym
);
2132 if (fmt
.format(0.25, s
, pos
) != UNICODE_STRING("25^", 3)) {
2133 errln(UnicodeString("FAIL: 0.25 x (percent=^) -> ") + s
+
2137 if (fmt
.getPositiveSuffix(s
) != UnicodeString((UChar
)0x5e)) {
2138 errln(UnicodeString("FAIL: (percent=^).getPositiveSuffix -> ") +
2141 sym
.setSymbol(DecimalFormatSymbols::kPercentSymbol
, (UChar
)0x25);
2143 fmt
.applyPattern(str("#\\u2030"), status
);
2144 failure(status
, "applyPattern permill");
2145 sym
.setSymbol(DecimalFormatSymbols::kPerMillSymbol
, (UChar
)0x5e);
2146 fmt
.setDecimalFormatSymbols(sym
);
2148 if (fmt
.format(0.25, s
, pos
) != UNICODE_STRING("250^", 4)) {
2149 errln(UnicodeString("FAIL: 0.25 x (permill=^) -> ") + s
+
2153 if (fmt
.getPositiveSuffix(s
) != UnicodeString((UChar
)0x5e)) {
2154 errln(UnicodeString("FAIL: (permill=^).getPositiveSuffix -> ") +
2157 sym
.setSymbol(DecimalFormatSymbols::kPerMillSymbol
, (UChar
)0x2030);
2159 fmt
.applyPattern(str("\\u00A4#.00"), status
);
2160 failure(status
, "applyPattern currency");
2161 sym
.setSymbol(DecimalFormatSymbols::kCurrencySymbol
, "usd");
2162 fmt
.setDecimalFormatSymbols(sym
);
2164 if (fmt
.format(12.5, s
, pos
) != UnicodeString("usd12.50")) {
2165 errln(UnicodeString("FAIL: 12.5 x (currency=usd) -> ") + s
+
2169 if (fmt
.getPositivePrefix(s
) != UnicodeString("usd")) {
2170 errln(UnicodeString("FAIL: (currency=usd).getPositivePrefix -> ") +
2173 sym
.setSymbol(DecimalFormatSymbols::kCurrencySymbol
, "$");
2175 fmt
.applyPattern(str("\\u00A4\\u00A4#.00"), status
);
2176 failure(status
, "applyPattern intl currency");
2177 sym
.setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
, "DOL");
2178 fmt
.setDecimalFormatSymbols(sym
);
2180 if (fmt
.format(12.5, s
, pos
) != UnicodeString("DOL12.50")) {
2181 errln(UnicodeString("FAIL: 12.5 x (intlcurrency=DOL) -> ") + s
+
2185 if (fmt
.getPositivePrefix(s
) != UnicodeString("DOL")) {
2186 errln(UnicodeString("FAIL: (intlcurrency=DOL).getPositivePrefix -> ") +
2189 sym
.setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
, "USD");
2191 // Since the pattern logic has changed, make sure that patterns round
2192 // trip properly. Test stream in/out integrity too.
2194 const Locale
* avail
= NumberFormat::getAvailableLocales(n
);
2195 static const char* type
[] = {
2200 for (int i
=0; i
<n
; ++i
) {
2201 for (int j
=0; j
<3; ++j
) {
2202 status
= U_ZERO_ERROR
;
2206 nf
= NumberFormat::createInstance(avail
[i
], status
);
2207 failure(status
, "createInstance");
2210 nf
= NumberFormat::createCurrencyInstance(avail
[i
], status
);
2211 failure(status
, "createCurrencyInstance");
2214 nf
= NumberFormat::createPercentInstance(avail
[i
], status
);
2215 failure(status
, "createPercentInstance");
2218 if (U_FAILURE(status
)) {
2221 DecimalFormat
*df
= (DecimalFormat
*) nf
;
2223 // Test toPattern/applyPattern round trip
2226 DecimalFormatSymbols
symb(avail
[i
], status
);
2227 failure(status
, "Construct DecimalFormatSymbols");
2228 DecimalFormat
f2(pat
, symb
, status
);
2230 UnicodeString("Construct DecimalFormat(") + pat
+ ")")) {
2235 errln(UnicodeString("FAIL: ") + type
[j
] + avail
[i
].getDisplayName(l
) +
2237 "\" -> \"" + f2
.toPattern(p
) + "\"");
2240 // Test toLocalizedPattern/applyLocalizedPattern round trip
2241 df
->toLocalizedPattern(pat
);
2242 f2
.applyLocalizedPattern(pat
, status
);
2244 UnicodeString("applyLocalizedPattern(") + pat
+ ")");
2245 if (U_FAILURE(status
)) {
2250 errln(UnicodeString("FAIL: ") + type
[j
] + avail
[i
].getDisplayName(l
) +
2251 " -> localized \"" + pat
+
2252 "\" -> \"" + f2
.toPattern(p
) + "\"");
2257 // Test writeObject/readObject round trip
2258 // NOT ON ICU -- Java only
2264 * May 17 1999 sync up - liu
2265 * DecimalFormat.parse() fails for mulipliers 2^n.
2267 void NumberFormatRegressionTest::Test4216742(void) {
2268 UErrorCode status
= U_ZERO_ERROR
;
2269 DecimalFormat
*fmt
= (DecimalFormat
*) NumberFormat::createInstance(Locale::getUS(), status
);
2270 failure(status
, "createInstance");
2271 int32_t DATA
[] = { INT32_MIN
, INT32_MAX
, -100000000, 100000000 };
2272 int DATA_length
= (int)(sizeof(DATA
) / sizeof(DATA
[0]));
2273 for (int i
=0; i
<DATA_length
; ++i
) {
2274 UnicodeString
str((UnicodeString
)"" + DATA
[i
]);
2275 for (int m
= 1; m
<= 100; m
++) {
2276 fmt
->setMultiplier(m
);
2278 fmt
->parse(str
, num
, status
);
2279 failure(status
, "parse");
2280 if (num
.getType() != Formattable::kLong
&&
2281 num
.getType() != Formattable::kDouble
) {
2282 errln(UnicodeString("FAIL: Wanted number, got ") +
2285 double d
= num
.getType() == Formattable::kDouble
?
2286 num
.getDouble() : (double) num
.getLong();
2287 if (d
> 0 != DATA
[i
] > 0) {
2288 errln(UnicodeString("\"") + str
+ "\" parse(x " +
2289 fmt
->getMultiplier() +
2290 ") => " + toString(num
));
2299 * May 17 1999 sync up - liu
2300 * DecimalFormat formats 1.001 to "1.00" instead of "1" with 2 fraction
2303 void NumberFormatRegressionTest::Test4217661(void) {
2304 const double D
[] = { 0.001, 1.001, 0.006, 1.006 };
2305 const char* S
[] = { "0", "1", "0.01", "1.01" };
2306 int D_length
= (int)(sizeof(D
) / sizeof(D
[0]));
2307 UErrorCode status
= U_ZERO_ERROR
;
2308 NumberFormat
*fmt
= NumberFormat::createInstance(Locale::getUS(), status
);
2309 failure(status
, "createInstance");
2310 fmt
->setMaximumFractionDigits(2);
2311 for (int i
=0; i
<D_length
; i
++) {
2313 fmt
->format(D
[i
], s
);
2314 if (s
!= UnicodeString(S
[i
])) {
2315 errln(UnicodeString("FAIL: Got ") + s
+ ", exp " + S
[i
]);
2322 * alphaWorks upgrade
2324 void NumberFormatRegressionTest::Test4161100(void) {
2325 UErrorCode status
= U_ZERO_ERROR
;
2326 NumberFormat
*nf
= NumberFormat::createInstance(Locale::getUS(), status
);
2327 failure(status
, "createInstance");
2328 nf
->setMinimumFractionDigits(1);
2329 nf
->setMaximumFractionDigits(1);
2334 logln(UnicodeString() + a
+ " x " +
2335 ((DecimalFormat
*) nf
)->toPattern(pat
) + " = " + s
);
2336 if (s
!= UnicodeString("-0.1")) {
2343 * June 16 1999 sync up - liu
2344 * Formatting .5 rounds to "1" instead of "0". (Regression in 1.2.2 RC1)
2346 void NumberFormatRegressionTest::Test4243011(void) {
2347 UErrorCode status
= U_ZERO_ERROR
;
2348 DecimalFormatSymbols
sym(Locale::getUS(), status
);
2349 failure(status
, "DecimalFormatSymbols ct");
2350 DecimalFormat
fmt(UnicodeString("0."), sym
, status
);
2351 failure(status
, "DecimalFormat ct");
2353 const double NUM
[] = { -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5 };
2354 const char* STR
[] = { "-2.", "-2.", "-0.", "0.", "2.", "2.", "4.", "4." };
2355 int32_t N
= (int32_t)(sizeof(NUM
) / sizeof(NUM
[0]));
2357 for (int32_t i
=0; i
<N
; ++i
) {
2359 UnicodeString
exp(STR
[i
]);
2361 fmt
.format(NUM
[i
], str
, pos
);
2363 logln(UnicodeString("Ok ") + NUM
[i
] + " x 0. = " + str
);
2365 errln(UnicodeString("FAIL ") + NUM
[i
] + " x 0. = " + str
+
2372 * June 16 1999 sync up - liu
2373 * format(0.0) gives "0.1" if preceded by parse("99.99").
2374 * (Regression in 1.2.2 RC1)
2376 void NumberFormatRegressionTest::Test4243108(void) {
2377 UErrorCode status
= U_ZERO_ERROR
;
2378 DecimalFormatSymbols
sym(Locale::getUS(), status
);
2379 failure(status
, "DecimalFormatSymbols ct");
2380 DecimalFormat
fmt(UnicodeString("#.#"), sym
, status
);
2381 failure(status
, "DecimalFormat ct");
2386 fmt
.format(0.0, str
, pos
);
2387 UnicodeString
exp("0");
2389 logln(UnicodeString("Ok 0.0 x #.# = ") + str
);
2391 errln(UnicodeString("FAIL 0.0 x #.# = ") + str
+
2397 fmt
.parse(str
, val
, status
);
2398 failure(status
, "DecimalFormat.parse(99.99)");
2399 if (val
.getType() == Formattable::kDouble
&&
2400 val
.getDouble() == 99.99) {
2401 logln(UnicodeString("Ok 99.99 / #.# = ") + toString(val
));
2403 errln(UnicodeString("FAIL 99.99 / #.# = ") + toString(val
) +
2408 fmt
.format(0.0, str
, pos
);
2410 logln(UnicodeString("Ok 0.0 x #.# = ") + str
);
2412 errln(UnicodeString("FAIL 0.0 x #.# = ") + str
+
2419 * DateFormat should call setIntegerParseOnly(TRUE) on adopted
2420 * NumberFormat objects.
2422 void NumberFormatRegressionTest::TestJ691(void) {
2423 UErrorCode status
= U_ZERO_ERROR
;
2424 Locale
loc("fr", "CH");
2426 // set up the input date string & expected output
2427 UnicodeString
udt("11.10.2000", "");
2428 UnicodeString
exp("11.10.00", "");
2430 // create a Calendar for this locale
2431 Calendar
*cal
= Calendar::createInstance(loc
, status
);
2432 if (U_FAILURE(status
)) {
2433 errln("FAIL: Calendar::createInstance() returned " + (UnicodeString
)u_errorName(status
));
2437 // create a NumberFormat for this locale
2438 NumberFormat
*nf
= NumberFormat::createInstance(loc
, status
);
2439 if (U_FAILURE(status
)) {
2440 errln("FAIL: NumberFormat::createInstance() returned " + (UnicodeString
)u_errorName(status
));
2444 // *** Here's the key: We don't want to have to do THIS:
2445 // nf->setParseIntegerOnly(TRUE);
2447 // create the DateFormat
2448 DateFormat
*df
= DateFormat::createDateInstance(DateFormat::kShort
, loc
);
2449 if (U_FAILURE(status
)) {
2450 errln("FAIL: DateFormat::createInstance() returned " + (UnicodeString
)u_errorName(status
));
2454 df
->adoptCalendar(cal
);
2455 df
->adoptNumberFormat(nf
);
2457 // set parsing to lenient & parse
2458 df
->setLenient(TRUE
);
2459 UDate ulocdat
= df
->parse(udt
, status
);
2461 // format back to a string
2462 UnicodeString outString
;
2463 df
->format(ulocdat
, outString
);
2465 if (outString
!= exp
) {
2466 errln("FAIL: " + udt
+ " => " + outString
);
2472 #endif /* #if !UCONFIG_NO_FORMATTING */