7050528: Improve performance of java.text.DecimalFormat.format() call stack

Reviewed-by: darcy
This commit is contained in:
Olivier Lagneau 2012-10-02 10:11:57 +01:00
parent 9b8e06e699
commit b6ea800f9b
6 changed files with 4471 additions and 19 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -286,10 +286,21 @@ public abstract class NumberFormat extends Format {
* @see java.text.Format#format
*/
public final String format(double number) {
// Use fast-path for double result if that works
String result = fastFormat(number);
if (result != null)
return result;
return format(number, new StringBuffer(),
DontCareFieldPosition.INSTANCE).toString();
}
/*
* fastFormat() is supposed to be implemented in concrete subclasses only.
* Default implem always returns null.
*/
String fastFormat(double number) { return null; }
/**
* Specialization of format.
* @exception ArithmeticException if rounding is needed with rounding

View File

@ -0,0 +1,926 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 7050528
* @summary Set of micro-benchmarks testing throughput of java.text.DecimalFormat.format()
* @author Olivier Lagneau
* @run main FormatMicroBenchmark
*/
/* This is a set of micro-benchmarks testing throughput of java.text.DecimalFormat.format().
* It never fails.
*
* Usage and arguments:
* - Run with no argument skips the whole benchmark and exits.
* - Run with "-help" as first argument calls the usage() method and exits.
* - Run with "-doit" runs the benchmark with summary details.
* - Run with "-verbose" provides additional details on the run.
*
* Example run :
* java -Xms500m -Xmx500m -XX:NewSize=400m FormatMicroBenchmark -doit -verbose
*
* Running with jtreg:
* The jtreg header "run" tag options+args must be changed to avoid skipping
* the execution. here is an example of run options:
* "main/othervm -Xms500m -Xmx500m -XX:NewSize=400m FormatMicroBenchmark -doit"
*
* Note:
* - Vm options -Xms, -Xmx, -XX:NewSize must be set correctly for
* getting reliable numbers. Otherwise GC activity may corrupt results.
* As of jdk80b48 using "-Xms500m -Xmx500m -XX:NewSize=400m" covers
* all cases.
* - Optionally using "-XX:+printGC" option provides information that
* helps checking any GC activity while benches are run.
*
* Vm Options:
* - Vm options to use (as of jdk80b48):
* fast-path case : -Xms128m -Xmx128m -XX:NewSize=100m
* non fast-path case: -Xms500m -Xmx500m -XX:NewSize=400m
* or use worst case (non fast-path above) with both types of algorithm.
*
* - use -XX:+PrintGC to verify memory consumption of the benchmarks.
* (See "Checking Memory Consumption" below).
*
* Description:
*
* Fast-path algorithm for format(double...) call stack is very different of
* the standard call stack. Where the standard algorithm for formating double
* uses internal class sun.misc.FloatingDecimal and its dtoa(double) method to
* provide digits, fast-path embeds its own algorithm for binary to decimal
* string conversion.
*
* FloatingDecimal always converts completely the passed double to a string.
* Fast-path converts only to the needed digits since it follows constraints
* on both the pattern rule, the DecimalFormat instance properties, and the
* passed double.
*
* Micro benchmarks below measure the throughput for formating double values
* using NumberFormat.format(double) call stack. The standard DecimalFormat
* call stack as well as the fast-path algorithm implementation are sensitive
* to the nature of the passed double values regarding throughput performance.
*
* These benchmarks are useful both for measuring the global performance gain
* of fast-path and to check that any modification done on fast-path algorithm
* does not bring any regression in the performance boost of fast-path.
*
* Note that these benchmarks will provide numbers without any knowledge of
* the implementation of DecimalFormat class. So to check regression any run
* should be compared to another reference run with a previous JDK, wether or
* not this previous reference JDK contains fast-path implementation.
*
* The eight benchmarks below are dedicated to measure throughput on different
* kinds of double that all fall in the fast-path case (all in Integer range):
*
* - Integer case : used double values are all "integer-like" (ex: -12345.0).
* This is the benchFormatInteger micro-benchmark.
*
* - Fractional case : double values are "fractional" (ex: -0.12345).
* This is the benchFormatFractional micro-benchmark.
*
* - Small integral case : like Integer case but double values are all limited
* in their magnitude, from -500.0 to 500.0 if the number of iterations N is
* set to 500000.
* This is the benchFormatSmallIntegral micro-benchmark.
*
* - Fractional All Nines : doubles values have fractional part that is very
* close to "999" (decimal pattern), or "99" (currency pattern),
* or "0000...".
* This is the benchFormatFractionalAllNines micro-benchmark.
*
* - All Nines : double values are such that both integral and fractional
* part consist only of '9' digits. None of these values are rounded up.
* This is the benchFormatAllNines micro-benchmark.
*
* - Fair simple case : calling J the loop variable and iterating over
* the N number of iterations, used double values are computed as
* d = (double) J + J*seed
* where seed is a very small value that adds a fractional part and adds a
* small number to integral part. Provides fairly distributed double values.
* This is the benchFormatFairSimple micro-benchmark.
*
* - Fair case : this is a combination of small integral case and fair simple
* case. Double values are limited in their magnitude but follow a parabolic
* curve y = x**2 / K, keeping large magnitude only for large values of J.
* The intent is trying to reproduce a distribution of double values as could
* be found in a business application, with most values in either the low
* range or the high range.
* This is the benchFormatFair micro-benchmark.
*
* - Tie cases: values are very close to a tie case (iii...ii.fff5)
* That is the worst situation that can happen for Fast-path algorithm when
* considering throughput.
* This is the benchFormatTie micro-benchmark.
*
* For all of the micro-benchmarks, the throughput load of the eventual
* additional computations inside the loop is calculated prior to running the
* benchmark, and provided in the output. That may be useful since this load
* may vary for each architecture or machine configuration.
*
* The "-verbose" flag, when set, provides the throughput load numbers, the
* time spent for each run of a benchmark, as well as an estimation of the
* memory consumed by the runs. Beware of incremental GCs, see "Checking
* Memory Consumption" section below. Every run should be done with correct
* ms, mx, and NewSize vm options to get fully reliable numbers.
*
* The output provides the mean time needed for a benchmark after the server
* jit compiler has done its optimization work if any. Thus only the last but
* first three runs are taken into account in the time measurement (server jit
* compiler shows to have done full optimization in most cases after the
* second run, given a base number of iterations set to 500000).
*
* The program cleans up memory (stabilizeMemory() method) between each run of
* the benchmarks to make sure that no garbage collection activity happens in
* measurements. However that does not preclude incremental GCs activity that
* may happen during the micro-benchmark if -Xms, -Xmx, and NewSize options
* have not been tuned and set correctly.
*
* Checking Memory Consumption:
*
* For getting confidence in the throughput numbers, there must not give any
* GC activity during the benchmark runs. That means that specific VM options
* related to memory must be tuned for any given implementation of the JDK.
*
* Running with "-verbose" arguments will provide clues of the memory consumed
* but is not enough, since any unexpected incremental GC may lower
* artificially the estimation of the memory consumption.
*
* Options to set are -Xms, -Xmx, -XX:NewSize, plus -XX:+PrintGC to evaluate
* correctly the values of these options. When running "-verbose", varying
* numbers reported for memory consumption may indicate bad choices for these
* options.
*
* For jdk80b25, fast-path shows a consuption of ~60Mbs for 500000 iterations
* while a jdk without fast-path will consume ~260Mbs for each benchmark run.
* Indeed these values will vary depending on the jdk used.
*
* Correct option settings found jdk80b48 were :
* fast-path : -Xms128m -Xmx128m -XX:NewSize=100m
* non fast-path : -Xms500m -Xmx500m -XX:NewSize=400m
* Greater values can be provided safely but not smaller ones.
* ----------------------------------------------------------------------
*/
import java.util.*;
import java.text.NumberFormat;
import java.text.DecimalFormat;
public class FormatMicroBenchmark {
// The number of times the bench method will be run (must be at least 4).
private static final int NB_RUNS = 20;
// The bench* methods below all iterates over [-MAX_RANGE , +MAX_RANGE] integer values.
private static final int MAX_RANGE = 500000;
// Flag for more details on each bench run (default is no).
private static boolean Verbose = false;
// Should we really execute the benches ? (no by default).
private static boolean DoIt = false;
// Prints out a message describing how to run the program.
private static void usage() {
System.out.println(
"This is a set of micro-benchmarks testing throughput of " +
"java.text.DecimalFormat.format(). It never fails.\n\n" +
"Usage and arguments:\n" +
" - Run with no argument skips the whole benchmark and exits.\n" +
" - Run with \"-help\" as first argument prints this message and exits.\n" +
" - Run with \"-doit\" runs the benchmark with summary details.\n" +
" - Run with \"-verbose\" provides additional details on the run.\n\n" +
"Example run :\n" +
" java -Xms500m -Xmx500m -XX:NewSize=400m FormatMicroBenchmark -doit -verbose\n\n" +
"Note: \n" +
" - Vm options -Xms, -Xmx, -XX:NewSize must be set correctly for \n" +
" getting reliable numbers. Otherwise GC activity may corrupt results.\n" +
" As of jdk80b48 using \"-Xms500m -Xmx500m -XX:NewSize=400m\" covers \n" +
" all cases.\n" +
" - Optionally using \"-XX:+printGC\" option provides information that \n" +
" helps checking any GC activity while benches are run.\n\n" +
"Look at the heading comments and description in source code for " +
"detailed information.\n");
}
/* We will call stabilizeMemory before each call of benchFormat***().
* This in turn tries to clean up as much memory as possible.
* As a safe bound we limit number of System.gc() calls to 10,
* but most of the time two calls to System.gc() will be enough.
* If memory reporting is asked for, the method returns the difference
* of free memory between entering an leaving the method.
*/
private static long stabilizeMemory(boolean reportConsumedMemory) {
final long oneMegabyte = 1024L * 1024L;
long refMemory = 0;
long initialMemoryLeft = Runtime.getRuntime().freeMemory();
long currMemoryLeft = initialMemoryLeft;
int nbGCCalls = 0;
do {
nbGCCalls++;
refMemory = currMemoryLeft;
System.gc();
currMemoryLeft = Runtime.getRuntime().freeMemory();
} while ((Math.abs(currMemoryLeft - refMemory) > oneMegabyte) &&
(nbGCCalls < 10));
if (Verbose &&
reportConsumedMemory)
System.out.println("Memory consumed by previous run : " +
(currMemoryLeft - initialMemoryLeft)/oneMegabyte + "Mbs.");
return currMemoryLeft;
}
// ---------- Integer only based bench --------------------
private static final String INTEGER_BENCH = "benchFormatInteger";
private static String benchFormatInteger(NumberFormat nf) {
String str = "";
for (int j = - MAX_RANGE; j <= MAX_RANGE; j++)
str = nf.format((double) j);
return str;
}
// This reproduces the throughput load added in benchFormatInteger
static double integerThroughputLoad() {
double d = 0.0d;
for (int j = - MAX_RANGE; j <= MAX_RANGE; j++) {
d = (double) j;
}
return d;
}
// Runs integerThroughputLoad and calculate its mean load
static void calculateIntegerThroughputLoad() {
int nbRuns = NB_RUNS;
long elapsedTime = 0;
double foo;
for (int i = 1; i <= nbRuns; i++) {
long startTime = System.nanoTime();
foo = integerThroughputLoad();
long estimatedTime = System.nanoTime() - startTime;
if (i > 3) elapsedTime += estimatedTime / 1000;
}
if (Verbose)
System.out.println(
"calculated throughput load for " + INTEGER_BENCH +
" bench is = " + (elapsedTime / (nbRuns - 3)) + " microseconds");
}
// ---------- Fractional only based bench --------------------
private static final String FRACTIONAL_BENCH = "benchFormatFractional";
private static String benchFormatFractional(NumberFormat nf) {
String str = "";
double floatingN = 1.0d / (double) MAX_RANGE;
for (int j = - MAX_RANGE; j <= MAX_RANGE; j++)
str = nf.format(floatingN * (double) j);
return str;
}
// This reproduces the throughput load added in benchFormatFractional
static double fractionalThroughputLoad() {
double d = 0.0d;
double floatingN = 1.0d / (double) MAX_RANGE;
for (int j = - MAX_RANGE; j <= MAX_RANGE; j++) {
d = floatingN * (double) j;
}
return d;
}
// Runs fractionalThroughputLoad and calculate its mean load
static void calculateFractionalThroughputLoad() {
int nbRuns = NB_RUNS;
long elapsedTime = 0;
double foo;
for (int i = 1; i <= nbRuns; i++) {
long startTime = System.nanoTime();
foo = fractionalThroughputLoad();
long estimatedTime = System.nanoTime() - startTime;
if (i > 3) elapsedTime += estimatedTime / 1000;
}
if (Verbose)
System.out.println(
"calculated throughput load for " + FRACTIONAL_BENCH +
" bench is = " + (elapsedTime / (nbRuns - 3)) + " microseconds");
}
// ---------- An Small Integral bench --------------------
// that limits the magnitude of tested double values
private static final String SMALL_INTEGRAL_BENCH = "benchFormatSmallIntegral";
private static String benchFormatSmallIntegral(NumberFormat nf) {
String str = "";
for (int j = - MAX_RANGE; j <= MAX_RANGE; j++)
str = nf.format(((double) j) / 1000.0d);
return str;
}
// This reproduces the throughput load added in benchFormatSmallIntegral
static double smallIntegralThroughputLoad() {
double d = 0.0d;
for (int j = - MAX_RANGE; j <= MAX_RANGE; j++) {
d = (double) j / 1000.0d;
}
return d;
}
// Runs small_integralThroughputLoad and calculate its mean load
static void calculateSmallIntegralThroughputLoad() {
int nbRuns = NB_RUNS;
long elapsedTime = 0;
double foo;
for (int i = 1; i <= nbRuns; i++) {
long startTime = System.nanoTime();
foo = smallIntegralThroughputLoad();
long estimatedTime = System.nanoTime() - startTime;
if (i > 3) elapsedTime += estimatedTime / 1000;
}
if (Verbose)
System.out.println(
"calculated throughput load for " + SMALL_INTEGRAL_BENCH +
" bench is = " + (elapsedTime / (nbRuns - 3)) + " microseconds");
}
// ---------- A fair and simple bench --------------------
private static final String FAIR_SIMPLE_BENCH = "benchFormatFairSimple";
private static String benchFormatFairSimple(NumberFormat nf, boolean isCurrency) {
String str = "";
double seed = isCurrency ? 0.0010203040506070809 : 0.00010203040506070809;
double d = (double) -MAX_RANGE;
for (int j = - MAX_RANGE; j <= MAX_RANGE; j++) {
d = d + 1.0d + seed;
str = nf.format(d);
}
return str;
}
// This reproduces the throughput load added in benchFormatFairSimple
static double fairSimpleThroughputLoad() {
double seed = 0.00010203040506070809;
double delta = 0.0d;
double d = (double) -MAX_RANGE;
for (int j = - MAX_RANGE; j <= MAX_RANGE; j++) {
d = d + 1.0d + seed;
}
return d;
}
// Runs fairThroughputLoad and calculate its mean load
static void calculateFairSimpleThroughputLoad() {
int nbRuns = NB_RUNS;
long elapsedTime = 0;
double foo;
for (int i = 1; i <= nbRuns; i++) {
long startTime = System.nanoTime();
foo = fairSimpleThroughputLoad();
long estimatedTime = System.nanoTime() - startTime;
if (i > 3) elapsedTime += estimatedTime / 1000;
}
if (Verbose)
System.out.println(
"calculated throughput load for " + FAIR_SIMPLE_BENCH +
" bench is = " + (elapsedTime / (nbRuns - 3)) + " microseconds");
}
// ---------- Fractional part is only made of nines bench --------------
private static final String FRACTIONAL_ALL_NINES_BENCH = "benchFormatFractionalAllNines";
private static String benchFormatFractionalAllNines(NumberFormat nf, boolean isCurrency) {
String str = "";
double fractionalEven = isCurrency ? 0.993000001 : 0.99930000001;
double fractionalOdd = isCurrency ? 0.996000001 : 0.99960000001;
double fractional;
double d;
for (int j = - MAX_RANGE; j <= MAX_RANGE; j++) {
if ((j & 1) == 0)
fractional = fractionalEven;
else
fractional = fractionalOdd;
if ( j >= 0)
d = (double ) j + fractional;
else d = (double) j - fractional;
str = nf.format(d);
}
return str;
}
// This reproduces the throughput load added in benchFormatFractionalAllNines
static double fractionalAllNinesThroughputLoad() {
double fractionalEven = 0.99930000001;
double fractionalOdd = 0.99960000001;
double fractional;
double d = 0.0d;
for (int j = - MAX_RANGE; j <= MAX_RANGE; j++) {
if ((j & 1) == 0)
fractional = fractionalEven;
else fractional = fractionalOdd;
if ( j >= 0)
d = (double ) j + fractional;
else d = (double) j - fractional;
}
return d;
}
// Runs fractionalAllNinesThroughputLoad and calculate its mean load
static void calculateFractionalAllNinesThroughputLoad() {
int nbRuns = NB_RUNS;
long elapsedTime = 0;
double foo;
for (int i = 1; i <= nbRuns; i++) {
long startTime = System.nanoTime();
foo = fractionalAllNinesThroughputLoad();
long estimatedTime = System.nanoTime() - startTime;
if (i > 3) elapsedTime += estimatedTime / 1000;
}
if (Verbose)
System.out.println(
"calculated throughput load for " + FRACTIONAL_ALL_NINES_BENCH +
" bench is = " + (elapsedTime / (nbRuns - 3)) + " microseconds");
}
// ---------- Number is only made of nines bench --------------
private static final String ALL_NINES_BENCH = "benchFormatAllNines";
private static String benchFormatAllNines(NumberFormat nf, boolean isCurrency) {
String str = "";
double[] decimaAllNines =
{9.9993, 99.9993, 999.9993, 9999.9993, 99999.9993,
999999.9993, 9999999.9993, 99999999.9993, 999999999.9993};
double[] currencyAllNines =
{9.993, 99.993, 999.993, 9999.993, 99999.993,
999999.993, 9999999.993, 99999999.993, 999999999.993};
double[] valuesArray = (isCurrency) ? currencyAllNines : decimaAllNines;
double seed = 1.0 / (double) MAX_RANGE;
double d;
int id;
for (int j = - MAX_RANGE; j <= MAX_RANGE; j++) {
id = (j >= 0) ? j % 9 : -j % 9;
if ((j & 1) == 0)
d = valuesArray[id] + id * seed;
else
d = valuesArray[id] - id * seed;
str = nf.format(d);
}
return str;
}
// This reproduces the throughput load added in benchFormatAllNines
static double allNinesThroughputLoad() {
double[] decimaAllNines =
{9.9993, 99.9993, 999.9993, 9999.9993, 99999.9993,
999999.9993, 9999999.9993, 99999999.9993, 999999999.9993};
double[] valuesArray = decimaAllNines;
double seed = 1.0 / (double) MAX_RANGE;
double d = 0.0d;
int id;
for (int j = - MAX_RANGE; j <= MAX_RANGE; j++) {
id = (j >= 0) ? j % 9 : -j % 9;
if ((j & 1) == 0)
d = valuesArray[id] + id * seed;
else
d = valuesArray[id] - id * seed;
}
return d;
}
// Runs allNinesThroughputLoad and calculate its mean load
static void calculateAllNinesThroughputLoad() {
int nbRuns = NB_RUNS;
long elapsedTime = 0;
double foo;
for (int i = 1; i <= nbRuns; i++) {
long startTime = System.nanoTime();
foo = allNinesThroughputLoad();
long estimatedTime = System.nanoTime() - startTime;
if (i > 3) elapsedTime += estimatedTime / 1000;
}
if (Verbose)
System.out.println(
"calculated throughput load for " + ALL_NINES_BENCH +
" bench is = " + (elapsedTime / (nbRuns - 3)) + " microseconds");
}
// --- A fair bench trying (hopefully) to reproduce business applicatons ---
/* benchFormatFair uses the following formula :
* y = F(x) = sign(x) * x**2 * ((1000/MAX_RANGE)**2).
*
* which converts in the loop as (if j is the loop index) :
* x = double(j)
* k = 1000.0d * double(MAX_RANGE)
* y = sign(j) * x**2 * k**2
*
* This is a flattened parabolic curve where only the j values
* in [-1000, 1000] will provide y results in [-1, +1] interval,
* and for abs(j) >= 1000 the result y will be greater than 1.
*
* The difference with benchFormatSmallIntegral is that since y results
* follow a parabolic curve the magnitude of y grows much more rapidly
* and closer to j values when abs(j) >= 1000:
* - for |j| < 1000, SmallIntegral(j) < 1.0 and fair(j) < 1.0
* - for j in [1000, 10000[
* SmallIntegral(j) is in [1, 10[
* Fair(j) is in [4, 400[
* - for j in [10000,100000[
* SmallIntegral(j) is in [10, 100[
* Fair(j) is in [400,40000[
* - for j in [100000,1000000[
* SmallIntegral(j) is in [100, 1000[
* Fair(j) is in [40000, 4000000[
*
* Since double values for j less than 100000 provide only 4 digits in the
* integral, values greater than 250000 provide at least 6 digits, and 500000
* computes to 1000000, the distribution is roughly half with less than 5
* digits and half with at least 6 digits in the integral part.
*
* Compared to FairSimple bench, this represents an application where 20% of
* the double values to format are less than 40000.0 absolute value.
*
* Fair(j) is close to the magnitude of j when j > 100000 and is hopefully
* more representative of what may be found in general in business apps.
* (assumption : there will be mainly either small or large values, and
* less values in middle range).
*
* We could get even more precise distribution of values using formula :
* y = sign(x) * abs(x)**n * ((1000 / MAX_RANGE)**n) where n > 2,
* or even well-known statistics function to fine target such distribution,
* but we have considred that the throughput load for calculating y would
* then be too high. We thus restrain the use of a power of 2 formula.
*/
private static final String FAIR_BENCH = "benchFormatFair";
private static String benchFormatFair(NumberFormat nf) {
String str = "";
double k = 1000.0d / (double) MAX_RANGE;
k *= k;
double d;
double absj;
double jPowerOf2;
for (int j = - MAX_RANGE; j <= MAX_RANGE; j++) {
absj = (double) j;
jPowerOf2 = absj * absj;
d = k * jPowerOf2;
if (j < 0) d = -d;
str = nf.format(d);
}
return str;
}
// This is the exact throughput load added in benchFormatFair
static double fairThroughputLoad() {
double k = 1000.0d / (double) MAX_RANGE;
k *= k;
double d = 0.0d;
double absj;
double jPowerOf2;
for (int j = - MAX_RANGE; j <= MAX_RANGE; j++) {
absj = (double) j;
jPowerOf2 = absj * absj;
d = k * jPowerOf2;
if (j < 0) d = -d;
}
return d;
}
// Runs fairThroughputLoad and calculate its mean load
static void calculateFairThroughputLoad() {
int nbRuns = NB_RUNS;
long elapsedTime = 0;
double foo;
for (int i = 1; i <= nbRuns; i++) {
long startTime = System.nanoTime();
foo = fairThroughputLoad();
long estimatedTime = System.nanoTime() - startTime;
if (i > 3) elapsedTime += estimatedTime / 1000;
}
if (Verbose)
System.out.println(
"calculated throughput load for " + FAIR_BENCH +
" bench is = " + (elapsedTime / (nbRuns - 3)) + " microseconds");
}
// ---------- All double values are very close to a tie --------------------
// i.e. like 123.1235 (for decimal case) or 123.125 (for currency case).
private static final String TIE_BENCH = "benchFormatTie";
private static String benchFormatTie(NumberFormat nf, boolean isCurrency) {
double d;
String str = "";
double fractionaScaling = (isCurrency) ? 1000.0d : 10000.0d;
int fixedFractionalPart = (isCurrency) ? 125 : 1235;
for (int j = - MAX_RANGE; j <= MAX_RANGE; j++) {
d = (((double) j * fractionaScaling) +
(double) fixedFractionalPart) / fractionaScaling;
str = nf.format(d);
}
return str;
}
// This is the exact throughput load added in benchFormatTie
static double tieThroughputLoad(boolean isCurrency) {
double d = 0.0d;
double fractionaScaling = (isCurrency) ? 1000.0d : 10000.0d;
int fixedFractionalPart = (isCurrency) ? 125 : 1235;
for (int j = - MAX_RANGE; j <= MAX_RANGE; j++) {
d = (((double) j * fractionaScaling) +
(double) fixedFractionalPart) / fractionaScaling;
}
return d;
}
// Runs tieThroughputLoad and calculate its mean load
static void calculateTieThroughputLoad(boolean isCurrency) {
int nbRuns = NB_RUNS;
long elapsedTime = 0;
double foo;
for (int i = 1; i <= nbRuns; i++) {
long startTime = System.nanoTime();
foo = tieThroughputLoad(isCurrency);
long estimatedTime = System.nanoTime() - startTime;
if (i > 3) elapsedTime += estimatedTime / 1000;
}
if (Verbose)
System.out.println(
"calculated throughput load for " + TIE_BENCH +
" bench is = " + (elapsedTime / (nbRuns - 3)) + " microseconds");
}
// Print statistics for passed times results of benchName.
static void printPerfResults(long[] times, String benchName) {
int nbBenches = times.length;
long totalTimeSpent = 0;
long meanTimeSpent;
double variance = 0;
double standardDeviation = 0;
// Calculates mean spent time
for (int i = 1; i <= nbBenches; i++)
totalTimeSpent += times[i-1];
meanTimeSpent = totalTimeSpent / nbBenches;
// Calculates standard deviation
for (int j = 1; j <= nbBenches; j++)
variance += Math.pow(((double)times[j-1] - (double)meanTimeSpent), 2);
variance = variance / (double) times.length;
standardDeviation = Math.sqrt(variance) / meanTimeSpent;
// Print result and statistics for benchName
System.out.println(
"Statistics (starting at 4th bench) for bench " + benchName +
"\n for last " + nbBenches +
" runs out of " + NB_RUNS +
" , each with 2x" + MAX_RANGE + " format(double) calls : " +
"\n mean exec time = " + meanTimeSpent + " microseconds" +
"\n standard deviation = " + String.format("%.3f", standardDeviation) + "% \n");
}
public static void main(String[] args) {
if (args.length >= 1) {
// Parse args, just checks expected ones. Ignore others or dups.
if (args[0].equals("-help")) {
usage();
return;
}
for (String s : args) {
if (s.equals("-doit"))
DoIt = true;
else if (s.equals("-verbose"))
Verbose = true;
}
} else {
// No arguments, skips the benchmarks and exits.
System.out.println(
"Test skipped with success by default. See -help for details.");
return;
}
if (!DoIt) {
if (Verbose)
usage();
System.out.println(
"Test skipped and considered successful.");
return;
}
System.out.println("Single Threaded micro benchmark evaluating " +
"the throughput of java.text.DecimalFormat.format() call stack.\n");
String fooString = "";
// Run benches for decimal instance
DecimalFormat df = (DecimalFormat) NumberFormat.getInstance(Locale.US);
System.out.println("Running with a decimal instance of DecimalFormat.");
calculateIntegerThroughputLoad();
fooString =
BenchType.INTEGER_BENCH.runBenchAndPrintStatistics(NB_RUNS, df, false);
calculateFractionalThroughputLoad();
fooString =
BenchType.FRACTIONAL_BENCH.runBenchAndPrintStatistics(NB_RUNS, df, false);
calculateSmallIntegralThroughputLoad();
fooString =
BenchType.SMALL_INTEGRAL_BENCH.runBenchAndPrintStatistics(NB_RUNS, df, false);
calculateFractionalAllNinesThroughputLoad();
fooString =
BenchType.FRACTIONAL_ALL_NINES_BENCH.runBenchAndPrintStatistics(NB_RUNS, df, false);
calculateAllNinesThroughputLoad();
fooString =
BenchType.ALL_NINES_BENCH.runBenchAndPrintStatistics(NB_RUNS, df, false);
calculateFairSimpleThroughputLoad();
fooString =
BenchType.FAIR_SIMPLE_BENCH.runBenchAndPrintStatistics(NB_RUNS, df, false);
calculateFairThroughputLoad();
fooString =
BenchType.FAIR_BENCH.runBenchAndPrintStatistics(NB_RUNS, df, false);
calculateTieThroughputLoad(false);
fooString =
BenchType.TIE_BENCH.runBenchAndPrintStatistics(NB_RUNS, df, false);
// Run benches for currency instance
DecimalFormat cf = (DecimalFormat) NumberFormat.getCurrencyInstance(Locale.US);
System.out.println("Running with a currency instance of DecimalFormat.");
calculateIntegerThroughputLoad();
fooString =
BenchType.INTEGER_BENCH.runBenchAndPrintStatistics(NB_RUNS, cf, false);
calculateFractionalThroughputLoad();
fooString =
BenchType.FRACTIONAL_BENCH.runBenchAndPrintStatistics(NB_RUNS, cf, false);
calculateSmallIntegralThroughputLoad();
fooString =
BenchType.SMALL_INTEGRAL_BENCH.runBenchAndPrintStatistics(NB_RUNS, cf, false);
calculateFractionalAllNinesThroughputLoad();
fooString =
BenchType.FRACTIONAL_ALL_NINES_BENCH.runBenchAndPrintStatistics(NB_RUNS, cf, false);
calculateAllNinesThroughputLoad();
fooString =
BenchType.ALL_NINES_BENCH.runBenchAndPrintStatistics(NB_RUNS, cf, false);
calculateFairSimpleThroughputLoad();
fooString =
BenchType.FAIR_SIMPLE_BENCH.runBenchAndPrintStatistics(NB_RUNS, cf, false);
calculateFairThroughputLoad();
fooString =
BenchType.FAIR_BENCH.runBenchAndPrintStatistics(NB_RUNS, cf, false);
calculateTieThroughputLoad(false);
fooString =
BenchType.TIE_BENCH.runBenchAndPrintStatistics(NB_RUNS, cf, false);
}
// This class to factorise what would be duplicated otherwise.
static enum BenchType {
INTEGER_BENCH("benchFormatInteger"),
FRACTIONAL_BENCH("benchFormatFractional"),
SMALL_INTEGRAL_BENCH("benchFormatSmallIntegral"),
FAIR_SIMPLE_BENCH("benchFormatFairSimple"),
FRACTIONAL_ALL_NINES_BENCH("benchFormatFractionalAllNines"),
ALL_NINES_BENCH("benchFormatAllNines"),
FAIR_BENCH("benchFormatFair"),
TIE_BENCH("benchFormatTie");
private final String name;
BenchType(String name) {
this.name = name;
}
String runBenchAndPrintStatistics(int nbRuns,
NumberFormat nf,
boolean isCurrency) {
// We eliminate the first 3 runs in the time measurements
// to let C2 do complete compilation and optimization work.
long[] elapsedTimes = new long[nbRuns - 3];
System.out.println("Now running " + nbRuns + " times bench " + name);
String str = "";
for (int i = 1; i <= nbRuns; i++) {
stabilizeMemory(false);
long startTime = System.nanoTime();
switch(this) {
case INTEGER_BENCH :
str = benchFormatInteger(nf);
break;
case FRACTIONAL_BENCH :
str = benchFormatFractional(nf);
break;
case SMALL_INTEGRAL_BENCH :
str = benchFormatSmallIntegral(nf);
break;
case FRACTIONAL_ALL_NINES_BENCH :
str = benchFormatFractionalAllNines(nf, isCurrency);
break;
case ALL_NINES_BENCH :
str = benchFormatAllNines(nf, isCurrency);
break;
case FAIR_SIMPLE_BENCH :
str = benchFormatFairSimple(nf, isCurrency);
break;
case FAIR_BENCH :
str = benchFormatFair(nf);
break;
case TIE_BENCH :
str = benchFormatTie(nf, isCurrency);
break;
default:
}
long estimatedTime = System.nanoTime() - startTime;
if (i > 3)
elapsedTimes[i-4] = estimatedTime / 1000;
if (Verbose)
System.out.println(
"calculated time for " + name +
" bench " + i + " is = " +
(estimatedTime / 1000) + " microseconds");
else System.out.print(".");
stabilizeMemory(true);
}
System.out.println(name + " Done.");
printPerfResults(elapsedTimes, name);
return str;
}
}
}

View File

@ -0,0 +1,965 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* Set of constants and values used in RoundingAndPropertyTest.java.
*
* There are 5 different information in this class:
* - TestLocale is the locale used by RoundingAndPropertyTest regression test
* when calling DecimalFormat.format() on either the set of DecimalGoldenValues
* or CurrencyGoldenValues.
* See main method of RoundingAndPropertyTest.
*
* - FullLocalizationTestLocale is the locale used by RoundingAndPropertyTest
* regression test when calling DecimalFormat.format() on the set of values
* (DecimalLocalizationValues) used to test that localization of digits
* happens correctly when needed.
* See main method of RoundingAndPropertyTest.
*
* - DecimalLocalizationValues is an array containing all the double values used
* to check that localization of digits happens correctly when needed.
* See RoundingAndPropertyTest.testLocalizationValues() method.
*
* - DecimalGoldenValues and CurrencyGoldenValues are arrays containing all the
* double values that will be used as input when checking correctness of
* results returned by DecimalFormat.format().
* 2 arrays are needed since decimal and currency formatting patterns require
* a different number of digits after decimal point.
* See RoundingAndPropertyTest.testGoldenValues() method.
*
* - PROPERTY_CHECK_POSITIVE_VALUE and PROPERTY_CHECK_NEGATIVE_VALUE are the
* double values used for testing the validity of the property changes call
* in the fast-path case. The locale used in that case is TestLocale.
* See RoundingAndPropertyTest.testSettersAndFastPath() method.
*/
import java.util.*;
class GoldenDoubleValues {
// TestLocale is the testing locale used by RoundingAndPropertyTest test,
// when testing the golden double values
static final Locale TestLocale = new Locale("en", "US");
// FullTestLocale is the testing locale used by RoundingAndPropertyTest test,
// when testing full localization of double values.
static final Locale FullLocalizationTestLocale = new Locale("hi", "IN");
/* Below are the two double values used for exercising the changes of
* of DecimalFormat properties and symbols. These values are also used
* as golden values (see golden arrays below).
*/
/* PROPERTY_CHECK_NEGATIVE_VALUE is the negative double value used for
* testing the validity of the property changes for fast-path.
* See testSettersAndFastPath() in RoundingAndPropertyTest test.
*/
static final double PROPERTY_CHECK_NEGATIVE_VALUE = -2147483646.2334997d;
/* PROPERTY_CHECK_POSITIVE_VALUE is the positive double value used for
* testing the validity of the property changes for fast-path.
* See testSettersAndFastPath() in RoundingAndPropertyTest test.
*/
static final double PROPERTY_CHECK_POSITIVE_VALUE = 2147483646.2335003d;
/* --- Array of double values to test localization ------------------------
*
* For most locales, effective localization does not happen on digits, i.e.
* the digits are not changed due to localization. In order to check that
* fast-path localize correctly digits in such a case, the array of double
* values below deals with all the case of localization that may happen on
* digits
*/
static final double[] DecimalLocalizationValues = {
1.123,
12.123,
123.123,
1234.123,
12345.123,
123456.123,
1234567.123,
12345678.123,
123456789.123,
1234567890.123,
1234.0,
1234.9,
1234.99,
1234.999
};
/* --- Arrays of golden double values ----------------------------------
*
* The GoldenValues arrays are used as input values for checking the
* correctness of the DecimalFormat.format() call results done in
* RoundingAndPropertyTest regression test. The results are compared to the
* expected ones found in GoldenFormattedValues. For each value in the
* arrays there is a corresponding expected string result found,
* represented as an array of unicode values, at the same index in the
* related GoldenFormattedValues array. The string returned by the format
* call and the found in GoldenFormattedValues array must be equal for the
* result to be considered valid.
* See RoundingAndPropertyTest.testGoldenValues() method.
*
* We need 2 such GoldenValues arrays since the decimal and currency
* formatting rules require different number of digits after decimal point.
*
* Thus we have two different arrays of golden values:
* - DecimalGoldenValues for the decimal case.
* - CurrencyGoldenValues for the currency case.
*
* They are associated to related GoldenFormattedValues arrays, generated by
* running RoundingAndPropertyTest with a "gengold" argument:
* - DecimalGoldenFormattedValues for the decimal case.
* - CurrencyGoldenFormattedValues for the currency case.
* These two generated arrays are found in GoldenFormattedValues.java file.
*
* The impact of the formatting rules is as follows, because the pattern
* rule for the fractional part is different for decimal and currency
* patterns:
* - in decimal case one must output the first non-zero 3 digits of
* fractional part 1.1232 => "1.123" and 1.12016789 => "1.12"
* - in currency case the first 2 fractional digits are always output
* 1.1232 => "1.12" and 1.0016789 => "1.00"
*
* Thus we need a different number of fractional digits when we specify
* below the golden double values to check, and most of the decimal and
* currency golden values differ only in the number of fractional digits.
*
* The list below exercises almost all code pathes of the fast-path
* algorithm except localization of digits.
*/
// --- The set of golden values for the Decimal formatting case --------
static final double[] DecimalGoldenValues = {
// Testing of specific values
+0.0,
-0.0,
Double.MIN_VALUE,
Double.MIN_NORMAL,
PROPERTY_CHECK_NEGATIVE_VALUE,
PROPERTY_CHECK_POSITIVE_VALUE,
-2147483647.9996,
2147483647.9996,
-1999999999.9994997,
1999999999.9995003,
// Testing fast-path range checks (all outside bounds)
Double.NaN,
Double.POSITIVE_INFINITY,
Double.NEGATIVE_INFINITY,
Double.MAX_VALUE,
-9876543210.9876543,
9876543210.9876543,
-1234567890.1234567E128,
1234567890.1234567E128,
// Testing of integral string size
1.123,
12.123,
123.123,
1234.123,
12345.123,
123456.123,
1234567.123,
12345678.123,
123456789.123,
1234567890.123,
-1.123,
-12.123,
-123.123,
-1234.123,
-12345.123,
-123456.123,
-1234567.123,
-12345678.123,
-123456789.123,
-1234567890.123,
// Testing of fractional string size
0.1,
0.12,
0.123,
0.1234,
10.1,
10.12,
10.123,
10.1234,
100.1,
100.12,
100.123,
100.1234,
1000.1,
1000.12,
1000.123,
1000.1234,
10000.1,
10000.12,
10000.123,
10000.1234,
100000.1,
100000.12,
100000.123,
100000.1234,
1000000.1,
1000000.12,
1000000.123,
1000000.1234,
10000000.1,
10000000.12,
10000000.123,
10000000.1234,
100000000.1,
100000000.12,
100000000.123,
100000000.1234,
1000000000.1,
1000000000.12,
1000000000.123,
1000000000.1234,
-0.1,
-0.12,
-0.123,
-0.1234,
-10.1,
-10.12,
-10.123,
-10.1234,
-100.1,
-100.12,
-100.123,
-100.1234,
-1000.1,
-1000.12,
-1000.123,
-1000.1234,
-10000.1,
-10000.12,
-10000.123,
-10000.1234,
-100000.1,
-100000.12,
-100000.123,
-100000.1234,
-1000000.1,
-1000000.12,
-1000000.123,
-1000000.1234,
-10000000.1,
-10000000.12,
-10000000.123,
-10000000.1234,
-100000000.1,
-100000000.12,
-100000000.123,
-100000000.1234,
-1000000000.1,
-1000000000.12,
-1000000000.123,
-1000000000.1234,
// Testing of special rounding cases
1.9993,
12.9993,
123.9993,
1234.9993,
12345.9993,
123456.9993,
1234567.9993,
12345678.9993,
123456789.9993,
1234567890.9993,
1.9996,
12.9996,
123.9996,
1234.9996,
12345.9996,
123456.9996,
1234567.9996,
12345678.9996,
123456789.9996,
1234567890.9996,
-1.9993,
-12.9993,
-123.9993,
-1234.9993,
-12345.9993,
-123456.9993,
-1234567.9993,
-12345678.9993,
-123456789.9993,
-1234567890.9993,
-1.9996,
-12.9996,
-123.9996,
-1234.9996,
-12345.9996,
-123456.9996,
-1234567.9996,
-12345678.9996,
-123456789.9996,
-1234567890.9996,
109.9996,
1099.9996,
10999.9996,
109999.9996,
1099999.9996,
10999999.9996,
109999999.9996,
1099999999.9996,
-109.9996,
-1099.9996,
-10999.9996,
-109999.9996,
-1099999.9996,
-10999999.9996,
-109999999.9996,
-1099999999.9996,
1.9996,
19.9996,
199.9996,
1999.9996,
19999.9996,
199999.9996,
1999999.9996,
19999999.9996,
199999999.9996,
1999999999.9996,
-1.9996,
-19.9996,
-199.9996,
-1999.9996,
-19999.9996,
-199999.9996,
-1999999.9996,
-19999999.9996,
-199999999.9996,
-1999999999.9996,
// Testing for all nines cases
9.9996,
99.9996,
999.9996,
9999.9996,
99999.9996,
999999.9996,
9999999.9996,
99999999.9996,
999999999.9996,
9.999,
99.999,
999.999,
9999.999,
99999.999,
999999.999,
9999999.999,
99999999.999,
999999999.999,
-9.9996,
-99.9996,
-999.9996,
-9999.9996,
-99999.9996,
-999999.9996,
-9999999.9996,
-99999999.9996,
-999999999.9996,
-9.999,
-99.999,
-999.999,
-9999.999,
-99999.999,
-999999.999,
-9999999.999,
-99999999.999,
-999999999.999,
// Testing for no Fractional part cases
1.0,
12.0,
123.0,
1234.0,
12345.0,
123456.0,
1234567.0,
12345678.0,
123456789.0,
1234567890.0,
-1.0,
-12.0,
-123.0,
-1234.0,
-12345.0,
-123456.0,
-1234567.0,
-12345678.0,
-123456789.0,
-1234567890.0,
// Testing of tricky cases
-2599.399999990123,
-2599.339999990123,
-2599.333999990123,
1.000099999999818,
1.000199999999818,
1.000299999999818,
1.000399999999818,
1.000499999999818,
1.000599999999818,
1.000699999999818,
1.000799999999818,
1.000899999999818,
1.000999999999818,
1.2224999999999980,
1.2224999999999981,
1.2224999999999982,
1.2224999999999983,
1.2224999999999984,
1.2224999999999985,
1.2224999999999986,
1.2224999999999987,
1.2224999999999988,
1.2224999999999989,
1.2224999999999990,
1.2224999999999991,
1.2224999999999992,
1.2224999999999993,
1.2224999999999994,
1.2224999999999995,
1.2224999999999996,
1.2224999999999997,
1.2224999999999998,
// 1.2225 and 1.2224999999999999 have the same double approximation
1.2225,
1.2225000000000001,
1.2225000000000002,
1.2225000000000003,
1.2225000000000004,
1.2225000000000005,
1.2225000000000006,
1.2225000000000007,
1.2225000000000008,
1.2225000000000009,
1.2225000000000010,
1.2225000000000011,
1.2225000000000012,
1.2225000000000013,
1.2225000000000014,
1.2225000000000015,
1.2225000000000016,
1.2225000000000017,
1.2225000000000018,
1.2225000000000019,
// Tricky rounding cases around tie values
100913.67050000005,
199999.99895901306,
251846.3465,
253243.8825000001,
365045.85349999997,
314734.9615,
541133.9755,
858372.1225,
1000999.9995000001,
1347505.7825,
3358844.1975,
9997979.4085,
9993743.1585,
9938671.9085,
3385302.5465,
3404642.6605,
3431280.0865,
3438756.4754999997,
3446053.7874999996,
3457917.5125,
3465393.9014999997,
3484734.0154999997,
3492031.3274999997,
3503895.0525,
3511371.4414999997,
3518668.7534999996,
3530532.4785,
3538008.8674999997,
3545306.1794999996,
3557169.9045,
3557348.9814999998,
3564646.2934999997,
3583986.4074999997,
3591283.7194999997,
3603147.4445,
3610623.8334999997,
3617921.1454999996,
3629784.8705,
3637261.2594999997,
3656422.2965,
3656601.3734999998,
3663898.6854999997,
3675762.4105,
3683238.7994999997,
3690536.1114999996,
3702399.8365,
3709876.2254999997,
3717173.5374999996,
3729037.2625,
3736513.6514999997,
3755853.7654999997,
3763151.0774999997,
3775014.8025,
3782491.1914999997,
3789788.5034999996,
3801652.2285,
3809128.6174999997,
3816425.9294999996,
3828289.6545,
3828468.7314999998,
3835766.0434999997,
3855106.1574999997,
3862403.4694999997,
3874267.1945,
3881743.5834999997,
3889040.8954999996,
3900904.6205,
3908381.0094999997,
3927542.0465,
3927721.1234999998,
3935018.4354999997,
3946882.1605,
3954358.5494999997,
3961655.8614999996,
3973519.5865,
3980995.9754999997,
3988293.2874999996,
4000157.0125,
4007633.4014999997,
4026973.5154999997,
4034270.8274999997,
4046134.5525,
4053610.9414999997,
4060908.2534999996,
4072771.9785,
4080248.3674999997,
4087545.6794999996,
4099409.4045,
4099588.4814999998,
4106885.7934999997,
4126225.9074999997,
4133523.2194999997,
4145386.9445,
4152863.3334999997,
4160160.6454999996,
4172024.3705,
4179500.7594999997,
4198661.7965,
4203407.2865,
4210704.5985,
4213435.4975
};
// --- The set of golden values for the currency formatting case --------
static final double[] CurrencyGoldenValues = {
// Testing of specific values
+0.0,
-0.0,
Double.MIN_VALUE,
Double.MIN_NORMAL,
PROPERTY_CHECK_NEGATIVE_VALUE,
PROPERTY_CHECK_POSITIVE_VALUE,
-2147483647.996,
2147483647.996,
-1999999999.9949997,
1999999999.9950003,
// Testing fast-path range checks (all outside bounds)
Double.NaN,
Double.POSITIVE_INFINITY,
Double.NEGATIVE_INFINITY,
Double.MAX_VALUE,
-9876543210.9876543,
9876543210.9876543,
-1234567890.1234567E128,
1234567890.1234567E128,
// Testing of integral string size
1.12,
12.12,
123.12,
1234.12,
12345.12,
123456.12,
1234567.12,
12345678.12,
123456789.12,
1234567890.12,
-1.12,
-12.12,
-123.12,
-1234.12,
-12345.12,
-123456.12,
-1234567.12,
-12345678.12,
-123456789.12,
-1234567890.12,
// Testing of fractional string size
0.1,
0.12,
0.123,
10.1,
10.12,
10.123,
100.1,
100.12,
100.123,
1000.1,
1000.12,
1000.123,
10000.1,
10000.12,
10000.123,
100000.1,
100000.12,
100000.123,
1000000.1,
1000000.12,
1000000.123,
10000000.1,
10000000.12,
10000000.123,
100000000.1,
100000000.12,
100000000.123,
1000000000.1,
1000000000.12,
1000000000.123,
-0.1,
-0.12,
-0.123,
-10.1,
-10.12,
-10.123,
-100.1,
-100.12,
-100.123,
-1000.1,
-1000.12,
-1000.123,
-10000.1,
-10000.12,
-10000.123,
-100000.1,
-100000.12,
-100000.123,
-1000000.1,
-1000000.12,
-1000000.123,
-10000000.1,
-10000000.12,
-10000000.123,
-100000000.1,
-100000000.12,
-100000000.123,
-1000000000.1,
-1000000000.12,
-1000000000.123,
// Testing of special rounding cases
1.993,
12.993,
123.993,
1234.993,
12345.993,
123456.993,
1234567.993,
12345678.993,
123456789.993,
1234567890.993,
1.996,
12.996,
123.996,
1234.996,
12345.996,
123456.996,
1234567.996,
12345678.996,
123456789.996,
1234567890.996,
-1.993,
-12.993,
-123.993,
-1234.993,
-12345.993,
-123456.993,
-1234567.993,
-12345678.993,
-123456789.993,
-1234567890.993,
-1.996,
-12.996,
-123.996,
-1234.996,
-12345.996,
-123456.996,
-1234567.996,
-12345678.996,
-123456789.996,
-1234567890.996,
109.996,
1099.996,
10999.996,
109999.996,
1099999.996,
10999999.996,
109999999.996,
1099999999.996,
-109.996,
-1099.996,
-10999.996,
-109999.996,
-1099999.996,
-10999999.996,
-109999999.996,
-1099999999.996,
1.996,
19.996,
199.996,
1999.996,
19999.996,
199999.996,
1999999.996,
19999999.996,
199999999.996,
1999999999.996,
-1.996,
-19.996,
-199.996,
-1999.996,
-19999.996,
-199999.996,
-1999999.996,
-19999999.996,
-199999999.996,
-1999999999.996,
// Testing of all nines cases
9.996,
99.996,
999.996,
9999.996,
99999.996,
999999.996,
9999999.996,
99999999.996,
999999999.996,
9.99,
99.99,
999.99,
9999.99,
99999.99,
999999.99,
9999999.99,
99999999.99,
999999999.99,
-9.996,
-99.996,
-999.996,
-9999.996,
-99999.996,
-999999.996,
-9999999.996,
-99999999.996,
-999999999.996,
-9.99,
-99.99,
-999.99,
-9999.99,
-99999.99,
-999999.99,
-9999999.99,
-99999999.99,
-999999999.99,
// Testing of no Fractional part cases
1.0,
12.0,
123.0,
1234.0,
12345.0,
123456.0,
1234567.0,
12345678.0,
123456789.0,
1234567890.0,
-1.0,
-12.0,
-123.0,
-1234.0,
-12345.0,
-123456.0,
-1234567.0,
-12345678.0,
-123456789.0,
-1234567890.0,
// Testing of tricky cases
-2599.399999990123,
-2599.339999990123,
-2599.333999990123,
1.000999999999818,
1.001999999999818,
1.002999999999818,
1.003999999999818,
1.004999999999818,
1.005999999999818,
1.006999999999818,
1.007999999999818,
1.008999999999818,
1.009999999999818,
1.224999999999980,
1.224999999999981,
1.224999999999982,
1.224999999999983,
1.224999999999984,
1.224999999999985,
1.224999999999986,
1.224999999999987,
1.224999999999988,
1.224999999999989,
1.224999999999990,
1.224999999999991,
1.224999999999992,
1.224999999999993,
1.224999999999994,
1.224999999999995,
1.224999999999996,
1.224999999999997,
1.224999999999998,
1.224999999999999,
1.225,
1.225000000000001,
1.225000000000002,
1.225000000000003,
1.225000000000004,
1.225000000000005,
1.225000000000006,
1.225000000000007,
1.225000000000008,
1.225000000000009,
1.225000000000010,
1.225000000000011,
1.225000000000012,
1.225000000000013,
1.225000000000014,
1.225000000000015,
1.225000000000016,
1.225000000000017,
1.225000000000018,
1.225000000000019,
// Tricky rounding cases around tie values
1009136.7050000005,
2518463.465,
2532438.825000001,
3650458.5349999997,
3147349.615,
5411339.755,
8583721.225,
13475057.825,
33588441.975,
99979794.085,
99937431.585,
99386719.085,
33853025.465,
34046426.605,
34312800.865,
34387564.754999997,
34460537.874999996,
34579175.125,
34653939.014999997,
34847340.154999997,
34920313.274999997,
35038950.525,
35113714.414999997,
35186687.534999996,
35305324.785,
35380088.674999997,
35453061.794999996,
35571699.045,
35573489.814999998,
35646462.934999997,
35839864.074999997,
35912837.194999997,
36031474.445,
36106238.334999997,
36179211.454999996,
36297848.705,
36372612.594999997,
36564222.965,
36566013.734999998,
36638986.854999997,
36757624.105,
36832387.994999997,
36905361.114999996,
37023998.365,
37098762.254999997,
37171735.374999996,
37290372.625,
37365136.514999997,
37558537.654999997,
37631510.774999997,
37750148.025,
37824911.914999997,
37897885.034999996,
38016522.285,
38091286.174999997,
38164259.294999996,
38282896.545,
38284687.314999998,
38357660.434999997,
38551061.574999997,
38624034.694999997,
38742671.945,
38817435.834999997,
38890408.954999996,
39009046.205,
39083810.094999997,
39275420.465,
39277211.234999998,
39350184.354999997,
39468821.605,
39543585.494999997,
39616558.614999996,
39735195.865,
39809959.754999997,
39882932.874999996,
40001570.125,
40076334.014999997,
40269735.154999997,
40342708.274999997,
40461345.525,
40536109.414999997,
40609082.534999996,
40727719.785,
40802483.674999997,
40875456.794999996,
40994094.045,
40995884.814999998,
41068857.934999997,
41262259.074999997,
41335232.194999997,
41453869.445,
41528633.334999997,
41601606.454999996,
41720243.705,
41795007.594999997,
41986617.965,
42034072.865,
42107045.985,
42134354.975
};
}

View File

@ -0,0 +1,868 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* This is a machine generated file - Please DO NOT EDIT !
* Change RoundingAndPropertyTest instead,
* and run with "-gengold" argument to regenerate (without copyright header).
*/
/* This file contains the set of result Strings expected from calling inside
* RoundingAndPropertyTest the method NumberFormat.format() upon the set of
* double values provided in GoldenDoubleValues.java. It contains three arrays,
* each containing arrays of unicode values representing the expected string
* result when calling format() on the corresponding (i.e. same index) double
* value found in GoldenDoubleValues arrays :
* - DecimalDigitsLocalizedFormattedValues corresponds to DecimalLocalizationValues,
* when using FullLocalizationTestLocale to format.
* - DecimalGoldenFormattedValues corresponds to DecimalGoldenValues, when used
* in the decimal pattern case together with TestLocale.
* - CurrencyGoldenFormattedValues corresponds to CurrencyGoldenValues. when used
* in the currency pattern case together with TestLocale.
* Please see documentation in RoundingAndPropertyTest.java for more details.
*
* This file generated by running RoundingAndPropertyTest with "-gengold" argument.
*/
class GoldenFormattedValues {
// The formatted values below were generated from golden values
// listed in GoldenDoubleValues.java, using the following jvm version :
// Oracle Corporation Java HotSpot(TM) Server VM 1.8.0-ea
// locale for golden double values : en_US
// locale for testing digit localization : hi_IN
// The array of int[] unicode values storing the expected results
// when experiencing full localization of digits on DecimalLocalizationValues.
static int[][] DecimalDigitsLocalizedFormattedValues = {
{ 2407, 46, 2407, 2408, 2409 },
{ 2407, 2408, 46, 2407, 2408, 2409 },
{ 2407, 2408, 2409, 46, 2407, 2408, 2409 },
{ 2407, 44, 2408, 2409, 2410, 46, 2407, 2408, 2409 },
{ 2407, 2408, 44, 2409, 2410, 2411, 46, 2407, 2408, 2409 },
{ 2407, 2408, 2409, 44, 2410, 2411, 2412, 46, 2407, 2408, 2409 },
{ 2407, 44, 2408, 2409, 2410, 44, 2411, 2412, 2413, 46, 2407, 2408, 2409 },
{ 2407, 2408, 44, 2409, 2410, 2411, 44, 2412, 2413, 2414, 46, 2407, 2408, 2409 },
{ 2407, 2408, 2409, 44, 2410, 2411, 2412, 44, 2413, 2414, 2415, 46, 2407, 2408, 2409 },
{ 2407, 44, 2408, 2409, 2410, 44, 2411, 2412, 2413, 44, 2414, 2415, 2406, 46, 2407, 2408, 2409 },
{ 2407, 44, 2408, 2409, 2410 },
{ 2407, 44, 2408, 2409, 2410, 46, 2415 },
{ 2407, 44, 2408, 2409, 2410, 46, 2415, 2415 },
{ 2407, 44, 2408, 2409, 2410, 46, 2415, 2415, 2415 },
};
// The array of int[] unicode values storing the expected results
// when calling Decimal.format(double) on the decimal GoldenDoubleValues.
static int[][] DecimalGoldenFormattedValues = {
{ 48 },
{ 45, 48 },
{ 48 },
{ 48 },
{ 45, 50, 44, 49, 52, 55, 44, 52, 56, 51, 44, 54, 52, 54, 46, 50, 51, 51 },
{ 50, 44, 49, 52, 55, 44, 52, 56, 51, 44, 54, 52, 54, 46, 50, 51, 52 },
{ 45, 50, 44, 49, 52, 55, 44, 52, 56, 51, 44, 54, 52, 56 },
{ 50, 44, 49, 52, 55, 44, 52, 56, 51, 44, 54, 52, 56 },
{ 45, 49, 44, 57, 57, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
{ 50, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
{ 65533 },
{ 8734 },
{ 45, 8734 },
{ 49, 55, 57, 44, 55, 54, 57, 44, 51, 49, 51, 44, 52, 56, 54, 44, 50, 51, 49, 44, 53, 55, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
{ 45, 57, 44, 56, 55, 54, 44, 53, 52, 51, 44, 50, 49, 48, 46, 57, 56, 56 },
{ 57, 44, 56, 55, 54, 44, 53, 52, 51, 44, 50, 49, 48, 46, 57, 56, 56 },
{ 45, 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 44, 48, 49, 50, 44, 51, 52, 53, 44, 54, 55, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
{ 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 44, 48, 49, 50, 44, 51, 52, 53, 44, 54, 55, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
{ 49, 46, 49, 50, 51 },
{ 49, 50, 46, 49, 50, 51 },
{ 49, 50, 51, 46, 49, 50, 51 },
{ 49, 44, 50, 51, 52, 46, 49, 50, 51 },
{ 49, 50, 44, 51, 52, 53, 46, 49, 50, 51 },
{ 49, 50, 51, 44, 52, 53, 54, 46, 49, 50, 51 },
{ 49, 44, 50, 51, 52, 44, 53, 54, 55, 46, 49, 50, 51 },
{ 49, 50, 44, 51, 52, 53, 44, 54, 55, 56, 46, 49, 50, 51 },
{ 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 46, 49, 50, 51 },
{ 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48, 46, 49, 50, 51 },
{ 45, 49, 46, 49, 50, 51 },
{ 45, 49, 50, 46, 49, 50, 51 },
{ 45, 49, 50, 51, 46, 49, 50, 51 },
{ 45, 49, 44, 50, 51, 52, 46, 49, 50, 51 },
{ 45, 49, 50, 44, 51, 52, 53, 46, 49, 50, 51 },
{ 45, 49, 50, 51, 44, 52, 53, 54, 46, 49, 50, 51 },
{ 45, 49, 44, 50, 51, 52, 44, 53, 54, 55, 46, 49, 50, 51 },
{ 45, 49, 50, 44, 51, 52, 53, 44, 54, 55, 56, 46, 49, 50, 51 },
{ 45, 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 46, 49, 50, 51 },
{ 45, 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48, 46, 49, 50, 51 },
{ 48, 46, 49 },
{ 48, 46, 49, 50 },
{ 48, 46, 49, 50, 51 },
{ 48, 46, 49, 50, 51 },
{ 49, 48, 46, 49 },
{ 49, 48, 46, 49, 50 },
{ 49, 48, 46, 49, 50, 51 },
{ 49, 48, 46, 49, 50, 51 },
{ 49, 48, 48, 46, 49 },
{ 49, 48, 48, 46, 49, 50 },
{ 49, 48, 48, 46, 49, 50, 51 },
{ 49, 48, 48, 46, 49, 50, 51 },
{ 49, 44, 48, 48, 48, 46, 49 },
{ 49, 44, 48, 48, 48, 46, 49, 50 },
{ 49, 44, 48, 48, 48, 46, 49, 50, 51 },
{ 49, 44, 48, 48, 48, 46, 49, 50, 51 },
{ 49, 48, 44, 48, 48, 48, 46, 49 },
{ 49, 48, 44, 48, 48, 48, 46, 49, 50 },
{ 49, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
{ 49, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
{ 49, 48, 48, 44, 48, 48, 48, 46, 49 },
{ 49, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
{ 49, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
{ 49, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
{ 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49 },
{ 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
{ 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
{ 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
{ 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49 },
{ 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
{ 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
{ 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
{ 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49 },
{ 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
{ 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
{ 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
{ 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49 },
{ 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
{ 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
{ 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
{ 45, 48, 46, 49 },
{ 45, 48, 46, 49, 50 },
{ 45, 48, 46, 49, 50, 51 },
{ 45, 48, 46, 49, 50, 51 },
{ 45, 49, 48, 46, 49 },
{ 45, 49, 48, 46, 49, 50 },
{ 45, 49, 48, 46, 49, 50, 51 },
{ 45, 49, 48, 46, 49, 50, 51 },
{ 45, 49, 48, 48, 46, 49 },
{ 45, 49, 48, 48, 46, 49, 50 },
{ 45, 49, 48, 48, 46, 49, 50, 51 },
{ 45, 49, 48, 48, 46, 49, 50, 51 },
{ 45, 49, 44, 48, 48, 48, 46, 49 },
{ 45, 49, 44, 48, 48, 48, 46, 49, 50 },
{ 45, 49, 44, 48, 48, 48, 46, 49, 50, 51 },
{ 45, 49, 44, 48, 48, 48, 46, 49, 50, 51 },
{ 45, 49, 48, 44, 48, 48, 48, 46, 49 },
{ 45, 49, 48, 44, 48, 48, 48, 46, 49, 50 },
{ 45, 49, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
{ 45, 49, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
{ 45, 49, 48, 48, 44, 48, 48, 48, 46, 49 },
{ 45, 49, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
{ 45, 49, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
{ 45, 49, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
{ 45, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49 },
{ 45, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
{ 45, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
{ 45, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
{ 45, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49 },
{ 45, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
{ 45, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
{ 45, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
{ 45, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49 },
{ 45, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
{ 45, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
{ 45, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
{ 45, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49 },
{ 45, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
{ 45, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
{ 45, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
{ 49, 46, 57, 57, 57 },
{ 49, 50, 46, 57, 57, 57 },
{ 49, 50, 51, 46, 57, 57, 57 },
{ 49, 44, 50, 51, 52, 46, 57, 57, 57 },
{ 49, 50, 44, 51, 52, 53, 46, 57, 57, 57 },
{ 49, 50, 51, 44, 52, 53, 54, 46, 57, 57, 57 },
{ 49, 44, 50, 51, 52, 44, 53, 54, 55, 46, 57, 57, 57 },
{ 49, 50, 44, 51, 52, 53, 44, 54, 55, 56, 46, 57, 57, 57 },
{ 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 46, 57, 57, 57 },
{ 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48, 46, 57, 57, 57 },
{ 50 },
{ 49, 51 },
{ 49, 50, 52 },
{ 49, 44, 50, 51, 53 },
{ 49, 50, 44, 51, 52, 54 },
{ 49, 50, 51, 44, 52, 53, 55 },
{ 49, 44, 50, 51, 52, 44, 53, 54, 56 },
{ 49, 50, 44, 51, 52, 53, 44, 54, 55, 57 },
{ 49, 50, 51, 44, 52, 53, 54, 44, 55, 57, 48 },
{ 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 49 },
{ 45, 49, 46, 57, 57, 57 },
{ 45, 49, 50, 46, 57, 57, 57 },
{ 45, 49, 50, 51, 46, 57, 57, 57 },
{ 45, 49, 44, 50, 51, 52, 46, 57, 57, 57 },
{ 45, 49, 50, 44, 51, 52, 53, 46, 57, 57, 57 },
{ 45, 49, 50, 51, 44, 52, 53, 54, 46, 57, 57, 57 },
{ 45, 49, 44, 50, 51, 52, 44, 53, 54, 55, 46, 57, 57, 57 },
{ 45, 49, 50, 44, 51, 52, 53, 44, 54, 55, 56, 46, 57, 57, 57 },
{ 45, 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 46, 57, 57, 57 },
{ 45, 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48, 46, 57, 57, 57 },
{ 45, 50 },
{ 45, 49, 51 },
{ 45, 49, 50, 52 },
{ 45, 49, 44, 50, 51, 53 },
{ 45, 49, 50, 44, 51, 52, 54 },
{ 45, 49, 50, 51, 44, 52, 53, 55 },
{ 45, 49, 44, 50, 51, 52, 44, 53, 54, 56 },
{ 45, 49, 50, 44, 51, 52, 53, 44, 54, 55, 57 },
{ 45, 49, 50, 51, 44, 52, 53, 54, 44, 55, 57, 48 },
{ 45, 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 49 },
{ 49, 49, 48 },
{ 49, 44, 49, 48, 48 },
{ 49, 49, 44, 48, 48, 48 },
{ 49, 49, 48, 44, 48, 48, 48 },
{ 49, 44, 49, 48, 48, 44, 48, 48, 48 },
{ 49, 49, 44, 48, 48, 48, 44, 48, 48, 48 },
{ 49, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
{ 49, 44, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
{ 45, 49, 49, 48 },
{ 45, 49, 44, 49, 48, 48 },
{ 45, 49, 49, 44, 48, 48, 48 },
{ 45, 49, 49, 48, 44, 48, 48, 48 },
{ 45, 49, 44, 49, 48, 48, 44, 48, 48, 48 },
{ 45, 49, 49, 44, 48, 48, 48, 44, 48, 48, 48 },
{ 45, 49, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
{ 45, 49, 44, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
{ 50 },
{ 50, 48 },
{ 50, 48, 48 },
{ 50, 44, 48, 48, 48 },
{ 50, 48, 44, 48, 48, 48 },
{ 50, 48, 48, 44, 48, 48, 48 },
{ 50, 44, 48, 48, 48, 44, 48, 48, 48 },
{ 50, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
{ 50, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
{ 50, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
{ 45, 50 },
{ 45, 50, 48 },
{ 45, 50, 48, 48 },
{ 45, 50, 44, 48, 48, 48 },
{ 45, 50, 48, 44, 48, 48, 48 },
{ 45, 50, 48, 48, 44, 48, 48, 48 },
{ 45, 50, 44, 48, 48, 48, 44, 48, 48, 48 },
{ 45, 50, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
{ 45, 50, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
{ 45, 50, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
{ 49, 48 },
{ 49, 48, 48 },
{ 49, 44, 48, 48, 48 },
{ 49, 48, 44, 48, 48, 48 },
{ 49, 48, 48, 44, 48, 48, 48 },
{ 49, 44, 48, 48, 48, 44, 48, 48, 48 },
{ 49, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
{ 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
{ 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
{ 57, 46, 57, 57, 57 },
{ 57, 57, 46, 57, 57, 57 },
{ 57, 57, 57, 46, 57, 57, 57 },
{ 57, 44, 57, 57, 57, 46, 57, 57, 57 },
{ 57, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
{ 57, 57, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
{ 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
{ 57, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
{ 57, 57, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
{ 45, 49, 48 },
{ 45, 49, 48, 48 },
{ 45, 49, 44, 48, 48, 48 },
{ 45, 49, 48, 44, 48, 48, 48 },
{ 45, 49, 48, 48, 44, 48, 48, 48 },
{ 45, 49, 44, 48, 48, 48, 44, 48, 48, 48 },
{ 45, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
{ 45, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
{ 45, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
{ 45, 57, 46, 57, 57, 57 },
{ 45, 57, 57, 46, 57, 57, 57 },
{ 45, 57, 57, 57, 46, 57, 57, 57 },
{ 45, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
{ 45, 57, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
{ 45, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
{ 45, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
{ 45, 57, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
{ 45, 57, 57, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
{ 49 },
{ 49, 50 },
{ 49, 50, 51 },
{ 49, 44, 50, 51, 52 },
{ 49, 50, 44, 51, 52, 53 },
{ 49, 50, 51, 44, 52, 53, 54 },
{ 49, 44, 50, 51, 52, 44, 53, 54, 55 },
{ 49, 50, 44, 51, 52, 53, 44, 54, 55, 56 },
{ 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57 },
{ 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48 },
{ 45, 49 },
{ 45, 49, 50 },
{ 45, 49, 50, 51 },
{ 45, 49, 44, 50, 51, 52 },
{ 45, 49, 50, 44, 51, 52, 53 },
{ 45, 49, 50, 51, 44, 52, 53, 54 },
{ 45, 49, 44, 50, 51, 52, 44, 53, 54, 55 },
{ 45, 49, 50, 44, 51, 52, 53, 44, 54, 55, 56 },
{ 45, 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57 },
{ 45, 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48 },
{ 45, 50, 44, 53, 57, 57, 46, 52 },
{ 45, 50, 44, 53, 57, 57, 46, 51, 52 },
{ 45, 50, 44, 53, 57, 57, 46, 51, 51, 52 },
{ 49 },
{ 49 },
{ 49 },
{ 49 },
{ 49 },
{ 49, 46, 48, 48, 49 },
{ 49, 46, 48, 48, 49 },
{ 49, 46, 48, 48, 49 },
{ 49, 46, 48, 48, 49 },
{ 49, 46, 48, 48, 49 },
{ 49, 46, 50, 50, 50 },
{ 49, 46, 50, 50, 50 },
{ 49, 46, 50, 50, 50 },
{ 49, 46, 50, 50, 50 },
{ 49, 46, 50, 50, 50 },
{ 49, 46, 50, 50, 50 },
{ 49, 46, 50, 50, 50 },
{ 49, 46, 50, 50, 50 },
{ 49, 46, 50, 50, 50 },
{ 49, 46, 50, 50, 50 },
{ 49, 46, 50, 50, 50 },
{ 49, 46, 50, 50, 50 },
{ 49, 46, 50, 50, 50 },
{ 49, 46, 50, 50, 50 },
{ 49, 46, 50, 50, 50 },
{ 49, 46, 50, 50, 50 },
{ 49, 46, 50, 50, 50 },
{ 49, 46, 50, 50, 50 },
{ 49, 46, 50, 50, 50 },
{ 49, 46, 50, 50, 50 },
{ 49, 46, 50, 50, 51 },
{ 49, 46, 50, 50, 51 },
{ 49, 46, 50, 50, 51 },
{ 49, 46, 50, 50, 51 },
{ 49, 46, 50, 50, 51 },
{ 49, 46, 50, 50, 51 },
{ 49, 46, 50, 50, 51 },
{ 49, 46, 50, 50, 51 },
{ 49, 46, 50, 50, 51 },
{ 49, 46, 50, 50, 51 },
{ 49, 46, 50, 50, 51 },
{ 49, 46, 50, 50, 51 },
{ 49, 46, 50, 50, 51 },
{ 49, 46, 50, 50, 51 },
{ 49, 46, 50, 50, 51 },
{ 49, 46, 50, 50, 51 },
{ 49, 46, 50, 50, 51 },
{ 49, 46, 50, 50, 51 },
{ 49, 46, 50, 50, 51 },
{ 49, 48, 48, 44, 57, 49, 51, 46, 54, 55, 49 },
{ 49, 57, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
{ 50, 53, 49, 44, 56, 52, 54, 46, 51, 52, 55 },
{ 50, 53, 51, 44, 50, 52, 51, 46, 56, 56, 51 },
{ 51, 54, 53, 44, 48, 52, 53, 46, 56, 53, 51 },
{ 51, 49, 52, 44, 55, 51, 52, 46, 57, 54, 49 },
{ 53, 52, 49, 44, 49, 51, 51, 46, 57, 55, 53 },
{ 56, 53, 56, 44, 51, 55, 50, 46, 49, 50, 51 },
{ 49, 44, 48, 48, 49, 44, 48, 48, 48 },
{ 49, 44, 51, 52, 55, 44, 53, 48, 53, 46, 55, 56, 50 },
{ 51, 44, 51, 53, 56, 44, 56, 52, 52, 46, 49, 57, 55 },
{ 57, 44, 57, 57, 55, 44, 57, 55, 57, 46, 52, 48, 57 },
{ 57, 44, 57, 57, 51, 44, 55, 52, 51, 46, 49, 53, 57 },
{ 57, 44, 57, 51, 56, 44, 54, 55, 49, 46, 57, 48, 57 },
{ 51, 44, 51, 56, 53, 44, 51, 48, 50, 46, 53, 52, 55 },
{ 51, 44, 52, 48, 52, 44, 54, 52, 50, 46, 54, 54, 49 },
{ 51, 44, 52, 51, 49, 44, 50, 56, 48, 46, 48, 56, 55 },
{ 51, 44, 52, 51, 56, 44, 55, 53, 54, 46, 52, 55, 53 },
{ 51, 44, 52, 52, 54, 44, 48, 53, 51, 46, 55, 56, 55 },
{ 51, 44, 52, 53, 55, 44, 57, 49, 55, 46, 53, 49, 51 },
{ 51, 44, 52, 54, 53, 44, 51, 57, 51, 46, 57, 48, 49 },
{ 51, 44, 52, 56, 52, 44, 55, 51, 52, 46, 48, 49, 53 },
{ 51, 44, 52, 57, 50, 44, 48, 51, 49, 46, 51, 50, 55 },
{ 51, 44, 53, 48, 51, 44, 56, 57, 53, 46, 48, 53, 51 },
{ 51, 44, 53, 49, 49, 44, 51, 55, 49, 46, 52, 52, 49 },
{ 51, 44, 53, 49, 56, 44, 54, 54, 56, 46, 55, 53, 51 },
{ 51, 44, 53, 51, 48, 44, 53, 51, 50, 46, 52, 55, 57 },
{ 51, 44, 53, 51, 56, 44, 48, 48, 56, 46, 56, 54, 55 },
{ 51, 44, 53, 52, 53, 44, 51, 48, 54, 46, 49, 55, 57 },
{ 51, 44, 53, 53, 55, 44, 49, 54, 57, 46, 57, 48, 53 },
{ 51, 44, 53, 53, 55, 44, 51, 52, 56, 46, 57, 56, 49 },
{ 51, 44, 53, 54, 52, 44, 54, 52, 54, 46, 50, 57, 51 },
{ 51, 44, 53, 56, 51, 44, 57, 56, 54, 46, 52, 48, 55 },
{ 51, 44, 53, 57, 49, 44, 50, 56, 51, 46, 55, 49, 57 },
{ 51, 44, 54, 48, 51, 44, 49, 52, 55, 46, 52, 52, 53 },
{ 51, 44, 54, 49, 48, 44, 54, 50, 51, 46, 56, 51, 51 },
{ 51, 44, 54, 49, 55, 44, 57, 50, 49, 46, 49, 52, 53 },
{ 51, 44, 54, 50, 57, 44, 55, 56, 52, 46, 56, 55, 49 },
{ 51, 44, 54, 51, 55, 44, 50, 54, 49, 46, 50, 53, 57 },
{ 51, 44, 54, 53, 54, 44, 52, 50, 50, 46, 50, 57, 55 },
{ 51, 44, 54, 53, 54, 44, 54, 48, 49, 46, 51, 55, 51 },
{ 51, 44, 54, 54, 51, 44, 56, 57, 56, 46, 54, 56, 53 },
{ 51, 44, 54, 55, 53, 44, 55, 54, 50, 46, 52, 49, 49 },
{ 51, 44, 54, 56, 51, 44, 50, 51, 56, 46, 55, 57, 57 },
{ 51, 44, 54, 57, 48, 44, 53, 51, 54, 46, 49, 49, 49 },
{ 51, 44, 55, 48, 50, 44, 51, 57, 57, 46, 56, 51, 55 },
{ 51, 44, 55, 48, 57, 44, 56, 55, 54, 46, 50, 50, 53 },
{ 51, 44, 55, 49, 55, 44, 49, 55, 51, 46, 53, 51, 55 },
{ 51, 44, 55, 50, 57, 44, 48, 51, 55, 46, 50, 54, 51 },
{ 51, 44, 55, 51, 54, 44, 53, 49, 51, 46, 54, 53, 49 },
{ 51, 44, 55, 53, 53, 44, 56, 53, 51, 46, 55, 54, 53 },
{ 51, 44, 55, 54, 51, 44, 49, 53, 49, 46, 48, 55, 55 },
{ 51, 44, 55, 55, 53, 44, 48, 49, 52, 46, 56, 48, 51 },
{ 51, 44, 55, 56, 50, 44, 52, 57, 49, 46, 49, 57, 49 },
{ 51, 44, 55, 56, 57, 44, 55, 56, 56, 46, 53, 48, 51 },
{ 51, 44, 56, 48, 49, 44, 54, 53, 50, 46, 50, 50, 57 },
{ 51, 44, 56, 48, 57, 44, 49, 50, 56, 46, 54, 49, 55 },
{ 51, 44, 56, 49, 54, 44, 52, 50, 53, 46, 57, 50, 57 },
{ 51, 44, 56, 50, 56, 44, 50, 56, 57, 46, 54, 53, 53 },
{ 51, 44, 56, 50, 56, 44, 52, 54, 56, 46, 55, 51, 49 },
{ 51, 44, 56, 51, 53, 44, 55, 54, 54, 46, 48, 52, 51 },
{ 51, 44, 56, 53, 53, 44, 49, 48, 54, 46, 49, 53, 55 },
{ 51, 44, 56, 54, 50, 44, 52, 48, 51, 46, 52, 54, 57 },
{ 51, 44, 56, 55, 52, 44, 50, 54, 55, 46, 49, 57, 53 },
{ 51, 44, 56, 56, 49, 44, 55, 52, 51, 46, 53, 56, 51 },
{ 51, 44, 56, 56, 57, 44, 48, 52, 48, 46, 56, 57, 53 },
{ 51, 44, 57, 48, 48, 44, 57, 48, 52, 46, 54, 50, 49 },
{ 51, 44, 57, 48, 56, 44, 51, 56, 49, 46, 48, 48, 57 },
{ 51, 44, 57, 50, 55, 44, 53, 52, 50, 46, 48, 52, 55 },
{ 51, 44, 57, 50, 55, 44, 55, 50, 49, 46, 49, 50, 51 },
{ 51, 44, 57, 51, 53, 44, 48, 49, 56, 46, 52, 51, 53 },
{ 51, 44, 57, 52, 54, 44, 56, 56, 50, 46, 49, 54, 49 },
{ 51, 44, 57, 53, 52, 44, 51, 53, 56, 46, 53, 52, 57 },
{ 51, 44, 57, 54, 49, 44, 54, 53, 53, 46, 56, 54, 49 },
{ 51, 44, 57, 55, 51, 44, 53, 49, 57, 46, 53, 56, 55 },
{ 51, 44, 57, 56, 48, 44, 57, 57, 53, 46, 57, 55, 53 },
{ 51, 44, 57, 56, 56, 44, 50, 57, 51, 46, 50, 56, 55 },
{ 52, 44, 48, 48, 48, 44, 49, 53, 55, 46, 48, 49, 51 },
{ 52, 44, 48, 48, 55, 44, 54, 51, 51, 46, 52, 48, 49 },
{ 52, 44, 48, 50, 54, 44, 57, 55, 51, 46, 53, 49, 53 },
{ 52, 44, 48, 51, 52, 44, 50, 55, 48, 46, 56, 50, 55 },
{ 52, 44, 48, 52, 54, 44, 49, 51, 52, 46, 53, 53, 51 },
{ 52, 44, 48, 53, 51, 44, 54, 49, 48, 46, 57, 52, 49 },
{ 52, 44, 48, 54, 48, 44, 57, 48, 56, 46, 50, 53, 51 },
{ 52, 44, 48, 55, 50, 44, 55, 55, 49, 46, 57, 55, 57 },
{ 52, 44, 48, 56, 48, 44, 50, 52, 56, 46, 51, 54, 55 },
{ 52, 44, 48, 56, 55, 44, 53, 52, 53, 46, 54, 55, 57 },
{ 52, 44, 48, 57, 57, 44, 52, 48, 57, 46, 52, 48, 53 },
{ 52, 44, 48, 57, 57, 44, 53, 56, 56, 46, 52, 56, 49 },
{ 52, 44, 49, 48, 54, 44, 56, 56, 53, 46, 55, 57, 51 },
{ 52, 44, 49, 50, 54, 44, 50, 50, 53, 46, 57, 48, 55 },
{ 52, 44, 49, 51, 51, 44, 53, 50, 51, 46, 50, 49, 57 },
{ 52, 44, 49, 52, 53, 44, 51, 56, 54, 46, 57, 52, 53 },
{ 52, 44, 49, 53, 50, 44, 56, 54, 51, 46, 51, 51, 51 },
{ 52, 44, 49, 54, 48, 44, 49, 54, 48, 46, 54, 52, 53 },
{ 52, 44, 49, 55, 50, 44, 48, 50, 52, 46, 51, 55, 49 },
{ 52, 44, 49, 55, 57, 44, 53, 48, 48, 46, 55, 53, 57 },
{ 52, 44, 49, 57, 56, 44, 54, 54, 49, 46, 55, 57, 55 },
{ 52, 44, 50, 48, 51, 44, 52, 48, 55, 46, 50, 56, 55 },
{ 52, 44, 50, 49, 48, 44, 55, 48, 52, 46, 53, 57, 57 },
{ 52, 44, 50, 49, 51, 44, 52, 51, 53, 46, 52, 57, 55 },
};
// The array of int[] unicode values storing the expected results
// when calling Decimal.format(double) on the currency GoldenDoubleValues.
static int[][] CurrencyGoldenFormattedValues = {
{ 36, 48, 46, 48, 48 },
{ 40, 36, 48, 46, 48, 48, 41 },
{ 36, 48, 46, 48, 48 },
{ 36, 48, 46, 48, 48 },
{ 40, 36, 50, 44, 49, 52, 55, 44, 52, 56, 51, 44, 54, 52, 54, 46, 50, 51, 41 },
{ 36, 50, 44, 49, 52, 55, 44, 52, 56, 51, 44, 54, 52, 54, 46, 50, 51 },
{ 40, 36, 50, 44, 49, 52, 55, 44, 52, 56, 51, 44, 54, 52, 56, 46, 48, 48, 41 },
{ 36, 50, 44, 49, 52, 55, 44, 52, 56, 51, 44, 54, 52, 56, 46, 48, 48 },
{ 40, 36, 49, 44, 57, 57, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57, 41 },
{ 36, 50, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
{ 65533 },
{ 36, 8734 },
{ 40, 36, 8734, 41 },
{ 36, 49, 55, 57, 44, 55, 54, 57, 44, 51, 49, 51, 44, 52, 56, 54, 44, 50, 51, 49, 44, 53, 55, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
{ 40, 36, 57, 44, 56, 55, 54, 44, 53, 52, 51, 44, 50, 49, 48, 46, 57, 57, 41 },
{ 36, 57, 44, 56, 55, 54, 44, 53, 52, 51, 44, 50, 49, 48, 46, 57, 57 },
{ 40, 36, 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 44, 48, 49, 50, 44, 51, 52, 53, 44, 54, 55, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48, 41 },
{ 36, 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 44, 48, 49, 50, 44, 51, 52, 53, 44, 54, 55, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
{ 36, 49, 46, 49, 50 },
{ 36, 49, 50, 46, 49, 50 },
{ 36, 49, 50, 51, 46, 49, 50 },
{ 36, 49, 44, 50, 51, 52, 46, 49, 50 },
{ 36, 49, 50, 44, 51, 52, 53, 46, 49, 50 },
{ 36, 49, 50, 51, 44, 52, 53, 54, 46, 49, 50 },
{ 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 46, 49, 50 },
{ 36, 49, 50, 44, 51, 52, 53, 44, 54, 55, 56, 46, 49, 50 },
{ 36, 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 46, 49, 50 },
{ 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48, 46, 49, 50 },
{ 40, 36, 49, 46, 49, 50, 41 },
{ 40, 36, 49, 50, 46, 49, 50, 41 },
{ 40, 36, 49, 50, 51, 46, 49, 50, 41 },
{ 40, 36, 49, 44, 50, 51, 52, 46, 49, 50, 41 },
{ 40, 36, 49, 50, 44, 51, 52, 53, 46, 49, 50, 41 },
{ 40, 36, 49, 50, 51, 44, 52, 53, 54, 46, 49, 50, 41 },
{ 40, 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 46, 49, 50, 41 },
{ 40, 36, 49, 50, 44, 51, 52, 53, 44, 54, 55, 56, 46, 49, 50, 41 },
{ 40, 36, 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 46, 49, 50, 41 },
{ 40, 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48, 46, 49, 50, 41 },
{ 36, 48, 46, 49, 48 },
{ 36, 48, 46, 49, 50 },
{ 36, 48, 46, 49, 50 },
{ 36, 49, 48, 46, 49, 48 },
{ 36, 49, 48, 46, 49, 50 },
{ 36, 49, 48, 46, 49, 50 },
{ 36, 49, 48, 48, 46, 49, 48 },
{ 36, 49, 48, 48, 46, 49, 50 },
{ 36, 49, 48, 48, 46, 49, 50 },
{ 36, 49, 44, 48, 48, 48, 46, 49, 48 },
{ 36, 49, 44, 48, 48, 48, 46, 49, 50 },
{ 36, 49, 44, 48, 48, 48, 46, 49, 50 },
{ 36, 49, 48, 44, 48, 48, 48, 46, 49, 48 },
{ 36, 49, 48, 44, 48, 48, 48, 46, 49, 50 },
{ 36, 49, 48, 44, 48, 48, 48, 46, 49, 50 },
{ 36, 49, 48, 48, 44, 48, 48, 48, 46, 49, 48 },
{ 36, 49, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
{ 36, 49, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
{ 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 48 },
{ 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
{ 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
{ 36, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 48 },
{ 36, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
{ 36, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
{ 36, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 48 },
{ 36, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
{ 36, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
{ 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 48 },
{ 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
{ 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
{ 40, 36, 48, 46, 49, 48, 41 },
{ 40, 36, 48, 46, 49, 50, 41 },
{ 40, 36, 48, 46, 49, 50, 41 },
{ 40, 36, 49, 48, 46, 49, 48, 41 },
{ 40, 36, 49, 48, 46, 49, 50, 41 },
{ 40, 36, 49, 48, 46, 49, 50, 41 },
{ 40, 36, 49, 48, 48, 46, 49, 48, 41 },
{ 40, 36, 49, 48, 48, 46, 49, 50, 41 },
{ 40, 36, 49, 48, 48, 46, 49, 50, 41 },
{ 40, 36, 49, 44, 48, 48, 48, 46, 49, 48, 41 },
{ 40, 36, 49, 44, 48, 48, 48, 46, 49, 50, 41 },
{ 40, 36, 49, 44, 48, 48, 48, 46, 49, 50, 41 },
{ 40, 36, 49, 48, 44, 48, 48, 48, 46, 49, 48, 41 },
{ 40, 36, 49, 48, 44, 48, 48, 48, 46, 49, 50, 41 },
{ 40, 36, 49, 48, 44, 48, 48, 48, 46, 49, 50, 41 },
{ 40, 36, 49, 48, 48, 44, 48, 48, 48, 46, 49, 48, 41 },
{ 40, 36, 49, 48, 48, 44, 48, 48, 48, 46, 49, 50, 41 },
{ 40, 36, 49, 48, 48, 44, 48, 48, 48, 46, 49, 50, 41 },
{ 40, 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 48, 41 },
{ 40, 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 41 },
{ 40, 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 41 },
{ 40, 36, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 48, 41 },
{ 40, 36, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 41 },
{ 40, 36, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 41 },
{ 40, 36, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 48, 41 },
{ 40, 36, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 41 },
{ 40, 36, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 41 },
{ 40, 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 48, 41 },
{ 40, 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 41 },
{ 40, 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 41 },
{ 36, 49, 46, 57, 57 },
{ 36, 49, 50, 46, 57, 57 },
{ 36, 49, 50, 51, 46, 57, 57 },
{ 36, 49, 44, 50, 51, 52, 46, 57, 57 },
{ 36, 49, 50, 44, 51, 52, 53, 46, 57, 57 },
{ 36, 49, 50, 51, 44, 52, 53, 54, 46, 57, 57 },
{ 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 46, 57, 57 },
{ 36, 49, 50, 44, 51, 52, 53, 44, 54, 55, 56, 46, 57, 57 },
{ 36, 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 46, 57, 57 },
{ 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48, 46, 57, 57 },
{ 36, 50, 46, 48, 48 },
{ 36, 49, 51, 46, 48, 48 },
{ 36, 49, 50, 52, 46, 48, 48 },
{ 36, 49, 44, 50, 51, 53, 46, 48, 48 },
{ 36, 49, 50, 44, 51, 52, 54, 46, 48, 48 },
{ 36, 49, 50, 51, 44, 52, 53, 55, 46, 48, 48 },
{ 36, 49, 44, 50, 51, 52, 44, 53, 54, 56, 46, 48, 48 },
{ 36, 49, 50, 44, 51, 52, 53, 44, 54, 55, 57, 46, 48, 48 },
{ 36, 49, 50, 51, 44, 52, 53, 54, 44, 55, 57, 48, 46, 48, 48 },
{ 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 49, 46, 48, 48 },
{ 40, 36, 49, 46, 57, 57, 41 },
{ 40, 36, 49, 50, 46, 57, 57, 41 },
{ 40, 36, 49, 50, 51, 46, 57, 57, 41 },
{ 40, 36, 49, 44, 50, 51, 52, 46, 57, 57, 41 },
{ 40, 36, 49, 50, 44, 51, 52, 53, 46, 57, 57, 41 },
{ 40, 36, 49, 50, 51, 44, 52, 53, 54, 46, 57, 57, 41 },
{ 40, 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 46, 57, 57, 41 },
{ 40, 36, 49, 50, 44, 51, 52, 53, 44, 54, 55, 56, 46, 57, 57, 41 },
{ 40, 36, 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 46, 57, 57, 41 },
{ 40, 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48, 46, 57, 57, 41 },
{ 40, 36, 50, 46, 48, 48, 41 },
{ 40, 36, 49, 51, 46, 48, 48, 41 },
{ 40, 36, 49, 50, 52, 46, 48, 48, 41 },
{ 40, 36, 49, 44, 50, 51, 53, 46, 48, 48, 41 },
{ 40, 36, 49, 50, 44, 51, 52, 54, 46, 48, 48, 41 },
{ 40, 36, 49, 50, 51, 44, 52, 53, 55, 46, 48, 48, 41 },
{ 40, 36, 49, 44, 50, 51, 52, 44, 53, 54, 56, 46, 48, 48, 41 },
{ 40, 36, 49, 50, 44, 51, 52, 53, 44, 54, 55, 57, 46, 48, 48, 41 },
{ 40, 36, 49, 50, 51, 44, 52, 53, 54, 44, 55, 57, 48, 46, 48, 48, 41 },
{ 40, 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 49, 46, 48, 48, 41 },
{ 36, 49, 49, 48, 46, 48, 48 },
{ 36, 49, 44, 49, 48, 48, 46, 48, 48 },
{ 36, 49, 49, 44, 48, 48, 48, 46, 48, 48 },
{ 36, 49, 49, 48, 44, 48, 48, 48, 46, 48, 48 },
{ 36, 49, 44, 49, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
{ 36, 49, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
{ 36, 49, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
{ 36, 49, 44, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
{ 40, 36, 49, 49, 48, 46, 48, 48, 41 },
{ 40, 36, 49, 44, 49, 48, 48, 46, 48, 48, 41 },
{ 40, 36, 49, 49, 44, 48, 48, 48, 46, 48, 48, 41 },
{ 40, 36, 49, 49, 48, 44, 48, 48, 48, 46, 48, 48, 41 },
{ 40, 36, 49, 44, 49, 48, 48, 44, 48, 48, 48, 46, 48, 48, 41 },
{ 40, 36, 49, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48, 41 },
{ 40, 36, 49, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48, 41 },
{ 40, 36, 49, 44, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48, 41 },
{ 36, 50, 46, 48, 48 },
{ 36, 50, 48, 46, 48, 48 },
{ 36, 50, 48, 48, 46, 48, 48 },
{ 36, 50, 44, 48, 48, 48, 46, 48, 48 },
{ 36, 50, 48, 44, 48, 48, 48, 46, 48, 48 },
{ 36, 50, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
{ 36, 50, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
{ 36, 50, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
{ 36, 50, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
{ 36, 50, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
{ 40, 36, 50, 46, 48, 48, 41 },
{ 40, 36, 50, 48, 46, 48, 48, 41 },
{ 40, 36, 50, 48, 48, 46, 48, 48, 41 },
{ 40, 36, 50, 44, 48, 48, 48, 46, 48, 48, 41 },
{ 40, 36, 50, 48, 44, 48, 48, 48, 46, 48, 48, 41 },
{ 40, 36, 50, 48, 48, 44, 48, 48, 48, 46, 48, 48, 41 },
{ 40, 36, 50, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48, 41 },
{ 40, 36, 50, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48, 41 },
{ 40, 36, 50, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48, 41 },
{ 40, 36, 50, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48, 41 },
{ 36, 49, 48, 46, 48, 48 },
{ 36, 49, 48, 48, 46, 48, 48 },
{ 36, 49, 44, 48, 48, 48, 46, 48, 48 },
{ 36, 49, 48, 44, 48, 48, 48, 46, 48, 48 },
{ 36, 49, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
{ 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
{ 36, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
{ 36, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
{ 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
{ 36, 57, 46, 57, 57 },
{ 36, 57, 57, 46, 57, 57 },
{ 36, 57, 57, 57, 46, 57, 57 },
{ 36, 57, 44, 57, 57, 57, 46, 57, 57 },
{ 36, 57, 57, 44, 57, 57, 57, 46, 57, 57 },
{ 36, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57 },
{ 36, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57 },
{ 36, 57, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57 },
{ 36, 57, 57, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57 },
{ 40, 36, 49, 48, 46, 48, 48, 41 },
{ 40, 36, 49, 48, 48, 46, 48, 48, 41 },
{ 40, 36, 49, 44, 48, 48, 48, 46, 48, 48, 41 },
{ 40, 36, 49, 48, 44, 48, 48, 48, 46, 48, 48, 41 },
{ 40, 36, 49, 48, 48, 44, 48, 48, 48, 46, 48, 48, 41 },
{ 40, 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48, 41 },
{ 40, 36, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48, 41 },
{ 40, 36, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48, 41 },
{ 40, 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48, 41 },
{ 40, 36, 57, 46, 57, 57, 41 },
{ 40, 36, 57, 57, 46, 57, 57, 41 },
{ 40, 36, 57, 57, 57, 46, 57, 57, 41 },
{ 40, 36, 57, 44, 57, 57, 57, 46, 57, 57, 41 },
{ 40, 36, 57, 57, 44, 57, 57, 57, 46, 57, 57, 41 },
{ 40, 36, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57, 41 },
{ 40, 36, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57, 41 },
{ 40, 36, 57, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57, 41 },
{ 40, 36, 57, 57, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57, 41 },
{ 36, 49, 46, 48, 48 },
{ 36, 49, 50, 46, 48, 48 },
{ 36, 49, 50, 51, 46, 48, 48 },
{ 36, 49, 44, 50, 51, 52, 46, 48, 48 },
{ 36, 49, 50, 44, 51, 52, 53, 46, 48, 48 },
{ 36, 49, 50, 51, 44, 52, 53, 54, 46, 48, 48 },
{ 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 46, 48, 48 },
{ 36, 49, 50, 44, 51, 52, 53, 44, 54, 55, 56, 46, 48, 48 },
{ 36, 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 46, 48, 48 },
{ 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48, 46, 48, 48 },
{ 40, 36, 49, 46, 48, 48, 41 },
{ 40, 36, 49, 50, 46, 48, 48, 41 },
{ 40, 36, 49, 50, 51, 46, 48, 48, 41 },
{ 40, 36, 49, 44, 50, 51, 52, 46, 48, 48, 41 },
{ 40, 36, 49, 50, 44, 51, 52, 53, 46, 48, 48, 41 },
{ 40, 36, 49, 50, 51, 44, 52, 53, 54, 46, 48, 48, 41 },
{ 40, 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 46, 48, 48, 41 },
{ 40, 36, 49, 50, 44, 51, 52, 53, 44, 54, 55, 56, 46, 48, 48, 41 },
{ 40, 36, 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 46, 48, 48, 41 },
{ 40, 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48, 46, 48, 48, 41 },
{ 40, 36, 50, 44, 53, 57, 57, 46, 52, 48, 41 },
{ 40, 36, 50, 44, 53, 57, 57, 46, 51, 52, 41 },
{ 40, 36, 50, 44, 53, 57, 57, 46, 51, 51, 41 },
{ 36, 49, 46, 48, 48 },
{ 36, 49, 46, 48, 48 },
{ 36, 49, 46, 48, 48 },
{ 36, 49, 46, 48, 48 },
{ 36, 49, 46, 48, 48 },
{ 36, 49, 46, 48, 49 },
{ 36, 49, 46, 48, 49 },
{ 36, 49, 46, 48, 49 },
{ 36, 49, 46, 48, 49 },
{ 36, 49, 46, 48, 49 },
{ 36, 49, 46, 50, 50 },
{ 36, 49, 46, 50, 50 },
{ 36, 49, 46, 50, 50 },
{ 36, 49, 46, 50, 50 },
{ 36, 49, 46, 50, 50 },
{ 36, 49, 46, 50, 50 },
{ 36, 49, 46, 50, 50 },
{ 36, 49, 46, 50, 50 },
{ 36, 49, 46, 50, 50 },
{ 36, 49, 46, 50, 50 },
{ 36, 49, 46, 50, 50 },
{ 36, 49, 46, 50, 50 },
{ 36, 49, 46, 50, 50 },
{ 36, 49, 46, 50, 50 },
{ 36, 49, 46, 50, 50 },
{ 36, 49, 46, 50, 50 },
{ 36, 49, 46, 50, 50 },
{ 36, 49, 46, 50, 50 },
{ 36, 49, 46, 50, 50 },
{ 36, 49, 46, 50, 50 },
{ 36, 49, 46, 50, 51 },
{ 36, 49, 46, 50, 51 },
{ 36, 49, 46, 50, 51 },
{ 36, 49, 46, 50, 51 },
{ 36, 49, 46, 50, 51 },
{ 36, 49, 46, 50, 51 },
{ 36, 49, 46, 50, 51 },
{ 36, 49, 46, 50, 51 },
{ 36, 49, 46, 50, 51 },
{ 36, 49, 46, 50, 51 },
{ 36, 49, 46, 50, 51 },
{ 36, 49, 46, 50, 51 },
{ 36, 49, 46, 50, 51 },
{ 36, 49, 46, 50, 51 },
{ 36, 49, 46, 50, 51 },
{ 36, 49, 46, 50, 51 },
{ 36, 49, 46, 50, 51 },
{ 36, 49, 46, 50, 51 },
{ 36, 49, 46, 50, 51 },
{ 36, 49, 46, 50, 51 },
{ 36, 49, 44, 48, 48, 57, 44, 49, 51, 54, 46, 55, 49 },
{ 36, 50, 44, 53, 49, 56, 44, 52, 54, 51, 46, 52, 54 },
{ 36, 50, 44, 53, 51, 50, 44, 52, 51, 56, 46, 56, 51 },
{ 36, 51, 44, 54, 53, 48, 44, 52, 53, 56, 46, 53, 51 },
{ 36, 51, 44, 49, 52, 55, 44, 51, 52, 57, 46, 54, 50 },
{ 36, 53, 44, 52, 49, 49, 44, 51, 51, 57, 46, 55, 53 },
{ 36, 56, 44, 53, 56, 51, 44, 55, 50, 49, 46, 50, 50 },
{ 36, 49, 51, 44, 52, 55, 53, 44, 48, 53, 55, 46, 56, 50 },
{ 36, 51, 51, 44, 53, 56, 56, 44, 52, 52, 49, 46, 57, 56 },
{ 36, 57, 57, 44, 57, 55, 57, 44, 55, 57, 52, 46, 48, 56 },
{ 36, 57, 57, 44, 57, 51, 55, 44, 52, 51, 49, 46, 53, 56 },
{ 36, 57, 57, 44, 51, 56, 54, 44, 55, 49, 57, 46, 48, 56 },
{ 36, 51, 51, 44, 56, 53, 51, 44, 48, 50, 53, 46, 52, 55 },
{ 36, 51, 52, 44, 48, 52, 54, 44, 52, 50, 54, 46, 54, 48 },
{ 36, 51, 52, 44, 51, 49, 50, 44, 56, 48, 48, 46, 56, 55 },
{ 36, 51, 52, 44, 51, 56, 55, 44, 53, 54, 52, 46, 55, 53 },
{ 36, 51, 52, 44, 52, 54, 48, 44, 53, 51, 55, 46, 56, 55 },
{ 36, 51, 52, 44, 53, 55, 57, 44, 49, 55, 53, 46, 49, 50 },
{ 36, 51, 52, 44, 54, 53, 51, 44, 57, 51, 57, 46, 48, 50 },
{ 36, 51, 52, 44, 56, 52, 55, 44, 51, 52, 48, 46, 49, 53 },
{ 36, 51, 52, 44, 57, 50, 48, 44, 51, 49, 51, 46, 50, 55 },
{ 36, 51, 53, 44, 48, 51, 56, 44, 57, 53, 48, 46, 53, 50 },
{ 36, 51, 53, 44, 49, 49, 51, 44, 55, 49, 52, 46, 52, 49 },
{ 36, 51, 53, 44, 49, 56, 54, 44, 54, 56, 55, 46, 53, 51 },
{ 36, 51, 53, 44, 51, 48, 53, 44, 51, 50, 52, 46, 55, 56 },
{ 36, 51, 53, 44, 51, 56, 48, 44, 48, 56, 56, 46, 54, 55 },
{ 36, 51, 53, 44, 52, 53, 51, 44, 48, 54, 49, 46, 55, 57 },
{ 36, 51, 53, 44, 53, 55, 49, 44, 54, 57, 57, 46, 48, 53 },
{ 36, 51, 53, 44, 53, 55, 51, 44, 52, 56, 57, 46, 56, 49 },
{ 36, 51, 53, 44, 54, 52, 54, 44, 52, 54, 50, 46, 57, 51 },
{ 36, 51, 53, 44, 56, 51, 57, 44, 56, 54, 52, 46, 48, 55 },
{ 36, 51, 53, 44, 57, 49, 50, 44, 56, 51, 55, 46, 50, 48 },
{ 36, 51, 54, 44, 48, 51, 49, 44, 52, 55, 52, 46, 52, 53 },
{ 36, 51, 54, 44, 49, 48, 54, 44, 50, 51, 56, 46, 51, 51 },
{ 36, 51, 54, 44, 49, 55, 57, 44, 50, 49, 49, 46, 52, 53 },
{ 36, 51, 54, 44, 50, 57, 55, 44, 56, 52, 56, 46, 55, 48 },
{ 36, 51, 54, 44, 51, 55, 50, 44, 54, 49, 50, 46, 53, 57 },
{ 36, 51, 54, 44, 53, 54, 52, 44, 50, 50, 50, 46, 57, 55 },
{ 36, 51, 54, 44, 53, 54, 54, 44, 48, 49, 51, 46, 55, 51 },
{ 36, 51, 54, 44, 54, 51, 56, 44, 57, 56, 54, 46, 56, 53 },
{ 36, 51, 54, 44, 55, 53, 55, 44, 54, 50, 52, 46, 49, 48 },
{ 36, 51, 54, 44, 56, 51, 50, 44, 51, 56, 55, 46, 57, 57 },
{ 36, 51, 54, 44, 57, 48, 53, 44, 51, 54, 49, 46, 49, 49 },
{ 36, 51, 55, 44, 48, 50, 51, 44, 57, 57, 56, 46, 51, 55 },
{ 36, 51, 55, 44, 48, 57, 56, 44, 55, 54, 50, 46, 50, 53 },
{ 36, 51, 55, 44, 49, 55, 49, 44, 55, 51, 53, 46, 51, 55 },
{ 36, 51, 55, 44, 50, 57, 48, 44, 51, 55, 50, 46, 54, 50 },
{ 36, 51, 55, 44, 51, 54, 53, 44, 49, 51, 54, 46, 53, 50 },
{ 36, 51, 55, 44, 53, 53, 56, 44, 53, 51, 55, 46, 54, 53 },
{ 36, 51, 55, 44, 54, 51, 49, 44, 53, 49, 48, 46, 55, 55 },
{ 36, 51, 55, 44, 55, 53, 48, 44, 49, 52, 56, 46, 48, 50 },
{ 36, 51, 55, 44, 56, 50, 52, 44, 57, 49, 49, 46, 57, 49 },
{ 36, 51, 55, 44, 56, 57, 55, 44, 56, 56, 53, 46, 48, 51 },
{ 36, 51, 56, 44, 48, 49, 54, 44, 53, 50, 50, 46, 50, 56 },
{ 36, 51, 56, 44, 48, 57, 49, 44, 50, 56, 54, 46, 49, 55 },
{ 36, 51, 56, 44, 49, 54, 52, 44, 50, 53, 57, 46, 50, 57 },
{ 36, 51, 56, 44, 50, 56, 50, 44, 56, 57, 54, 46, 53, 53 },
{ 36, 51, 56, 44, 50, 56, 52, 44, 54, 56, 55, 46, 51, 49 },
{ 36, 51, 56, 44, 51, 53, 55, 44, 54, 54, 48, 46, 52, 51 },
{ 36, 51, 56, 44, 53, 53, 49, 44, 48, 54, 49, 46, 53, 55 },
{ 36, 51, 56, 44, 54, 50, 52, 44, 48, 51, 52, 46, 55, 48 },
{ 36, 51, 56, 44, 55, 52, 50, 44, 54, 55, 49, 46, 57, 53 },
{ 36, 51, 56, 44, 56, 49, 55, 44, 52, 51, 53, 46, 56, 51 },
{ 36, 51, 56, 44, 56, 57, 48, 44, 52, 48, 56, 46, 57, 53 },
{ 36, 51, 57, 44, 48, 48, 57, 44, 48, 52, 54, 46, 50, 48 },
{ 36, 51, 57, 44, 48, 56, 51, 44, 56, 49, 48, 46, 48, 57 },
{ 36, 51, 57, 44, 50, 55, 53, 44, 52, 50, 48, 46, 52, 55 },
{ 36, 51, 57, 44, 50, 55, 55, 44, 50, 49, 49, 46, 50, 51 },
{ 36, 51, 57, 44, 51, 53, 48, 44, 49, 56, 52, 46, 51, 53 },
{ 36, 51, 57, 44, 52, 54, 56, 44, 56, 50, 49, 46, 54, 48 },
{ 36, 51, 57, 44, 53, 52, 51, 44, 53, 56, 53, 46, 52, 57 },
{ 36, 51, 57, 44, 54, 49, 54, 44, 53, 53, 56, 46, 54, 49 },
{ 36, 51, 57, 44, 55, 51, 53, 44, 49, 57, 53, 46, 56, 55 },
{ 36, 51, 57, 44, 56, 48, 57, 44, 57, 53, 57, 46, 55, 53 },
{ 36, 51, 57, 44, 56, 56, 50, 44, 57, 51, 50, 46, 56, 55 },
{ 36, 52, 48, 44, 48, 48, 49, 44, 53, 55, 48, 46, 49, 50 },
{ 36, 52, 48, 44, 48, 55, 54, 44, 51, 51, 52, 46, 48, 50 },
{ 36, 52, 48, 44, 50, 54, 57, 44, 55, 51, 53, 46, 49, 53 },
{ 36, 52, 48, 44, 51, 52, 50, 44, 55, 48, 56, 46, 50, 55 },
{ 36, 52, 48, 44, 52, 54, 49, 44, 51, 52, 53, 46, 53, 50 },
{ 36, 52, 48, 44, 53, 51, 54, 44, 49, 48, 57, 46, 52, 49 },
{ 36, 52, 48, 44, 54, 48, 57, 44, 48, 56, 50, 46, 53, 51 },
{ 36, 52, 48, 44, 55, 50, 55, 44, 55, 49, 57, 46, 55, 56 },
{ 36, 52, 48, 44, 56, 48, 50, 44, 52, 56, 51, 46, 54, 55 },
{ 36, 52, 48, 44, 56, 55, 53, 44, 52, 53, 54, 46, 55, 57 },
{ 36, 52, 48, 44, 57, 57, 52, 44, 48, 57, 52, 46, 48, 53 },
{ 36, 52, 48, 44, 57, 57, 53, 44, 56, 56, 52, 46, 56, 49 },
{ 36, 52, 49, 44, 48, 54, 56, 44, 56, 53, 55, 46, 57, 51 },
{ 36, 52, 49, 44, 50, 54, 50, 44, 50, 53, 57, 46, 48, 55 },
{ 36, 52, 49, 44, 51, 51, 53, 44, 50, 51, 50, 46, 50, 48 },
{ 36, 52, 49, 44, 52, 53, 51, 44, 56, 54, 57, 46, 52, 53 },
{ 36, 52, 49, 44, 53, 50, 56, 44, 54, 51, 51, 46, 51, 51 },
{ 36, 52, 49, 44, 54, 48, 49, 44, 54, 48, 54, 46, 52, 53 },
{ 36, 52, 49, 44, 55, 50, 48, 44, 50, 52, 51, 46, 55, 48 },
{ 36, 52, 49, 44, 55, 57, 53, 44, 48, 48, 55, 46, 53, 57 },
{ 36, 52, 49, 44, 57, 56, 54, 44, 54, 49, 55, 46, 57, 55 },
{ 36, 52, 50, 44, 48, 51, 52, 44, 48, 55, 50, 46, 56, 55 },
{ 36, 52, 50, 44, 49, 48, 55, 44, 48, 52, 53, 46, 57, 56 },
{ 36, 52, 50, 44, 49, 51, 52, 44, 51, 53, 52, 46, 57, 56 },
};
}

View File

@ -0,0 +1,795 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @bug 7050528
* @summary Test java.text.DecimalFormat fast-path for format(double...)
* @author Olivier Lagneau
* @run main RoundingAndPropertyTest
*
*/
/* -----------------------------------------------------------------------------
* Note :
* Since fast-path algorithm does not modify any feature of DecimalFormat,
* some tests or values in this program may have to be adapted/added/removed
* when any change has been done in the fast-path source code, because the
* conditions for exercising fast-path may change.
*
* This is specially true if the set of constraints to fall in the fast-path
* case is relaxed in any manner.
*
* Usage :
* - Run main without any argument to test against a set of golden values and
* associated results hard-coded in the source code. That will do the tests
* described below
* See below comment section named "Description".
*
* or
*
* - Run main with string argument "-gengold" to output source code of
* GoldenFormattedValues.java class file with the jdk version used while
* generating the code.
* See below comment section named : "Modifying Golden Values".
*
* In case of error while running the test, a Runtime exception is generated
* providing the numbers of errors detected (format of golden values checks and
* property changes checks), and the program exit.
*
* Description :
*
* This test first checks that localization of digits is done correctly when
* calling DecimalFormat.format() on the array of values DecimalLocalizationValues
* found in GoldenDoubleValues, using the locale FullLocalizationTestLocale
* (from GoldenDoubleValues) that implies localization of digits. it checks the
* the results against expected returned string. In case of formatting error,
* it provides a message informing which value was wrongly formatted.
*
* Then it checks the results of calling NumberFormat.format(double) on a set
* of predefined golden values and checks results against expected returned
* string. It does this both for the decimal case, with an instance returned
* NumberFormat.getInstance() call and for the currency case, with an instance
* returned by NumberFormat.getCurrencyInstance(). Almost all the tested double
* values satisfy the constraints assumed by the fast-path algorithm for
* format(double ...). Some are voluntarily outside the scope of fast-path to
* check that the algorithm correctly eliminate them. In case of formatting
* error a message provides information on the golden value raising the error
* (value, exact decimal value (using BidDecimal), expected result, formatted result).
*
* Last the test checks the status and behavior of a DecimalFormat instance
* when changing properties that make this instance satisfy/invalidate its
* fast-path status, depending on the predefined set of fast-path constraints.
*
* The golden results are predefined arrays of int[] containing the unicode
* ints of the chars in the expected formatted string, when using locale
* provided in GoldenDoubleValues class. The results are those obtained by
* using a reference jdk version (for example one that does not contains the
* DecimalFormat fast-path algorithm, like jdk80-b25).
*
* The double values from which we get golden results are stored inside two
* arrays of double values:
* - DecimalGoldenValues for testing NumberFormat.getInstance().
* - CurrencyGoldenValues for testing NumberFormat.getCurrencyInstance().
* These arrays are located in GoldenDoubleValues.java source file.
*
* For each double value in the arrays above, there is an associated golden
* result. These results are stored in arrays of int[]:
* - DecimalGoldenFormattedValues for expected decimal golden results.
* - CurrencyGoldenFormattedValues for expected currency golden results.
* - DecimalDigitsLocalizedFormattedValues for expected localized digit results.
*
* We store the results in int[] arrays containing the expected unicode values
* because the compiler that will compile the containing java file may use a
* different locale than the one registered in GoldenDoubleValues.java. These
* arrays are located in a separate GoldenFormattedValues.java source file
* that is generated by RoundingAndPropertyTest using "-gengold" parameter.
* See below "Modifying Golden Values".
*
* The golden value arrays can be expanded, modified ... to test additional
* or different double values. In that case, the source file of class
* GoldenFormattedValues must be regenerated to replace the existing one..
*
* Modifying Golden Values :
*
* In order to ease further modification of the list of double values checked
* and associated golden results, the test includes the method
* generatesGoldenFormattedValuesClass() that writes on standard output stream
* the source code for GoldenFormattedValues class that includes the expected
* results arrays.
*
* Here are the steps to follow for updating/modifying golden values and results:
* 1- Edit GoldenDoubleValues.java to add/remove/modify golden or localization
* values.
* 2- Run main with "-gengold" string argument with a target jdk.
* (at the creation of this test file, the target jdk used was jdk1.8.0-ea).
* 2- Copy this java code that has been writen on standard output and replace
* GoldenFormattedValues.java contents by the generated output.
* 3- Check that this updated code compiles.
* [4]- If needed replaces existing GoldenDoubleValues and GoldenFormattedValues
* files in jdk/test section, respectively by the one modified at step 1 and
* generated at step 2.
* -----------------------------------------------------------------------------
*/
import java.util.*;
import java.text.NumberFormat;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.math.RoundingMode;
import java.math.BigDecimal;
public class RoundingAndPropertyTest {
// Prints on standard output stream the unicode values of chars as a
// comma-separated list of int values
private static void printUnicodeValuesArray(char[] chars) {
for (int i = 0; i < chars.length; i++) {
System.out.print((int) chars[i]);
if (i != (chars.length - 1))
System.out.print(", ");
}
}
// Converts given array of unicode values as an array of chars.
// Returns this converted array.
private static char[] getCharsFromUnicodeArray(int[] unicodeValues) {
char[] chars = new char[unicodeValues.length];
for (int i = 0; i < unicodeValues.length; i++) {
chars[i] = (char) unicodeValues[i];
}
return chars;
}
/* Prints on standard output stream the java code of resulting
* GoldenFormattedValues class for the golden values found in
* class GoldenDoubleValues.
*/
private static void generatesGoldenFormattedValuesClass() {
String fourWhiteSpaces = " ";
String eightWhiteSpaces = " ";
// Prints header without Copyright header.
System.out.println("/* This is a machine generated file - Please DO NOT EDIT !");
System.out.println(" * Change RoundingAndPropertyTest instead,");
System.out.println(" * and run with \"-gengold\" argument to regenerate (without copyright header).");
System.out.println(" */");
System.out.println();
System.out.println("/* This file contains the set of result Strings expected from calling inside");
System.out.println(" * RoundingAndPropertyTest the method NumberFormat.format() upon the set of");
System.out.println(" * double values provided in GoldenDoubleValues.java. It contains three arrays,");
System.out.println(" * each containing arrays of unicode values representing the expected string");
System.out.println(" * result when calling format() on the corresponding (i.e. same index) double");
System.out.println(" * value found in GoldenDoubleValues arrays :");
System.out.println(" * - DecimalDigitsLocalizedFormattedValues corresponds to DecimalLocalizationValues,");
System.out.println(" * when using FullLocalizationTestLocale to format.");
System.out.println(" * - DecimalGoldenFormattedValues corresponds to DecimalGoldenValues, when used");
System.out.println(" * in the decimal pattern case together with TestLocale.");
System.out.println(" * - CurrencyGoldenFormattedValues corresponds to CurrencyGoldenValues. when used");
System.out.println(" * in the currency pattern case together with TestLocale.");
System.out.println(" * Please see documentation in RoundingAndPropertyTest.java for more details.");
System.out.println(" *");
System.out.println(" * This file generated by running RoundingAndPropertyTest with \"-gengold\" argument.");
System.out.println(" */");
System.out.println();
// Prints beginning of class GoldenFormattedValues.
System.out.println("class GoldenFormattedValues {");
System.out.println();
System.out.println(
fourWhiteSpaces +
"// The formatted values below were generated from golden values");
System.out.print(
fourWhiteSpaces +
"// listed in GoldenDoubleValues.java,");
System.out.println(" using the following jvm version :");
System.out.println(
fourWhiteSpaces + "// " +
System.getProperty("java.vendor") +
" " +
System.getProperty("java.vm.name") +
" " +
System.getProperty("java.version"));
System.out.println(
fourWhiteSpaces +
"// locale for golden double values : " + GoldenDoubleValues.TestLocale);
System.out.println(
fourWhiteSpaces +
"// locale for testing digit localization : " + GoldenDoubleValues.FullLocalizationTestLocale);
System.out.println();
// Prints the expected results when digit localization happens
System.out.println(
fourWhiteSpaces +
"// The array of int[] unicode values storing the expected results");
System.out.print(
fourWhiteSpaces +
"// when experiencing full localization of digits");
System.out.println(" on DecimalLocalizationValues.");
System.out.println(
fourWhiteSpaces +
"static int[][] DecimalDigitsLocalizedFormattedValues = {");
NumberFormat df =
NumberFormat.getInstance(GoldenDoubleValues.FullLocalizationTestLocale);
for (int i = 0;
i < GoldenDoubleValues.DecimalLocalizationValues.length;
i++) {
double d = GoldenDoubleValues.DecimalLocalizationValues[i];
String formatted = df.format(d);
char[] decFmtChars = formatted.toCharArray();
System.out.print(eightWhiteSpaces + "{ ");
printUnicodeValuesArray(decFmtChars);
System.out.println(" },");
}
System.out.println(fourWhiteSpaces + "};");
System.out.println();
// Prints the golden expected results for the decimal pattern case
System.out.println(
fourWhiteSpaces +
"// The array of int[] unicode values storing the expected results");
System.out.print(
fourWhiteSpaces +
"// when calling Decimal.format(double)");
System.out.println(" on the decimal GoldenDoubleValues.");
System.out.println(
fourWhiteSpaces +
"static int[][] DecimalGoldenFormattedValues = {");
df = NumberFormat.getInstance(GoldenDoubleValues.TestLocale);
for (int i = 0;
i < GoldenDoubleValues.DecimalGoldenValues.length;
i++) {
double d = GoldenDoubleValues.DecimalGoldenValues[i];
String formatted = df.format(d);
char[] decFmtChars = formatted.toCharArray();
System.out.print(eightWhiteSpaces + "{ ");
printUnicodeValuesArray(decFmtChars);
System.out.println(" },");
}
System.out.println(fourWhiteSpaces + "};");
System.out.println();
// Prints the golden expected results for the currency pattern case
System.out.println(
fourWhiteSpaces +
"// The array of int[] unicode values storing the expected results");
System.out.print(
fourWhiteSpaces +
"// when calling Decimal.format(double)");
System.out.println(" on the currency GoldenDoubleValues.");
System.out.println(
fourWhiteSpaces +
"static int[][] CurrencyGoldenFormattedValues = {");
NumberFormat cf =
NumberFormat.getCurrencyInstance(GoldenDoubleValues.TestLocale);
for (int i = 0;
i < GoldenDoubleValues.CurrencyGoldenValues.length;
i++) {
double d = GoldenDoubleValues.CurrencyGoldenValues[i];
String formatted = cf.format(d);
char[] decFmtChars = formatted.toCharArray();
System.out.print(eightWhiteSpaces + "{ ");
printUnicodeValuesArray(decFmtChars);
System.out.println(" },");
}
System.out.println(fourWhiteSpaces + "};");
System.out.println();
// Prints end of GoldenFormattedValues class.
System.out.println("}");
}
private static int testLocalizationValues() {
DecimalFormat df = (DecimalFormat)
NumberFormat.getInstance(GoldenDoubleValues.FullLocalizationTestLocale);
double[] localizationValues = GoldenDoubleValues.DecimalLocalizationValues;
int size = localizationValues.length;
int successCounter = 0;
int failureCounter = 0;
for (int i = 0; i < size; i++) {
double d = localizationValues[i];
String formatted = df.format(d);
char[] expectedUnicodeArray =
getCharsFromUnicodeArray(
GoldenFormattedValues.DecimalDigitsLocalizedFormattedValues[i]);
String expected = new String(expectedUnicodeArray);
if (!formatted.equals(expected)) {
failureCounter++;
System.out.println(
"--- Localization error for value d = " + d +
". Exact value = " + new BigDecimal(d).toString() +
". Expected result = " + expected +
". Output result = " + formatted);
} else successCounter++;
}
System.out.println("Checked positively " + successCounter +
" golden decimal values out of " + size +
" tests. There were " + failureCounter +
" format failure");
return failureCounter;
}
private static int testGoldenValues(java.text.DecimalFormat df,
java.text.DecimalFormat cf) {
double[] goldenDecimalValues = GoldenDoubleValues.DecimalGoldenValues;
int decimalSize = goldenDecimalValues.length;
int decimalSuccessCounter = 0;
int decimalFailureCounter = 0;
for (int i = 0; i < decimalSize; i++) {
double d = goldenDecimalValues[i];
String formatted = df.format(d);
char[] expectedUnicodeArray =
getCharsFromUnicodeArray(
GoldenFormattedValues.DecimalGoldenFormattedValues[i]);
String expected = new String(expectedUnicodeArray);
if (!formatted.equals(expected)) {
decimalFailureCounter++;
System.out.println(
"--- Error for golden value d = " + d +
". Exact value = " + new BigDecimal(d).toString() +
". Expected result = " + expected +
". Output result = " + formatted);
} else decimalSuccessCounter++;
}
System.out.println("Checked positively " + decimalSuccessCounter +
" golden decimal values out of " + decimalSize +
" tests. There were " + decimalFailureCounter +
" format failure");
double[] goldenCurrencyValues = GoldenDoubleValues.CurrencyGoldenValues;
int currencySize = goldenCurrencyValues.length;
int currencySuccessCounter = 0;
int currencyFailureCounter = 0;
for (int i = 0; i < currencySize; i++) {
double d = goldenCurrencyValues[i];
String formatted = cf.format(d);
char[] expectedUnicodeArray =
getCharsFromUnicodeArray(
GoldenFormattedValues.CurrencyGoldenFormattedValues[i]);
String expected = new String(expectedUnicodeArray);
if (!formatted.equals(expected)) {
currencyFailureCounter++;
System.out.println(
"--- Error for golden value d = " + d +
". Exact value = " + new BigDecimal(d).toString() +
". Expected result = " + expected +
". Output result = " + formatted);
} else currencySuccessCounter++;
}
System.out.println("Checked positively " + currencySuccessCounter +
" golden currency values out of " + currencySize +
" tests. There were " + currencyFailureCounter +
" format failure");
return (decimalFailureCounter + currencyFailureCounter);
}
// Checks that the two passed s1 and s2 string are equal, and prints
// out message in case of error.
private static boolean resultsEqual(String propertyName,
String s1,
String s2) {
boolean equality = s1.equals(s2);
if (!equality)
System.out.println(
"\n*** Error while reverting to default " +
propertyName + " property.\n" +
" initial output = " + s1 +
". reverted output = " + s2 + ".");
else System.out.println(" Test passed.");
return equality;
}
/* This methods checks the behaviour of the management of properties
* of a DecimalFormat instance that satisfies fast-path constraints.
*
* It does this by comparing the results of the format(double) output
* obtained from initial fast-path state with the output provided by
* the same instance that has been pushed and exercised outside
* fast-path rules and finally "reverted" to its initial fast-path state.
*
* The schema of actions is this :
* - Call format(double) on a known DecimalFormat fast-path instance,
* and store this result.
* - Record the current state of a given property.
* - Change the property to invalidate the fast-path state.
* - Call again format(double) on the instance.
* - Revert state of property to validate again fast-path context.
* - Call format(double) again.
* - Check that first and last call to format(double) provide same result
* - Record failure if any.
* - Do the same for another property with the same instance.
* So all the property changes are chained one after the other on only the
* same instance.
*
* Some properties that currently do not influence the fast-path state
* are also tested. This is not useful with current fast-path source
* but is here for testing the whole set of properties. This is the case
* for prefixes and suffixes, and parseBigDecimal properties.
*/
private static int testSettersAndFastPath(DecimalFormat df,
boolean isCurrency) {
final double d1 = GoldenDoubleValues.PROPERTY_CHECK_POSITIVE_VALUE;
final double d2 = GoldenDoubleValues.PROPERTY_CHECK_NEGATIVE_VALUE;
int errors = 0;
boolean testSucceeded = false;
String firstFormatResult;
String secondFormatResult;
String propertyName;
// ---- positivePrefix property test ----
testSucceeded = false;
propertyName = "positivePrefix";
System.out.print("Checking " + propertyName + " property.");
String initialPrefix = df.getPositivePrefix();
firstFormatResult = df.format(d1);
df.setPositivePrefix("positivePrefix:");
df.format(d1);
df.setPositivePrefix(initialPrefix);
secondFormatResult = df.format(d1);
testSucceeded =
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
if (!testSucceeded)
errors++;
// ---- positiveSuffix property test ----
testSucceeded = false;
propertyName = "positiveSuffix";
System.out.print("Checking " + propertyName + " property.");
String initialSuffix = df.getPositiveSuffix();
firstFormatResult = df.format(d1);
df.setPositiveSuffix("positiveSuffix:");
df.format(d1);
df.setPositiveSuffix(initialSuffix);
secondFormatResult = df.format(d1);
testSucceeded =
resultsEqual(propertyName,firstFormatResult, secondFormatResult);
if (!testSucceeded)
errors++;
// ---- negativePrefix property test ----
testSucceeded = false;
propertyName = "negativePrefix";
System.out.print("Checking " + propertyName + " property.");
initialPrefix = df.getNegativePrefix();
firstFormatResult = df.format(d1);
df.setNegativePrefix("negativePrefix:");
df.format(d1);
df.setNegativePrefix(initialPrefix);
secondFormatResult = df.format(d1);
testSucceeded =
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
if (!testSucceeded)
errors++;
// ---- negativeSuffix property test ----
testSucceeded = false;
propertyName = "negativeSuffix";
System.out.print("Checking " + propertyName + " property.");
initialSuffix = df.getNegativeSuffix();
firstFormatResult = df.format(d1);
df.setNegativeSuffix("negativeSuffix:");
df.format(d1);
df.setNegativeSuffix(initialSuffix);
secondFormatResult = df.format(d1);
testSucceeded =
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
if (!testSucceeded)
errors++;
// ---- multiplier property test ----
testSucceeded = false;
propertyName = "multiplier";
System.out.print("Checking " + propertyName + " property.");
int initialMultiplier = df.getMultiplier();
firstFormatResult = df.format(d1);
df.setMultiplier(10);
df.format(d1);
df.setMultiplier(initialMultiplier);
secondFormatResult = df.format(d1);
testSucceeded =
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
if (!testSucceeded)
errors++;
// ---- groupingUsed property test ----
testSucceeded = false;
propertyName = "groupingUsed";
System.out.print("Checking " + propertyName + " property.");
boolean initialGroupingUsed = df.isGroupingUsed();
firstFormatResult = df.format(d1);
df.setGroupingUsed(!initialGroupingUsed);
df.format(d1);
df.setGroupingUsed(initialGroupingUsed);
secondFormatResult = df.format(d1);
testSucceeded =
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
if (!testSucceeded)
errors++;
// ---- groupingSize property test ----
testSucceeded = false;
propertyName = "groupingSize";
System.out.print("Checking " + propertyName + " property.");
int initialGroupingSize = df.getGroupingSize();
firstFormatResult = df.format(d1);
df.setGroupingSize(initialGroupingSize + 1);
df.format(d1);
df.setGroupingSize(initialGroupingSize);
secondFormatResult = df.format(d1);
testSucceeded =
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
if (!testSucceeded)
errors++;
// ---- decimalSeparatorAlwaysShown property test ----
testSucceeded = false;
propertyName = "decimalSeparatorAlwaysShown";
System.out.print("Checking " + propertyName + " property.");
boolean initialDSShown = df.isDecimalSeparatorAlwaysShown();
firstFormatResult = df.format(d1);
df.setDecimalSeparatorAlwaysShown(!initialDSShown);
df.format(d1);
df.setDecimalSeparatorAlwaysShown(initialDSShown);
secondFormatResult = df.format(d1);
testSucceeded =
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
if (!testSucceeded)
errors++;
// ---- parseBigDecimal property test ----
testSucceeded = false;
propertyName = "parseBigDecimal";
System.out.print("Checking " + propertyName + " property.");
boolean initialParseBigdecimal = df.isParseBigDecimal();
firstFormatResult = df.format(d1);
df.setParseBigDecimal(!initialParseBigdecimal);
df.format(d1);
df.setParseBigDecimal(initialParseBigdecimal);
secondFormatResult = df.format(d1);
testSucceeded =
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
if (!testSucceeded)
errors++;
// ---- maximumIntegerDigits property test ----
testSucceeded = false;
propertyName = "maximumIntegerDigits";
System.out.print("Checking " + propertyName + " property.");
int initialMaxIDs = df.getMaximumIntegerDigits();
firstFormatResult = df.format(d1);
df.setMaximumIntegerDigits(8);
df.format(d1);
df.setMaximumIntegerDigits(initialMaxIDs);
secondFormatResult = df.format(d1);
testSucceeded =
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
if (!testSucceeded)
errors++;
// ---- minimumIntegerDigits property test ----
testSucceeded = false;
propertyName = "minimumIntegerDigits";
System.out.print("Checking " + propertyName + " property.");
int initialMinIDs = df.getMinimumIntegerDigits();
firstFormatResult = df.format(d1);
df.setMinimumIntegerDigits(2);
df.format(d1);
df.setMinimumIntegerDigits(initialMinIDs);
secondFormatResult = df.format(d1);
testSucceeded =
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
if (!testSucceeded)
errors++;
// ---- maximumFractionDigits property test ----
testSucceeded = false;
propertyName = "maximumFractionDigits";
System.out.print("Checking " + propertyName + " property.");
firstFormatResult = df.format(d1);
df.setMaximumFractionDigits(8);
df.format(d1);
if (isCurrency) {
df.setMinimumFractionDigits(2);
df.setMaximumFractionDigits(2);
} else {
df.setMinimumFractionDigits(0);
df.setMaximumFractionDigits(3);
}
secondFormatResult = df.format(d1);
testSucceeded =
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
if (!testSucceeded)
errors++;
// ---- minimumFractionDigits property test ----
testSucceeded = false;
propertyName = "minimumFractionDigits";
System.out.print("Checking " + propertyName + " property.");
firstFormatResult = df.format(d1);
df.setMinimumFractionDigits(1);
df.format(d1);
if (isCurrency) {
df.setMinimumFractionDigits(2);
df.setMaximumFractionDigits(2);
} else {
df.setMinimumFractionDigits(0);
df.setMaximumFractionDigits(3);
}
secondFormatResult = df.format(d1);
testSucceeded =
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
if (!testSucceeded)
errors++;
// ---- currency property test ----
testSucceeded = false;
propertyName = "currency";
System.out.print("Checking " + propertyName + " property.");
Currency initialCurrency = df.getCurrency();
Currency japanCur = java.util.Currency.getInstance(Locale.JAPAN);
firstFormatResult = df.format(d1);
df.setCurrency(japanCur);
df.format(d1);
df.setCurrency(initialCurrency);
secondFormatResult = df.format(d1);
testSucceeded =
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
if (!testSucceeded)
errors++;
// ---- roundingMode property test ----
testSucceeded = false;
propertyName = "roundingMode";
System.out.print("Checking " + propertyName + " property.");
RoundingMode initialRMode = df.getRoundingMode();
firstFormatResult = df.format(d1);
df.setRoundingMode(RoundingMode.HALF_UP);
df.format(d1);
df.setRoundingMode(RoundingMode.HALF_EVEN);
secondFormatResult = df.format(d1);
testSucceeded =
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
if (!testSucceeded)
errors++;
// ---- decimalFormatSymbols property test ----
testSucceeded = false;
propertyName = "decimalFormatSymbols";
System.out.print("Checking " + propertyName + " property.");
DecimalFormatSymbols initialDecimalFormatSymbols = df.getDecimalFormatSymbols();
firstFormatResult = df.format(d1);
Locale bizarreLocale = new Locale("fr", "FR");
DecimalFormatSymbols unusualSymbols = new DecimalFormatSymbols(bizarreLocale);
unusualSymbols.setDecimalSeparator('@');
unusualSymbols.setGroupingSeparator('|');
df.setDecimalFormatSymbols(unusualSymbols);
df.format(d1);
df.setDecimalFormatSymbols(initialDecimalFormatSymbols);
secondFormatResult = df.format(d1);
testSucceeded =
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
if (!testSucceeded)
errors++;
testSucceeded = false;
System.out.print("Checking " + propertyName + " property.");
initialDecimalFormatSymbols = df.getDecimalFormatSymbols();
firstFormatResult = df.format(d1);
Locale japanLocale = Locale.JAPAN;
unusualSymbols = new DecimalFormatSymbols(japanLocale);
unusualSymbols.setDecimalSeparator('9');
unusualSymbols.setGroupingSeparator('0');
df.setDecimalFormatSymbols(unusualSymbols);
df.format(d1);
df.setDecimalFormatSymbols(initialDecimalFormatSymbols);
secondFormatResult = df.format(d1);
testSucceeded =
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
if (!testSucceeded)
errors++;
return errors;
}
// Main for RoundingAndPropertyTest. We test first the golden values,
// and then the property setters and getters.
public static void main(String[] args) {
if ((args.length >= 1) &&
(args[0].equals("-gengold")))
generatesGoldenFormattedValuesClass();
else {
System.out.println("\nChecking correctness of formatting with digit localization.");
System.out.println("=============================================================");
int localizationErrors = testLocalizationValues();
if (localizationErrors != 0)
System.out.println("*** Failure in localization tests : " +
localizationErrors + " errors detected ");
else System.out.println(" Tests for full localization of digits all passed.");
DecimalFormat df = (DecimalFormat)
NumberFormat.getInstance(GoldenDoubleValues.TestLocale);
DecimalFormat cf = (DecimalFormat)
NumberFormat.getCurrencyInstance(GoldenDoubleValues.TestLocale);
System.out.println("\nChecking correctness of formating for golden values.");
System.out.println("=============================================================");
int goldenValuesErrors = testGoldenValues(df,cf);
if (goldenValuesErrors != 0)
System.out.println("*** Failure in goldenValues tests : " +
goldenValuesErrors + " errors detected ");
else System.out.println(" Tests for golden values all passed.");
System.out.println("\nChecking behavior of property changes for decimal case.");
System.out.println("=============================================================");
int decimalTestsErrors = testSettersAndFastPath(df, false);
if (decimalTestsErrors != 0)
System.out.println("*** Failure in decimal property changes tests : " +
decimalTestsErrors + " errors detected ");
else System.out.println(" Tests for decimal property changes all passed.");
System.out.println("\nChecking behavior of property changes for currency case.");
System.out.println("=============================================================");
int currencyTestsErrors = testSettersAndFastPath(cf, true);
if (currencyTestsErrors != 0)
System.out.println("*** Failure in currency property changes tests : " +
currencyTestsErrors + " errors detected ");
else System.out.println(" Tests for currency property chamges all passed.");
if ((localizationErrors > 0) ||
(goldenValuesErrors > 0) ||
(decimalTestsErrors > 0) ||
(currencyTestsErrors > 0))
throw new RuntimeException(
"Failed with " +
(localizationErrors + goldenValuesErrors +
decimalTestsErrors + currencyTestsErrors) +
" error(s).");
}
}
}