mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Adds some java.lang.Float implementation
This commit is contained in:
parent
758c7c7966
commit
2afbb3d4bd
|
@ -92,6 +92,9 @@ public class ClassNativeGenerator implements Generator, Injector, DependencyPlug
|
|||
case "doubleClass":
|
||||
context.getWriter().append("$rt_cls($rt_doublecls())");
|
||||
break;
|
||||
case "floatClass":
|
||||
context.getWriter().append("$rt_cls($rt_floatcls())");
|
||||
break;
|
||||
case "wrap":
|
||||
context.writeExpr(context.getArgument(0));
|
||||
break;
|
||||
|
@ -179,11 +182,12 @@ public class ClassNativeGenerator implements Generator, Injector, DependencyPlug
|
|||
@Override
|
||||
public void methodAchieved(DependencyChecker checker, MethodDependency graph) {
|
||||
switch (graph.getReference().getName()) {
|
||||
case "booleanClass":
|
||||
case "intClass":
|
||||
case "charClass":
|
||||
case "byteClass":
|
||||
case "voidClass":
|
||||
case "booleanClass":
|
||||
case "byteClass":
|
||||
case "charClass":
|
||||
case "intClass":
|
||||
case "floatClass":
|
||||
case "doubleClass":
|
||||
case "wrap":
|
||||
case "getSuperclass":
|
||||
|
|
|
@ -19,13 +19,15 @@ import java.io.IOException;
|
|||
import org.teavm.codegen.SourceWriter;
|
||||
import org.teavm.javascript.ni.Generator;
|
||||
import org.teavm.javascript.ni.GeneratorContext;
|
||||
import org.teavm.javascript.ni.Injector;
|
||||
import org.teavm.javascript.ni.InjectorContext;
|
||||
import org.teavm.model.MethodReference;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public class FloatNativeGenerator implements Generator {
|
||||
public class FloatNativeGenerator implements Generator, Injector {
|
||||
@Override
|
||||
public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException {
|
||||
switch (methodRef.getName()) {
|
||||
|
@ -38,6 +40,15 @@ public class FloatNativeGenerator implements Generator {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(InjectorContext context, MethodReference methodRef) throws IOException {
|
||||
switch (methodRef.getName()) {
|
||||
case "getNaN":
|
||||
context.getWriter().append("NaN");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void generateIsNaN(GeneratorContext context, SourceWriter writer) throws IOException {
|
||||
writer.append("return (isNaN(").append(context.getParameterName(1)).append(")").ws().append("?")
|
||||
.ws().append("1").ws().append(":").ws().append("0").ws().append(");").softNewLine();
|
||||
|
|
|
@ -89,6 +89,10 @@ public class TClass<T> extends TObject {
|
|||
@PluggableDependency(ClassNativeGenerator.class)
|
||||
static native TClass<TByte> byteClass();
|
||||
|
||||
@InjectedBy(ClassNativeGenerator.class)
|
||||
@PluggableDependency(ClassNativeGenerator.class)
|
||||
static native TClass<TFloat> floatClass();
|
||||
|
||||
@InjectedBy(ClassNativeGenerator.class)
|
||||
@PluggableDependency(ClassNativeGenerator.class)
|
||||
static native TClass<TDouble> doubleClass();
|
||||
|
|
|
@ -203,6 +203,12 @@ public class TDouble extends TNumber implements TComparable<TDouble> {
|
|||
return other instanceof TDouble && ((TDouble)other).value == value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
long h = doubleToLongBits(value);
|
||||
return (int)(h >>> 32) ^ ((int)h | 0);
|
||||
}
|
||||
|
||||
public static int compare(double a, double b) {
|
||||
return a > b ? 1 : a < b ? -1 : 0;
|
||||
}
|
||||
|
|
|
@ -22,13 +22,31 @@ import org.teavm.javascript.ni.Rename;
|
|||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public class TFloat extends TNumber {
|
||||
public class TFloat extends TNumber implements TComparable<TFloat> {
|
||||
public static final float POSITIVE_INFINITY = 1 / 0.0f;
|
||||
public static final float NEGATIVE_INFINITY = -POSITIVE_INFINITY;
|
||||
public static final float NaN = getNaN();
|
||||
public static final float MAX_VALUE = 0x1.fffffeP+127f;
|
||||
public static final float MIN_VALUE = 0x1.0p-126f;
|
||||
public static final float MIN_NORMAL = 0x0.000002P-126f;
|
||||
public static final int MAX_EXPONENT = 127;
|
||||
public static final int MIN_EXPONENT = -126;
|
||||
public static final int SIZE = 32;
|
||||
public static final TClass<TFloat> TYPE = TClass.floatClass();
|
||||
private float value;
|
||||
|
||||
public TFloat(float value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public TFloat(double value) {
|
||||
this((float)value);
|
||||
}
|
||||
|
||||
public TFloat(TString value) throws TNumberFormatException {
|
||||
this(parseFloat(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int intValue() {
|
||||
return (int)value;
|
||||
|
@ -76,4 +94,141 @@ public class TFloat extends TNumber {
|
|||
|
||||
@GeneratedBy(FloatNativeGenerator.class)
|
||||
public static native boolean isInfinite(float v);
|
||||
|
||||
@GeneratedBy(FloatNativeGenerator.class)
|
||||
private static native float getNaN();
|
||||
|
||||
public static float parseFloat(TString string) throws TNumberFormatException {
|
||||
// TODO: parse infinite and different radix
|
||||
string = string.trim();
|
||||
boolean negative = false;
|
||||
int index = 0;
|
||||
if (string.charAt(index) == '-') {
|
||||
++index;
|
||||
negative = true;
|
||||
} else if (string.charAt(index) == '+') {
|
||||
++index;
|
||||
}
|
||||
char c = string.charAt(index);
|
||||
if (c < '0' || c > '9') {
|
||||
throw new TNumberFormatException();
|
||||
}
|
||||
int mantissa = 0;
|
||||
int exp = 0;
|
||||
while (string.charAt(index) == '0') {
|
||||
if (++index == string.length()) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
while (index < string.length()) {
|
||||
c = string.charAt(index);
|
||||
if (c < '0' || c > '9') {
|
||||
break;
|
||||
}
|
||||
if (mantissa < 1E8) {
|
||||
mantissa = mantissa * 10 + (c - '0');
|
||||
} else {
|
||||
++exp;
|
||||
}
|
||||
++index;
|
||||
}
|
||||
if (index < string.length() && string.charAt(index) == '.') {
|
||||
++index;
|
||||
boolean hasOneDigit = false;
|
||||
while (index < string.length()) {
|
||||
c = string.charAt(index);
|
||||
if (c < '0' || c > '9') {
|
||||
break;
|
||||
}
|
||||
if (mantissa < 1E38) {
|
||||
mantissa = mantissa * 10 + (c - '0');
|
||||
--exp;
|
||||
}
|
||||
++index;
|
||||
hasOneDigit = true;
|
||||
}
|
||||
if (!hasOneDigit) {
|
||||
throw new TNumberFormatException();
|
||||
}
|
||||
}
|
||||
if (index < string.length()) {
|
||||
c = string.charAt(index);
|
||||
if (c != 'e' && c != 'E') {
|
||||
throw new TNumberFormatException();
|
||||
}
|
||||
++index;
|
||||
boolean negativeExp = false;
|
||||
if (string.charAt(index) == '-') {
|
||||
++index;
|
||||
negativeExp = true;
|
||||
} else if (string.charAt(index) == '+') {
|
||||
++index;
|
||||
}
|
||||
int numExp = 0;
|
||||
boolean hasOneDigit = false;
|
||||
while (index < string.length()) {
|
||||
c = string.charAt(index);
|
||||
if (c < '0' || c > '9') {
|
||||
break;
|
||||
}
|
||||
numExp = 10 * numExp + (c - '0');
|
||||
hasOneDigit = true;
|
||||
++index;
|
||||
}
|
||||
if (!hasOneDigit) {
|
||||
throw new TNumberFormatException();
|
||||
}
|
||||
if (negativeExp) {
|
||||
numExp = -numExp;
|
||||
}
|
||||
exp += numExp;
|
||||
}
|
||||
if (exp > 38 || exp == 38 && mantissa > 34028234) {
|
||||
return !negative ? POSITIVE_INFINITY : NEGATIVE_INFINITY;
|
||||
}
|
||||
if (negative) {
|
||||
mantissa = -mantissa;
|
||||
}
|
||||
return mantissa * decimalExponent(exp);
|
||||
}
|
||||
|
||||
private static float decimalExponent(int n) {
|
||||
float d;
|
||||
if (n < 0) {
|
||||
d = 0.1f;
|
||||
n = -n;
|
||||
} else {
|
||||
d = 10;
|
||||
}
|
||||
float result = 1;
|
||||
while (n != 0) {
|
||||
if (n % 2 != 0) {
|
||||
result *= d;
|
||||
}
|
||||
d *= d;
|
||||
n /= 2;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static TFloat valueOf(TString s) throws TNumberFormatException {
|
||||
return valueOf(parseFloat(s));
|
||||
}
|
||||
|
||||
public boolean isNaN() {
|
||||
return isNaN(value);
|
||||
}
|
||||
|
||||
public boolean isInfinite() {
|
||||
return isInfinite(value);
|
||||
}
|
||||
|
||||
public static int compare(float f1, float f2) {
|
||||
return f1 > f2 ? 1 : f2 < f1 ? -1 : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(TFloat other) {
|
||||
return compare(value, other.value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright 2014 Alexey Andreev.
|
||||
*
|
||||
* 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.teavm.classlib.java.lang;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public class FloatTest {
|
||||
@Test
|
||||
public void parsed() {
|
||||
assertEquals(23, Double.parseDouble("23"), 1E-12);
|
||||
assertEquals(23, Double.parseDouble("23.0"), 1E-12);
|
||||
assertEquals(23, Double.parseDouble("23E0"), 1E-12);
|
||||
assertEquals(23, Double.parseDouble("2.30000E1"), 1E-12);
|
||||
assertEquals(23, Double.parseDouble("0.23E2"), 1E-12);
|
||||
assertEquals(23, Double.parseDouble("0.000023E6"), 1E-12);
|
||||
assertEquals(23, Double.parseDouble("00230000e-4"), 1E-12);
|
||||
assertEquals(23, Double.parseDouble("2300000000000000000000e-20"), 1E-12);
|
||||
assertEquals(23, Double.parseDouble("2300000000000000000000e-20"), 1E-12);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void negativeParsed() {
|
||||
assertEquals(-23, Double.parseDouble("-23"), 1E-12);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void zeroParsed() {
|
||||
assertEquals(0, Double.parseDouble("0.0"), 1E-12);
|
||||
assertEquals(0, Double.parseDouble("23E-8000"), 1E-12);
|
||||
assertEquals(0, Double.parseDouble("00000"), 1E-12);
|
||||
assertEquals(0, Double.parseDouble("00000.0000"), 1E-12);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user