1 // 2016 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html#License 3 /* 4 ******************************************************************************* 5 * Copyright (C) 2001-2010, International Business Machines Corporation and * 6 * others. All Rights Reserved. * 7 ******************************************************************************* 8 */ 9 10 /** 11 * Porting From: ICU4C v1.8.1 : format : NumberFormatRoundTripTest 12 * Source File: $ICU4CRoot/source/test/intltest/nmfmtrt.cpp 13 **/ 14 15 package com.ibm.icu.dev.test.format; 16 17 import java.util.Locale; 18 import java.util.Random; 19 20 import org.junit.Test; 21 import org.junit.runner.RunWith; 22 import org.junit.runners.JUnit4; 23 24 import com.ibm.icu.dev.test.TestFmwk; 25 import com.ibm.icu.text.DecimalFormat; 26 import com.ibm.icu.text.NumberFormat; 27 28 /** 29 * Performs round-trip tests for NumberFormat 30 **/ 31 @RunWith(JUnit4.class) 32 public class NumberFormatRoundTripTest extends TestFmwk { 33 34 public double MAX_ERROR = 1e-14; 35 public double max_numeric_error = 0.0; 36 public double min_numeric_error = 1.0; 37 public boolean verbose = false; 38 public boolean STRING_COMPARE = false; 39 public boolean EXACT_NUMERIC_COMPARE = false; 40 public boolean DEBUG = false; 41 public boolean quick = true; 42 43 @Test 44 public void TestNumberFormatRoundTrip() { 45 46 NumberFormat fmt = null; 47 48 logln("Default Locale"); 49 50 logln("Default Number format"); 51 fmt = NumberFormat.getInstance(); 52 _test(fmt); 53 54 logln("Currency Format"); 55 fmt = NumberFormat.getCurrencyInstance(); 56 _test(fmt); 57 58 logln("Percent Format"); 59 fmt = NumberFormat.getPercentInstance(); 60 _test(fmt); 61 62 63 int locCount = 0; 64 final Locale[] loc = NumberFormat.getAvailableLocales(); 65 if(quick) { 66 if(locCount > 5) 67 locCount = 5; 68 logln("Quick mode: only _testing first 5 Locales"); 69 } 70 for(int i = 0; i < locCount; ++i) { 71 logln(loc[i].getDisplayName()); 72 73 fmt = NumberFormat.getInstance(loc[i]); 74 _test(fmt); 75 76 fmt = NumberFormat.getCurrencyInstance(loc[i]); 77 _test(fmt); 78 79 fmt = NumberFormat.getPercentInstance(loc[i]); 80 _test(fmt); 81 } 82 83 logln("Numeric error " + min_numeric_error + " to " + max_numeric_error); 84 } 85 86 /** 87 * Return a random value from -range..+range. 88 */ 89 private Random random; 90 public double randomDouble(double range) { 91 if (random == null) { 92 random = createRandom(); // use test framework's random seed 93 } 94 return random.nextDouble() * range; 95 } 96 97 private void _test(NumberFormat fmt) { 98 99 _test(fmt, Double.NaN); 100 _test(fmt, Double.POSITIVE_INFINITY); 101 _test(fmt, Double.NEGATIVE_INFINITY); 102 103 _test(fmt, 500); 104 _test(fmt, 0); 105 _test(fmt, -0); 106 _test(fmt, 0.0); 107 double negZero = 0.0; 108 negZero /= -1.0; 109 _test(fmt, negZero); 110 _test(fmt, 9223372036854775808.0d); 111 _test(fmt, -9223372036854775809.0d); 112 //_test(fmt, 6.936065876100493E74d); 113 114 // _test(fmt, 6.212122845281909E48d); 115 for (int i = 0; i < 10; ++i) { 116 117 _test(fmt, randomDouble(1)); 118 119 _test(fmt, randomDouble(10000)); 120 121 _test(fmt, Math.floor((randomDouble(10000)))); 122 123 _test(fmt, randomDouble(1e50)); 124 125 _test(fmt, randomDouble(1e-50)); 126 127 _test(fmt, randomDouble(1e100)); 128 129 _test(fmt, randomDouble(1e75)); 130 131 _test(fmt, randomDouble(1e308) / ((DecimalFormat) fmt).getMultiplier()); 132 133 _test(fmt, randomDouble(1e75) / ((DecimalFormat) fmt).getMultiplier()); 134 135 _test(fmt, randomDouble(1e65) / ((DecimalFormat) fmt).getMultiplier()); 136 137 _test(fmt, randomDouble(1e-292)); 138 139 _test(fmt, randomDouble(1e-78)); 140 141 _test(fmt, randomDouble(1e-323)); 142 143 _test(fmt, randomDouble(1e-100)); 144 145 _test(fmt, randomDouble(1e-78)); 146 } 147 } 148 149 private void _test(NumberFormat fmt, double value) { 150 _test(fmt, new Double(value)); 151 } 152 153 private void _test(NumberFormat fmt, long value) { 154 _test(fmt, new Long(value)); 155 } 156 157 private void _test(NumberFormat fmt, Number value) { 158 logln("test data = " + value); 159 fmt.setMaximumFractionDigits(999); 160 String s, s2; 161 if (value.getClass().getName().equalsIgnoreCase("java.lang.Double")) 162 s = fmt.format(value.doubleValue()); 163 else 164 s = fmt.format(value.longValue()); 165 166 Number n = new Double(0); 167 boolean show = verbose; 168 if (DEBUG) 169 logln( 170 /*value.getString(temp) +*/ " F> " + s); 171 try { 172 n = fmt.parse(s); 173 } catch (java.text.ParseException e) { 174 System.out.println(e); 175 } 176 177 if (DEBUG) 178 logln(s + " P> " /*+ n.getString(temp)*/); 179 180 if (value.getClass().getName().equalsIgnoreCase("java.lang.Double")) 181 s2 = fmt.format(n.doubleValue()); 182 else 183 s2 = fmt.format(n.longValue()); 184 185 if (DEBUG) 186 logln(/*n.getString(temp) +*/ " F> " + s2); 187 188 if (STRING_COMPARE) { 189 if (!s.equals(s2)) { 190 errln("*** STRING ERROR \"" + s + "\" != \"" + s2 + "\""); 191 show = true; 192 } 193 } 194 195 if (EXACT_NUMERIC_COMPARE) { 196 if (value != n) { 197 errln("*** NUMERIC ERROR"); 198 show = true; 199 } 200 } else { 201 // Compute proportional error 202 double error = proportionalError(value, n); 203 204 if (error > MAX_ERROR) { 205 errln("*** NUMERIC ERROR " + error); 206 show = true; 207 } 208 209 if (error > max_numeric_error) 210 max_numeric_error = error; 211 if (error < min_numeric_error) 212 min_numeric_error = error; 213 } 214 215 if (show) 216 logln( 217 /*value.getString(temp) +*/ value.getClass().getName() + " F> " + s + " P> " + 218 /*n.getString(temp) +*/ n.getClass().getName() + " F> " + s2); 219 220 } 221 222 private double proportionalError(Number a, Number b) { 223 double aa,bb; 224 225 if(a.getClass().getName().equalsIgnoreCase("java.lang.Double")) 226 aa = a.doubleValue(); 227 else 228 aa = a.longValue(); 229 230 if(a.getClass().getName().equalsIgnoreCase("java.lang.Double")) 231 bb = b.doubleValue(); 232 else 233 bb = b.longValue(); 234 235 double error = aa - bb; 236 if(aa != 0 && bb != 0) 237 error /= aa; 238 239 return Math.abs(error); 240 } 241 } 242