package org.solovyev.common; import org.junit.Before; import org.junit.Test; import java.math.BigInteger; import static java.lang.Math.pow; import static java.math.BigInteger.TEN; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.solovyev.common.NumberFormatter.DEFAULT_MAGNITUDE; import static org.solovyev.common.NumberFormatter.NO_ROUNDING; public class NumberFormatterTest { private NumberFormatter numberFormatter; @Before public void setUp() throws Exception { numberFormatter = new NumberFormatter(); } @Test public void testEngineeringFormat() throws Exception { numberFormatter.useEngineeringFormat(5); assertEquals("0.1", numberFormatter.format(0.1d)); assertEquals("0.01", numberFormatter.format(0.01d)); assertEquals("0.001", numberFormatter.format(0.001d)); assertEquals("5", numberFormatter.format(5d)); assertEquals("5000", numberFormatter.format(5000d)); } @Test public void testScientificFormatNoRounding() throws Exception { numberFormatter.useScientificFormat(DEFAULT_MAGNITUDE); numberFormatter.setPrecision(NO_ROUNDING); assertEquals("1", numberFormatter.format(1d)); assertEquals("0.333333333333333", numberFormatter.format(1d / 3)); assertEquals("3.333333333333333E-19", numberFormatter.format(pow(10, -18) / 3)); assertEquals("1.23456789E18", numberFormatter.format(123456789 * pow(10, 10))); assertEquals("1E-16", numberFormatter.format(pow(10, -16))); assertEquals("5.999999999999995E18", numberFormatter.format(5999999999999994999d)); testScientificFormat(); } @Test public void testScientificFormatWithRounding() throws Exception { numberFormatter.useScientificFormat(DEFAULT_MAGNITUDE); numberFormatter.setPrecision(5); assertEquals("1", numberFormatter.format(1d)); assertEquals("0.33333", numberFormatter.format(1d / 3)); assertEquals("3.33333E-19", numberFormatter.format(pow(10, -18) / 3)); assertEquals("1.23457E18", numberFormatter.format(123456789 * pow(10, 10))); assertEquals("1E-16", numberFormatter.format(pow(10, -16))); assertEquals("6E18", numberFormatter.format(5999999999999994999d)); testScientificFormat(); } @Test public void testSimpleFormatNoRounding() throws Exception { numberFormatter.useSimpleFormat(); numberFormatter.setPrecision(NO_ROUNDING); assertEquals("1", numberFormatter.format(1d)); assertEquals("0.000001", numberFormatter.format(pow(10, -6))); assertEquals("0.333333333333333", numberFormatter.format(1d / 3)); assertEquals("3.333333333333333E-19", numberFormatter.format(pow(10, -18) / 3)); assertEquals("1234567890000000000", numberFormatter.format(123456789 * pow(10, 10))); assertEquals("1E-16", numberFormatter.format(pow(10, -16))); assertEquals("1E-17", numberFormatter.format(pow(10, -17))); assertEquals("1E-18", numberFormatter.format(pow(10, -18))); assertEquals("1.5E-18", numberFormatter.format(1.5 * pow(10, -18))); assertEquals("1E-100", numberFormatter.format(pow(10, -100))); testSimpleFormat(); } @Test public void testSimpleFormatWithRounding() throws Exception { numberFormatter.useSimpleFormat(); numberFormatter.setPrecision(5); assertEquals("1", numberFormatter.format(1d)); assertEquals("0", numberFormatter.format(pow(10, -6))); assertEquals("0.33333", numberFormatter.format(1d / 3)); assertEquals("0", numberFormatter.format(pow(10, -18) / 3)); assertEquals("1234567890000000000", numberFormatter.format(123456789 * pow(10, 10))); assertEquals("0", numberFormatter.format(pow(10, -16))); assertEquals("0", numberFormatter.format(pow(10, -17))); assertEquals("0", numberFormatter.format(pow(10, -18))); assertEquals("0", numberFormatter.format(1.5 * pow(10, -18))); assertEquals("0", numberFormatter.format(pow(10, -100))); testSimpleFormat(); } // testing simple format with and without rounding private void testSimpleFormat() { assertEquals("0.00001", numberFormatter.format(pow(10, -5))); assertEquals("0.01", numberFormatter.format(3.11 - 3.1)); assertEquals("100", numberFormatter.format(pow(10, 2))); assertEquals("1", numberFormatter.format(BigInteger.ONE)); assertEquals("1000", numberFormatter.format(BigInteger.valueOf(1000))); assertEquals("1000000000000000000", numberFormatter.format(pow(10, 18))); assertEquals("1000000000000000000", numberFormatter.format(BigInteger.valueOf(10).pow(18))); assertEquals("1E19", numberFormatter.format(pow(10, 19))); assertEquals("1E19", numberFormatter.format(BigInteger.valueOf(10).pow(19))); assertEquals("1E20", numberFormatter.format(pow(10, 20))); assertEquals("1E20", numberFormatter.format(BigInteger.valueOf(10).pow(20))); assertEquals("1E100", numberFormatter.format(pow(10, 100))); assertEquals("1E100", numberFormatter.format(BigInteger.valueOf(10).pow(100))); assertEquals("0.01", numberFormatter.format(pow(10, -2))); assertEquals("5000000000000000000", numberFormatter.format(5000000000000000000d)); assertEquals("5000000000000000000", numberFormatter.format(BigInteger.valueOf(5000000000000000000L))); assertEquals("5000000000000000000", numberFormatter.format(5000000000000000001d)); assertEquals("5000000000000000001", numberFormatter.format(BigInteger.valueOf(5000000000000000001L))); assertEquals("5999999999999994900", numberFormatter.format(5999999999999994999d)); assertEquals("5999999999999994999", numberFormatter.format(BigInteger.valueOf(5999999999999994999L))); assertEquals("5E19", numberFormatter.format(50000000000000000000d)); assertEquals("5E19", numberFormatter.format(BigInteger.valueOf(5L).multiply(TEN.pow(19)))); assertEquals("5E40", numberFormatter.format(50000000000000000000000000000000000000000d)); assertEquals("5E40", numberFormatter.format(BigInteger.valueOf(5L).multiply(TEN.pow(40)))); } // testing scientific format with and without rounding private void testScientificFormat() { assertEquals("0.00001", numberFormatter.format(pow(10, -5))); assertEquals("1E-6", numberFormatter.format(pow(10, -6))); assertEquals("100", numberFormatter.format(pow(10, 2))); assertEquals("100", numberFormatter.format(TEN.pow(2))); assertEquals("10000", numberFormatter.format(pow(10, 4))); assertEquals("10000", numberFormatter.format(TEN.pow(4))); assertEquals("1E5", numberFormatter.format(pow(10, 5))); assertEquals("1E5", numberFormatter.format(TEN.pow(5))); assertEquals("1E18", numberFormatter.format(pow(10, 18))); assertEquals("1E18", numberFormatter.format(TEN.pow(18))); assertEquals("1E19", numberFormatter.format(pow(10, 19))); assertEquals("1E19", numberFormatter.format(TEN.pow( 19))); assertEquals("1E20", numberFormatter.format(pow(10, 20))); assertEquals("1E20", numberFormatter.format(TEN.pow(20))); assertEquals("1E100", numberFormatter.format(pow(10, 100))); assertEquals("1E100", numberFormatter.format(TEN.pow(100))); assertEquals("0.01", numberFormatter.format(pow(10, -2))); assertEquals("1E-17", numberFormatter.format(pow(10, -17))); assertEquals("1E-18", numberFormatter.format(pow(10, -18))); assertEquals("1.5E-18", numberFormatter.format(1.5 * pow(10, -18))); assertEquals("1E-100", numberFormatter.format(pow(10, -100))); assertEquals("5E18", numberFormatter.format(5000000000000000000d)); assertEquals("5E18", numberFormatter.format(5000000000000000001d)); assertEquals("5E19", numberFormatter.format(50000000000000000000d)); assertEquals("5E40", numberFormatter.format(50000000000000000000000000000000000000000d)); } @Test public void testMaximumPrecision() throws Exception { numberFormatter.useSimpleFormat(); numberFormatter.setPrecision(10); for (int i = 0; i < 1000; i++) { for (int j = 2; j < 1000; j += j - 1) { for (int k = 2; k < 1000; k += k - 1) { final double first = makeDouble(i, j); final double second = makeDouble(i, 1000 - k); checkMaximumPrecision(first + "-" + second, numberFormatter.format(first - second)); checkMaximumPrecision(second + "-" + first, numberFormatter.format(second - first)); checkMaximumPrecision(second + "+" + first, numberFormatter.format(first + second)); } } } } private void checkMaximumPrecision(String expression, CharSequence value) { assertTrue(expression + "=" + value, value.length() <= 8); } private static double makeDouble(int integerPart, int fractionalPart) { return Double.parseDouble(integerPart + "." + fractionalPart); } }