diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/StringBuilderTests.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/StringBuilderTests.java index 0871b3da2..6b82cb7cb 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/StringBuilderTests.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/StringBuilderTests.java @@ -1,6 +1,6 @@ package org.teavm.classlib.java.lang; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; import org.junit.Test; /** @@ -64,6 +64,76 @@ public class StringBuilderTests { assertEquals("9223372036854775807", sb.toString()); } + @Test + public void floatAppended() { + StringBuilder sb = new StringBuilder(); + sb.append(1.234E25F); + assertEquals("1.234E25", sb.toString()); + } + + @Test + public void floatAppended2() { + StringBuilder sb = new StringBuilder(); + sb.append(9.8765E30F); + assertEquals("9.8765E30", sb.toString()); + } + + @Test + public void negativeFloatAppended() { + StringBuilder sb = new StringBuilder(); + sb.append(-1.234E25F); + assertEquals("-1.234E25", sb.toString()); + } + + @Test + public void negativeFloatAppended2() { + StringBuilder sb = new StringBuilder(); + sb.append(9.8765E30F); + assertEquals("9.8765E30", sb.toString()); + } + + @Test + public void maxFloatAppended() { + StringBuilder sb = new StringBuilder(); + sb.append(3.402823E38f); + assertEquals("3.402823E38", sb.toString()); + } + + @Test + public void smallFloatAppended() { + StringBuilder sb = new StringBuilder(); + sb.append(1.234E-25F); + assertEquals("1.234E-25", sb.toString()); + } + + @Test + public void smallFloatAppended2() { + StringBuilder sb = new StringBuilder(); + sb.append(9.8764E-30F); + assertEquals("9.8764E-30", sb.toString()); + } + + @Test + public void negativeSmallFloatAppended() { + StringBuilder sb = new StringBuilder(); + sb.append(-1.234E-25F); + assertEquals("-1.234E-25", sb.toString()); + } + + @Test + public void negativeSmallFloatAppended2() { + StringBuilder sb = new StringBuilder(); + sb.append(-9.8764E-30F); + assertEquals("-9.8764E-30", sb.toString()); + } + + @Test + public void minFloatAppended() { + StringBuilder sb = new StringBuilder(); + sb.append(1.175494E-38f); + assertEquals("1.175494E-38", sb.toString()); + } + @Test public void appendsCodePoint() { StringBuilder sb = new StringBuilder(); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TAbstractStringBuilder.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TAbstractStringBuilder.java index 7687fae1e..2b4fbbae7 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TAbstractStringBuilder.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TAbstractStringBuilder.java @@ -2,6 +2,7 @@ package org.teavm.classlib.java.lang; import org.teavm.classlib.java.lang.io.TSerializable; import org.teavm.classlib.java.util.TArrays; +import org.teavm.javascript.ni.Remove; import org.teavm.javascript.ni.Rename; /** @@ -9,6 +10,8 @@ import org.teavm.javascript.ni.Rename; * @author Alexey Andreev */ class TAbstractStringBuilder extends TObject implements TSerializable, TCharSequence { + private static float[] powersOfTen = { 1E1f, 1E2f, 1E4f, 1E8f, 1E16f, 1E32f }; + private static float[] negPowersOfTen = { 1E-1f, 1E-2f, 1E-4f, 1E-8f, 1E-16f, 1E-32f }; char[] buffer; int length; @@ -104,6 +107,78 @@ class TAbstractStringBuilder extends TObject implements TSerializable, TCharSequ return this; } + protected TAbstractStringBuilder append(float value) { + boolean negative = false; + int sz = 10; + if (value < 0) { + negative = true; + value = -value; + ++sz; + } + int exp = 0; + if (value > 1) { + int bit = 32; + exp = 0; + float digit = 1; + for (int i = powersOfTen.length - 1; i >= 0; --i) { + if ((exp | bit) <= 38 && powersOfTen[i] * digit < value) { + digit *= powersOfTen[i]; + exp |= bit; + } + bit >>= 1; + } + value /= digit; + } else { + int bit = 32; + exp = 0; + float digit = 1; + for (int i = negPowersOfTen.length - 1; i >= 0; --i) { + if ((exp | bit) <= 38 && negPowersOfTen[i] * digit * 10 > value) { + digit *= negPowersOfTen[i]; + exp |= bit; + } + bit >>= 1; + } + value /= digit; + exp = -exp; + ++sz; + } + value += 5E-7F; + if (exp > 10) { + ++sz; + } + ensureCapacity(length + sz); + if (negative) { + buffer[length++] = '-'; + } + int intDigit = (int)value; + buffer[length++] = (char)('0' + intDigit); + buffer[length++] = '.'; + value = (value - intDigit) * 10; + int zeros = 0; + for (int i = 0; i < 6; ++i) { + intDigit = (int)value; + if (intDigit == 0) { + ++zeros; + } else { + zeros = 0; + } + buffer[length++] = (char)('0' + intDigit); + value = (value - intDigit) * 10; + } + length -= Math.min(zeros, 5); + buffer[length++] = 'E'; + if (exp < 0) { + exp = -exp; + buffer[length++] = '-'; + } + if (exp > 10) { + buffer[length++] = (char)('0' + exp / 10); + } + buffer[length++] = (char)('0' + exp % 10); + return this; + } + protected TAbstractStringBuilder append(char c) { ensureCapacity(length + 1); buffer[length++] = c; @@ -134,6 +209,12 @@ class TAbstractStringBuilder extends TObject implements TSerializable, TCharSequ return new TString(buffer, 0, length); } + @Remove + @Override + public String toString() { + return new String(buffer, 0, length); + } + @Override public int length() { return length; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TString.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TString.java index 058e3c655..af5ab3ae9 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TString.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TString.java @@ -423,6 +423,10 @@ public class TString extends TObject implements TSerializable, TComparable