/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.f1x.util.format;
import org.junit.Test;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.Random;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
public class Test_DoubleFormatter2 {
private static final int MAX_WIDTH = 512;
private final byte[] buffer = new byte[MAX_WIDTH];
@Test
public void testAroundBoundariesOfLong() {
assertFormat(0.99e19, "99000000000000000000", 1);
//assertFormat(0.99e-19, "0.99", 1);
assertFormat(0.99e-19, "0", 1);
}
@Test
public void testSimple() {
assertFormat(1.234, "1.234", 3);
assertFormat(0.123, "0.123", 3);
assertFormat(12.345, "12", 0);
assertFormat(12.345, "12.3", 1);
assertFormat(12.345, "12.35", 2); // rounding up
assertFormat(12.344, "12.34", 2); // rounding down
assertFormat(12.345, "12.345", 3);
assertFormat(12.345, "12.345", 4);
assertFormat(12.345, "12.345", 5);
}
@Test
public void testBug() {
assertFormat(-92233720368547760.0, "-92233720368547760", 2);
}
@Test
public void testNegative() {
assertFormat(-1.23, "-1.23", 3);
}
@Test
public void powerOfTen() {
assertFormat(0.0001, "0", 3);
assertFormat(0.001, "0.001", 3);
assertFormat(0.01, "0.01", 3);
assertFormat(0.1, "0.1", 3);
assertFormat(1, "1", 3);
assertFormat(10, "10", 3);
assertFormat(100, "100", 3);
assertFormat(1000, "1000", 3);
assertFormat(10000, "10000", 3);
assertFormat(100000, "100000", 3);
}
@Test
public void powerOfTenNegative() {
assertFormat(-0.0001, "-0", 3);
assertFormat(-0.001, "-0.001", 3);
assertFormat(-0.01, "-0.01", 3);
assertFormat(-0.1, "-0.1", 3);
assertFormat(-1, "-1", 3);
assertFormat(-10, "-10", 3);
assertFormat(-100, "-100", 3);
assertFormat(-1000, "-1000", 3);
assertFormat(-10000, "-10000", 3);
assertFormat(-100000, "-100000", 3);
}
@Test
public void testWholeNumbers() {
assertFormat(1, "1", 3);
assertFormat(123, "123", 3);
assertFormat(1, "1", 0);
assertFormat(123, "123", 0);
}
@Test
public void testPrecision0() {
assertFormat(12345.6, "12346", 0);
assertFormat(1234.56, "1235", 0);
assertFormat(123.456, "123", 0);
assertFormat(12.3456, "12", 0);
assertFormat(1.23456, "1", 0);
assertFormat(0.123456, "0", 0);
assertFormat(0.0123456, "0", 0);
assertFormat(0.0012345, "0", 0);
assertFormat(0.0001234, "0", 0);
assertFormat(0.0000123, "0", 0);
assertFormat(0.0000012, "0", 0);
assertFormat(0.0000001, "0", 0);
}
@Test
public void testPrecision1() {
assertFormat(123456., "123456", 1);
assertFormat(12345.6, "12345.6", 1);
assertFormat(1234.56, "1234.6", 1);
assertFormat(123.456, "123.5", 1);
assertFormat(12.3456, "12.3", 1);
assertFormat(1.23456, "1.2", 1);
assertFormat(0.123456, "0.1", 1);
assertFormat(0.0123456, "0", 1);
assertFormat(0.0012345, "0", 1);
assertFormat(0.0001234, "0", 1);
assertFormat(0.0000123, "0", 1);
assertFormat(0.0000012, "0", 1);
assertFormat(0.0000001, "0", 1);
}
@Test
public void testPrecision2() {
assertFormat(123456., "123456", 2);
assertFormat(12345.6, "12345.6", 2);
assertFormat(1234.56, "1234.56", 2);
assertFormat(123.456, "123.46", 2);
assertFormat(12.3456, "12.35", 2);
assertFormat(1.23456, "1.23", 2);
assertFormat(0.123456, "0.12", 2);
assertFormat(0.0123456, "0.01", 2);
assertFormat(0.0012345, "0", 2);
assertFormat(0.0001234, "0", 2);
assertFormat(0.0000123, "0", 2);
assertFormat(0.0000012, "0", 2);
assertFormat(0.0000001, "0", 2);
}
@Test
public void testPrecision3() {
assertFormat(123456., "123456", 3);
assertFormat(12345.6, "12345.6", 3);
assertFormat(1234.56, "1234.56", 3);
assertFormat(123.456, "123.456", 3);
assertFormat(12.3456, "12.346", 3);
assertFormat(1.23456, "1.235", 3);
assertFormat(0.123456, "0.123", 3);
assertFormat(0.0123456, "0.012", 3);
assertFormat(0.0012345, "0.001", 3);
assertFormat(0.0001234, "0", 3);
assertFormat(0.0000123, "0", 3);
assertFormat(0.0000012, "0", 3);
assertFormat(0.0000001, "0", 3);
}
@Test
public void testZeros() {
assertFormat(0, "0", 3);
assertFormat(-2.0 / Float.POSITIVE_INFINITY, "0", 3);
assertFormat(-0., "0", 3);
}
@Test
public void testPeriodic() {
assertFormat(1.0 / 3.0, "0.333333333", 9);
}
@Test
public void testDoubleMaxValue() {
assertFormat(Double.MAX_VALUE, "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368", DoubleFormatter.MAX_PRECISION);
}
@Test
public void testLongMaxValue() {
assertFormat(Long.MAX_VALUE, "9223372036854775808", DoubleFormatter.MAX_PRECISION);
}
@Test
public void testDoubleMinValue() {
assertFormat(Double.MIN_VALUE, "0", DoubleFormatter.MAX_PRECISION);
}
@Test
public void testLongMinValue() {
assertFormat(Long.MIN_VALUE, "-9223372036854775808", DoubleFormatter.MAX_PRECISION);
}
@Test
public void testNaN() {
try {
DoubleFormatter2.format(Double.NaN, 3, buffer, 0);
fail("Failed to detect NaN");
} catch (IllegalArgumentException expected) {
}
}
@Test
public void testInfinity() {
try {
DoubleFormatter2.format(Double.POSITIVE_INFINITY, 3, buffer, 0);
fail("Failed to detect positive INFINITY");
} catch (IllegalArgumentException expected) {
}
try {
DoubleFormatter2.format(Double.NEGATIVE_INFINITY, 3, buffer, 0);
fail("Failed to detect negative INFINITY");
} catch (IllegalArgumentException expected) {
}
}
private static void assertFormat(double number, int precision, DecimalFormat standardFormat) {
String expected = standardFormat.format(number);
if (expected.equals("-0"))
expected = "0";
String actual;
try {
byte[] buffer = new byte[MAX_WIDTH];
int length = DoubleFormatter2.format(number, precision, buffer, 0);
actual = new String(buffer, 0, length);
} catch (Exception e) {
throw new RuntimeException("Error formatting " + number + ": " + e.getMessage(), e);
}
// assertEquals (expected, actual);
if (!expected.equals(actual)) {
System.err.println("WARN: " + number + " formatted as " + actual);
assertEquals(number, Double.valueOf(actual), PRECISION);
}
}
private static final double PRECISION = 0.0000000000000000000001;
private static void assertFormat(double number, String expected, int precision) {
byte[] buffer = new byte[MAX_WIDTH];
int length = DoubleFormatter2.format(number, precision, buffer, 0);
String actual = new String(buffer, 0, length);
if (!expected.equals(actual)) {
assertEquals(number, Double.valueOf(actual), PRECISION);
}
}
@Test
public void testEnum() {
DecimalFormat standardFormat = new DecimalFormat("###.##");
standardFormat.setRoundingMode(RoundingMode.HALF_UP);
double number = 0.01 * Long.MIN_VALUE;
while (number < -0.01) {
assertFormat(number, 2, standardFormat);
number = number / 10;
}
number = 0.01 * Long.MAX_VALUE;
while (number > 0.01) {
assertFormat(number, 2, standardFormat);
number = number / 10;
}
}
@Test
public void testRandom() {
DecimalFormat standardFormat = new DecimalFormat("###.#####");
standardFormat.setRoundingMode(RoundingMode.HALF_UP);
Random rnd = new Random(13132);
for (int i = 0; i < 100000; i++) {
double number = rnd.nextDouble() * Math.pow(10, rnd.nextInt(8));
assertFormat(number, 5, standardFormat);
}
}
@Test
public void testBug1() {
DecimalFormat standardFormat = new DecimalFormat("###.##");
standardFormat.setRoundingMode(RoundingMode.HALF_UP);
assertEquals("standardFormat", "49405.99", standardFormat.format(49405.994999999995));
assertFormat(49405.994999999995, 2, standardFormat);
}
//@Test
public static void enumerateAll() {
double number = -10000, step = 0.000003;
DecimalFormat standardFormat = new DecimalFormat("###.##");
standardFormat.setRoundingMode(RoundingMode.HALF_UP);
while (number < 100000) {
assertFormat(number, 2, standardFormat);
number += step;
}
}
public static void main(String[] args) {
enumerateAll();
}
}