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