Float to string conversion implemented, excluding the case of range

without printable exponent (i.e. 10e-3 ... 10e7)
This commit is contained in:
konsoletyper 2013-12-14 00:41:21 +04:00
parent 808b0d9468
commit 3782bdd458
4 changed files with 162 additions and 1 deletions

View File

@ -1,6 +1,6 @@
package org.teavm.classlib.java.lang; package org.teavm.classlib.java.lang;
import static org.junit.Assert.*; import static org.junit.Assert.assertEquals;
import org.junit.Test; import org.junit.Test;
/** /**
@ -64,6 +64,76 @@ public class StringBuilderTests {
assertEquals("9223372036854775807", sb.toString()); 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 @Test
public void appendsCodePoint() { public void appendsCodePoint() {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();

View File

@ -2,6 +2,7 @@ package org.teavm.classlib.java.lang;
import org.teavm.classlib.java.lang.io.TSerializable; import org.teavm.classlib.java.lang.io.TSerializable;
import org.teavm.classlib.java.util.TArrays; import org.teavm.classlib.java.util.TArrays;
import org.teavm.javascript.ni.Remove;
import org.teavm.javascript.ni.Rename; import org.teavm.javascript.ni.Rename;
/** /**
@ -9,6 +10,8 @@ import org.teavm.javascript.ni.Rename;
* @author Alexey Andreev * @author Alexey Andreev
*/ */
class TAbstractStringBuilder extends TObject implements TSerializable, TCharSequence { 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; char[] buffer;
int length; int length;
@ -104,6 +107,78 @@ class TAbstractStringBuilder extends TObject implements TSerializable, TCharSequ
return this; 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) { protected TAbstractStringBuilder append(char c) {
ensureCapacity(length + 1); ensureCapacity(length + 1);
buffer[length++] = c; buffer[length++] = c;
@ -134,6 +209,12 @@ class TAbstractStringBuilder extends TObject implements TSerializable, TCharSequ
return new TString(buffer, 0, length); return new TString(buffer, 0, length);
} }
@Remove
@Override
public String toString() {
return new String(buffer, 0, length);
}
@Override @Override
public int length() { public int length() {
return length; return length;

View File

@ -423,6 +423,10 @@ public class TString extends TObject implements TSerializable, TComparable<TStri
return new TStringBuilder().append(l).toString0(); return new TStringBuilder().append(l).toString0();
} }
public static TString valueOf(float f) {
return new TStringBuilder().append(f).toString0();
}
@Override @Override
public boolean equals(TObject other) { public boolean equals(TObject other) {
if (this == other) { if (this == other) {

View File

@ -23,6 +23,12 @@ public class TStringBuilder extends TAbstractStringBuilder {
return this; return this;
} }
@Override
public TStringBuilder append(float value) {
super.append(value);
return this;
}
@Override @Override
public TStringBuilder append(char c) { public TStringBuilder append(char c) {
super.append(c); super.append(c);