From 27da14d8274da5e140a1d957c56ff1700adc82cc Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Sun, 7 Jun 2015 18:02:38 +0300 Subject: [PATCH] Implementing DecimalFormat --- .../classlib/java/text/TDecimalFormat.java | 55 ++++++++++++++++++- .../classlib/java/text/DecimalFormatTest.java | 28 ++++++++++ 2 files changed, 82 insertions(+), 1 deletion(-) diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TDecimalFormat.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TDecimalFormat.java index 89b700035..4f63f43de 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TDecimalFormat.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TDecimalFormat.java @@ -30,6 +30,8 @@ public class TDecimalFormat extends TNumberFormat { 1_000_0000, 1_0000_0000, 1_0_0000_0000, 1_00_0000_0000L, 1_000_0000_0000L, 1_0000_0000_0000L, 1_0_0000_0000_0000L, 1_00_0000_0000_0000L, 1_000_0000_0000_0000L, 1_0000_0000_0000_0000L, 1_0_0000_0000_0000_0000L, 1_00_0000_0000_0000_0000L }; + private static final int[] POW10_INT_ARRAY = { 1, 10, 100, 1000, 1_0000, 1_0_0000, 1_00_0000, + 1_000_0000, 1_0000_0000, 1_0_0000_0000 }; private static final double[] POW10_FRAC_ARRAY = { 1E1, 1E2, 1E4, 1E8, 1E16, 1E32, 1E64, 1E128, 1E256 }; private static final double[] POWM10_FRAC_ARRAY = { 1E-1, 1E-2, 1E-4, 1E-8, 1E-16, 1E-32, 1E-64, 1E-128, 1E-256 }; private static final int DOUBLE_MAX_EXPONENT = 308; @@ -250,7 +252,37 @@ public class TDecimalFormat extends TNumberFormat { buffer.append('0'); } - significantSize -= visibleExponent; + significantSize -= mantissaLength - visibleExponent; + if (getMinimumIntegerDigits() > 0 || (mantissa != 0 && significantSize > 0)) { + buffer.append(symbols.getDecimalSeparator()); + + int limit = Math.max(0, visibleExponent - significantSize); + int count = 0; + for (int i = visibleExponent - 1; i >= limit; --i) { + long mantissaDigitMask = POW10_ARRAY[i]; + buffer.append(Character.forDigit((int)(mantissa / mantissaDigitMask), 10)); + mantissa %= mantissaDigitMask; + if (mantissa == 0) { + break; + } + ++count; + } + while (count-- < getMinimumFractionDigits()) { + buffer.append('0'); + } + } + + buffer.append(symbols.getExponentSeparator()); + if (exponent < 0) { + exponent = -exponent; + buffer.append(symbols.getMinusSign()); + } + int exponentLength = Math.max(exponentDigits, fastLn10(exponent)); + for (int i = exponentLength - 1; i >= 0; --i) { + int exponentDigit = POW10_INT_ARRAY[i]; + buffer.append(Character.forDigit(exponent / exponentDigit, 10)); + exponent %= exponentDigit; + } } private void formatRegular(long mantissa, int exponent, StringBuffer buffer) { @@ -428,6 +460,27 @@ public class TDecimalFormat extends TNumberFormat { return result; } + private int fastLn10(int value) { + int result = 0; + if (value >= 1_0000_0000) { + result += 8; + value /= 1_0000_0000; + } + if (value >= 1_0000) { + result += 4; + value /= 1_0000; + } + if (value >= 100) { + result += 2; + value /= 100; + } + if (value >= 10L) { + result += 1; + value /= 10; + } + return result; + } + private MantissaAndExponent getMantissaAndExponent(double value) { long mantissaPattern = POW10_ARRAY[17]; int exp = 0; diff --git a/teavm-tests/src/test/java/org/teavm/classlib/java/text/DecimalFormatTest.java b/teavm-tests/src/test/java/org/teavm/classlib/java/text/DecimalFormatTest.java index 0ec578993..ee1420abe 100644 --- a/teavm-tests/src/test/java/org/teavm/classlib/java/text/DecimalFormatTest.java +++ b/teavm-tests/src/test/java/org/teavm/classlib/java/text/DecimalFormatTest.java @@ -235,6 +235,34 @@ public class DecimalFormatTest { assertEquals("-9223372036854775808", format.format(-9223372036854775808L)); } + @Test + public void formatsExponent() { + DecimalFormat format = createFormat("000E0"); + assertEquals("230E-1", format.format(23)); + assertEquals("230E0", format.format(230)); + assertEquals("230E1", format.format(2300)); + assertEquals("123E1", format.format(1234)); + + format = createFormat("0.00E0"); + assertEquals("2.00E1", format.format(20)); + assertEquals("2.30E1", format.format(23)); + assertEquals("2.30E2", format.format(230)); + assertEquals("1.23E3", format.format(1234)); + + format = createFormat("000000000000000000000.00E0"); + assertEquals("230000000000000000000.00E-19", format.format(23)); + + format = createFormat("0.0000000000000000000000E0"); + assertEquals("2.3000000000000000000000E1", format.format(23)); + + format = createFormat("0.0##E0"); + assertEquals("1.0E0", format.format(1)); + assertEquals("1.2E1", format.format(12)); + assertEquals("1.23E2", format.format(123)); + assertEquals("1.234E3", format.format(1234)); + assertEquals("1.234E4", format.format(12345)); + } + private DecimalFormat createFormat(String format) { return new DecimalFormat(format, symbols); }