2 *******************************************************************************
\r
3 * Copyright (C) 1996-2009, International Business Machines Corporation and *
\r
4 * others. All Rights Reserved. *
\r
5 *******************************************************************************
\r
7 package com.ibm.icu.dev.test.format;
\r
9 import java.text.ParseException;
\r
10 import java.util.Locale;
\r
12 import com.ibm.icu.dev.test.TestFmwk;
\r
13 import com.ibm.icu.impl.Utility;
\r
14 import com.ibm.icu.text.DecimalFormat;
\r
15 import com.ibm.icu.text.DecimalFormatSymbols;
\r
16 import com.ibm.icu.text.NumberFormat;
\r
20 * General test of Big NumberFormat
\r
22 public class BigNumberFormatTest extends TestFmwk {
\r
24 static final int ILLEGAL = -1;
\r
26 public static void main(String[] args) throws Exception {
\r
27 new BigNumberFormatTest().run(args);
\r
30 public void TestExponent() {
\r
31 DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US);
\r
32 DecimalFormat fmt1 = new DecimalFormat("0.###E0", US);
\r
33 DecimalFormat fmt2 = new DecimalFormat("0.###E+0", US);
\r
34 Number n = new Long(1234);
\r
35 expect(fmt1, n, "1.234E3");
\r
36 expect(fmt2, n, "1.234E+3");
\r
37 expect(fmt1, "1.234E3", n);
\r
38 expect(fmt1, "1.234E+3", n); // Either format should parse "E+3"
\r
39 expect(fmt2, "1.234E+3", n);
\r
43 * Test the functioning of the secondary grouping value.
\r
45 public void TestSecondaryGrouping() {
\r
46 DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US);
\r
47 DecimalFormat f = new DecimalFormat("#,##,###", US);
\r
48 expect(f, new Long(123456789), "12,34,56,789");
\r
49 expectPat(f, "#,##,###");
\r
50 f.applyPattern("#,###");
\r
51 f.setSecondaryGroupingSize(4);
\r
52 expect(f, new Long(123456789), "12,3456,789");
\r
53 expectPat(f, "#,####,###");
\r
55 // On Sun JDK 1.2-1.3, the hi_IN locale uses '0' for a zero digit,
\r
56 // but on IBM JDK 1.2-1.3, the locale uses U+0966.
\r
57 f = (DecimalFormat) NumberFormat.getInstance(new Locale("hi", "IN"));
\r
58 String str = transmute("1,87,65,43,210",
\r
59 f.getDecimalFormatSymbols().getZeroDigit());
\r
60 expect(f, new Long(1876543210), str);
\r
63 private void expectPad(DecimalFormat fmt, String pat, int pos) {
\r
64 expectPad(fmt, pat, pos, 0, (char)0);
\r
67 private void expectPad(DecimalFormat fmt, String pat,
\r
68 int pos, int width, char pad) {
\r
69 int apos = 0, awidth = 0;
\r
72 fmt.applyPattern(pat);
\r
73 apos = fmt.getPadPosition();
\r
74 awidth = fmt.getFormatWidth();
\r
75 apad = fmt.getPadCharacter();
\r
76 } catch (IllegalArgumentException e) {
\r
81 if (apos == pos && awidth == width && apad == pad) {
\r
82 logln("Ok \"" + pat + "\" pos=" + apos +
\r
83 ((pos == -1) ? "" : " width=" + awidth + " pad=" + apad));
\r
85 logln("FAIL \"" + pat + "\" pos=" + apos +
\r
86 " width=" + awidth + " pad=" + apad +
\r
87 ", expected " + pos + " " + width + " " + pad);
\r
93 public void TestPatterns() {
\r
94 DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US);
\r
95 DecimalFormat fmt = new DecimalFormat("#", US);
\r
97 expectPad(fmt, "*^#", DecimalFormat.PAD_BEFORE_PREFIX, 1, '^');
\r
98 expectPad(fmt, "$*^#", DecimalFormat.PAD_AFTER_PREFIX, 2, '^');
\r
99 expectPad(fmt, "#*^", DecimalFormat.PAD_BEFORE_SUFFIX, 1, '^');
\r
100 expectPad(fmt, "#$*^", DecimalFormat.PAD_AFTER_SUFFIX, 2, '^');
\r
101 expectPad(fmt, "$*^$#", ILLEGAL);
\r
102 expectPad(fmt, "#$*^$", ILLEGAL);
\r
103 expectPad(fmt, "'pre'#,##0*x'post'", DecimalFormat.PAD_BEFORE_SUFFIX,
\r
105 expectPad(fmt, "''#0*x", DecimalFormat.PAD_BEFORE_SUFFIX,
\r
107 expectPad(fmt, "'I''ll'*a###.##", DecimalFormat.PAD_AFTER_PREFIX,
\r
110 fmt.applyPattern("AA#,##0.00ZZ");
\r
111 fmt.setPadCharacter('^');
\r
113 fmt.setFormatWidth(10);
\r
115 fmt.setPadPosition(DecimalFormat.PAD_BEFORE_PREFIX);
\r
116 expectPat(fmt, "*^AA#,##0.00ZZ");
\r
118 fmt.setPadPosition(DecimalFormat.PAD_BEFORE_SUFFIX);
\r
119 expectPat(fmt, "AA#,##0.00*^ZZ");
\r
121 fmt.setPadPosition(DecimalFormat.PAD_AFTER_SUFFIX);
\r
122 expectPat(fmt, "AA#,##0.00ZZ*^");
\r
125 String exp = "AA*^#,##0.00ZZ";
\r
126 fmt.setFormatWidth(12);
\r
127 fmt.setPadPosition(DecimalFormat.PAD_AFTER_PREFIX);
\r
128 expectPat(fmt, exp);
\r
130 fmt.setFormatWidth(13);
\r
132 expectPat(fmt, "AA*^##,##0.00ZZ");
\r
134 fmt.setFormatWidth(14);
\r
136 expectPat(fmt, "AA*^###,##0.00ZZ");
\r
138 fmt.setFormatWidth(15);
\r
139 // 12 3456789012345
\r
140 expectPat(fmt, "AA*^####,##0.00ZZ"); // This is the interesting case
\r
142 fmt.setFormatWidth(16);
\r
143 // 12 34567890123456
\r
144 expectPat(fmt, "AA*^#,###,##0.00ZZ");
\r
147 private void expectPat(DecimalFormat fmt, String exp) {
\r
148 String pat = fmt.toPattern();
\r
149 if (pat.equals(exp)) {
\r
150 logln("Ok \"" + pat + '"');
\r
152 errln("FAIL \"" + pat + "\", expected \"" + exp + '"');
\r
157 * Test the handling of the AlphaWorks BigDecimal
\r
159 public void TestAlphaBigDecimal() {
\r
160 DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US);
\r
161 /*For ICU compatibility [Richard/GCL]*/
\r
162 expect(NumberFormat.getScientificInstance(Locale.US),
\r
163 new Number[] { new com.ibm.icu.math.BigDecimal("12345.678901"),
\r
166 expect(new DecimalFormat("##0.####E0", US),
\r
167 new Number[] { new com.ibm.icu.math.BigDecimal("12345.4999"),
\r
168 new com.ibm.icu.math.BigDecimal("12344.5001"),
\r
171 expect(new DecimalFormat("##0.####E0", US),
\r
172 new Number[] { new com.ibm.icu.math.BigDecimal("12345.5000"),
\r
173 new com.ibm.icu.math.BigDecimal("12346.5000"),
\r
180 public void TestScientific() {
\r
181 DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US);
\r
182 /*For ICU compatibility [Richard/GCL]*/
\r
183 expect(NumberFormat.getScientificInstance(Locale.US),
\r
184 new Number[] { new Double(12345.678901),
\r
185 new java.math.BigDecimal("12345.678901"),
\r
188 expect(new DecimalFormat("##0.###E0", US),
\r
191 expect(new DecimalFormat("##0.###E0", US),
\r
192 new Double(12345.00001),
\r
194 expect(new DecimalFormat("##0.####E0", US),
\r
195 new Number[] { new Integer(12345),
\r
197 new java.math.BigDecimal("12345.4999"),
\r
198 new java.math.BigDecimal("12344.5001"),
\r
201 expect(new DecimalFormat("##0.####E0", US),
\r
202 new Number[] { new java.math.BigDecimal("12345.5000"),
\r
203 new java.math.BigDecimal("12346.5000"),
\r
206 /*For ICU compatibility [Richard/GCL]*/
\r
207 expect(NumberFormat.getScientificInstance(Locale.FRANCE),
\r
208 new Double(12345.678901),
\r
210 expect(new DecimalFormat("##0.####E0", US),
\r
211 new Double(789.12345e-9),
\r
213 expect(new DecimalFormat("##0.####E0", US),
\r
214 new Double(780.e-9),
\r
216 expect(new DecimalFormat(".###E0", US),
\r
219 expect(new DecimalFormat(".###E0", US),
\r
222 expect(new DecimalFormat[] { new DecimalFormat("#E0", US),
\r
223 new DecimalFormat("##E0", US),
\r
224 new DecimalFormat("####E0", US),
\r
225 new DecimalFormat("0E0", US),
\r
226 new DecimalFormat("00E0", US),
\r
227 new DecimalFormat("000E0", US),
\r
229 new Long(45678000),
\r
230 new String[] { "4.5678E7",
\r
238 expect(new DecimalFormat("###E0", US),
\r
239 new Object[] { new Double(0.0000123), "12.3E-6",
\r
240 new Double(0.000123), "123E-6",
\r
241 new java.math.BigDecimal("0.00123"), "1.23E-3", // Cafe VM messes up Double(0.00123)
\r
242 new Double(0.0123), "12.3E-3",
\r
243 new Double(0.123), "123E-3",
\r
244 new Double(1.23), "1.23E0",
\r
245 new Double(12.3), "12.3E0",
\r
246 new Double(123), "123E0",
\r
247 new Double(1230), "1.23E3",
\r
249 expect(new DecimalFormat("0.#E+00", US),
\r
250 new Object[] { new Double(0.00012), "1.2E-04",
\r
251 new Long(12000), "1.2E+04",
\r
257 public void TestPad() {
\r
258 DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US);
\r
259 expect(new DecimalFormat("*^##.##", US),
\r
260 new Object[] { new Long(0), "^^^^0",
\r
261 new Double(-1.3), "^-1.3",
\r
264 expect(new DecimalFormat("##0.0####E0*_ 'g-m/s^2'", US),
\r
265 new Object[] { new Long(0), "0.0E0______ g-m/s^2",
\r
266 new Double(1.0/3), "333.333E-3_ g-m/s^2",
\r
269 expect(new DecimalFormat("##0.0####*_ 'g-m/s^2'", US),
\r
270 new Object[] { new Long(0), "0.0______ g-m/s^2",
\r
271 new Double(1.0/3), "0.33333__ g-m/s^2",
\r
274 expect(new DecimalFormat("*x#,###,###,##0.00;*x(#,###,###,##0.00)", US),
\r
276 new Long(-100), "xxxxxxxx(100.00)",
\r
277 new Long(-1000), "xxxxxx(1,000.00)",
\r
278 new Long(-1000000), "xx(1,000,000.00)",
\r
279 new Long(-1000000000), "(1,000,000,000.00)",
\r
283 private void expect(NumberFormat fmt, Object[] data) {
\r
284 for (int i=0; i<data.length; i+=2) {
\r
285 expect(fmt, (Number) data[i], (String) data[i+1]);
\r
289 private void expect(Object fmto, Object numo, Object expo) {
\r
290 NumberFormat fmt = null, fmts[] = null;
\r
291 Number num = null, nums[] = null;
\r
292 String exp = null, exps[] = null;
\r
293 if (fmto instanceof NumberFormat[]) {
\r
294 fmts = (NumberFormat[]) fmto;
\r
296 fmt = (NumberFormat) fmto;
\r
298 if (numo instanceof Number[]) {
\r
299 nums = (Number[]) numo;
\r
301 num = (Number) numo;
\r
303 if (expo instanceof String[]) {
\r
304 exps = (String[]) expo;
\r
306 exp = (String) expo;
\r
309 if (fmts != null) {
\r
310 n = Math.max(n, fmts.length);
\r
312 if (nums != null) {
\r
313 n = Math.max(n, nums.length);
\r
315 if (exps != null) {
\r
316 n = Math.max(n, exps.length);
\r
318 for (int i=0; i<n; ++i) {
\r
319 expect(fmts == null ? fmt : fmts[i],
\r
320 nums == null ? num : nums[i],
\r
321 exps == null ? exp : exps[i]);
\r
325 private static String showNumber(Number n) {
\r
326 String cls = n.getClass().getName();
\r
327 if (!(n instanceof com.ibm.icu.math.BigDecimal
\r
328 || n instanceof java.math.BigDecimal)) {
\r
329 int i = cls.lastIndexOf('.');
\r
330 cls = cls.substring(i+1);
\r
332 return n.toString() + " (" + cls + ')';
\r
335 private void expect(NumberFormat fmt, Number n, String exp) {
\r
336 String saw = fmt.format(n);
\r
337 String pat = ((DecimalFormat) fmt).toPattern();
\r
338 if (saw.equals(exp)) {
\r
339 logln("Ok " + showNumber(n) + " x " +
\r
341 Utility.escape(saw));
\r
343 errln("FAIL " + showNumber(n) + " x " +
\r
345 Utility.escape(saw) + ", expected " + Utility.escape(exp));
\r
349 private void expect(NumberFormat fmt, String str, Number exp) {
\r
352 saw = fmt.parse(str);
\r
353 } catch (ParseException e) {
\r
356 String pat = ((DecimalFormat) fmt).toPattern();
\r
357 if (saw.equals(exp)) {
\r
358 logln("Ok \"" + str + "\" x " +
\r
362 errln("FAIL \"" + str + "\" x " +
\r
364 showNumber(saw) + ", expected " + showNumber(exp));
\r
369 * Given a string composed of [0-9] and other chars, convert the
\r
370 * [0-9] chars to be offsets 0..9 from 'zero'.
\r
372 private static String transmute(String str, char zero) {
\r
373 StringBuffer buf = new StringBuffer();
\r
374 for (int i=0; i<str.length(); ++i) {
\r
375 char c = str.charAt(i);
\r
376 if (c >= '0' && c <= '9') {
\r
377 c = (char) (c - '0' + zero);
\r
381 return buf.toString();
\r
384 public void Test4161100() {
\r
385 NumberFormat f = NumberFormat.getInstance();
\r
386 f.setMinimumFractionDigits(1);
\r
387 f.setMaximumFractionDigits(1);
\r
389 String s = f.format(a);
\r
391 ((DecimalFormat) f).toPattern() + " = " +
\r
393 if (!s.equals("-0.1")) {
\r
398 public void TestBigDecimalJ28() {
\r
404 "-12.3e-45", "-1.23E-44",
\r
405 "0.73e-7", "7.3E-8",
\r
407 NumberFormat fmt = NumberFormat.getScientificInstance(Locale.US);
\r
408 logln("Pattern: " + ((DecimalFormat)fmt).toPattern());
\r
409 for (int i=0; i<DATA.length; i+=2) {
\r
410 String input = DATA[i];
\r
411 String exp = DATA[i+1];
\r
412 com.ibm.icu.math.BigDecimal bd = new com.ibm.icu.math.BigDecimal(input);
\r
413 String output = fmt.format(bd);
\r
414 if (output.equals(exp)) {
\r
415 logln("input=" + input + " num=" + bd + " output=" + output);
\r
417 errln("FAIL: input=" + input + " num=" + bd + " output=" + output +
\r
418 " expected=" + exp);
\r
422 public void TestBigDecimalRounding() {
\r
424 java.text.DecimalFormat jdkFormat=new java.text.DecimalFormat("###,###,###,##0");
\r
425 com.ibm.icu.text.DecimalFormat icuFormat=new com.ibm.icu.text.DecimalFormat("###,###,###,##0");
\r
426 String[] values = {
\r
427 "-1.74", "-1.24", "-0.74", "-0.24", "0.24", "0.74", "1.24", "1.74"
\r
429 for (int i = 0; i < values.length; ++i) {
\r
430 String val = values[i];
\r
431 java.math.BigDecimal bd = new java.math.BigDecimal(val);
\r
432 String jdk = jdkFormat.format(bd);
\r
433 String icu = icuFormat.format(bd);
\r
434 logln("Format of BigDecimal " + val + " by JDK is " + jdk);
\r
435 logln("Format of BigDecimal " + val + " by ICU is " + icu);
\r
436 if (!jdk.equals(icu)) {
\r
437 errln("BigDecimal jdk: " + jdk + " != icu: " + icu);
\r
440 double d = bd.doubleValue();
\r
441 jdk = jdkFormat.format(d);
\r
442 icu = icuFormat.format(d);
\r
443 logln("Format of double " + val + " by JDK is " + jdk);
\r
444 logln("Format of double " + val + " by ICU is " + icu);
\r
445 if (!jdk.equals(icu)) {
\r
446 errln("double jdk: " + jdk + " != icu: " + icu);
\r