mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
classlib: math fixes (#742)
This commit is contained in:
parent
4a081db1c3
commit
0997a65596
|
@ -21,6 +21,7 @@ import org.teavm.classlib.PlatformDetector;
|
||||||
import org.teavm.interop.Import;
|
import org.teavm.interop.Import;
|
||||||
import org.teavm.interop.NoSideEffects;
|
import org.teavm.interop.NoSideEffects;
|
||||||
import org.teavm.interop.Unmanaged;
|
import org.teavm.interop.Unmanaged;
|
||||||
|
import org.teavm.jso.JSBody;
|
||||||
|
|
||||||
@NoSideEffects
|
@NoSideEffects
|
||||||
public final class TMath extends TObject {
|
public final class TMath extends TObject {
|
||||||
|
@ -207,19 +208,33 @@ public final class TMath extends TObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int abs(int n) {
|
public static int abs(int n) {
|
||||||
return n > 0 ? n : -n;
|
return n >= 0 ? n : -n;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long abs(long n) {
|
public static long abs(long n) {
|
||||||
return n > 0 ? n : -n;
|
return n >= 0 ? n : -n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JSBody(params = "d", script = "return Math.abs(d);")
|
||||||
|
@NoSideEffects
|
||||||
|
private static native float jsAbs(float d);
|
||||||
|
|
||||||
public static float abs(float n) {
|
public static float abs(float n) {
|
||||||
return n > 0 ? n : -n;
|
if (PlatformDetector.isJavaScript()) {
|
||||||
|
return jsAbs(n);
|
||||||
|
}
|
||||||
|
return n <= 0.0f ? 0.0f - n : n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JSBody(params = "d", script = "return Math.abs(d);")
|
||||||
|
@NoSideEffects
|
||||||
|
private static native double jsAbs(double d);
|
||||||
|
|
||||||
public static double abs(double n) {
|
public static double abs(double n) {
|
||||||
return n > 0 ? n : -n;
|
if (PlatformDetector.isJavaScript()) {
|
||||||
|
return jsAbs(n);
|
||||||
|
}
|
||||||
|
return n <= 0.0d ? 0.0d - n : n;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double ulp(double d) {
|
public static double ulp(double d) {
|
||||||
|
@ -241,7 +256,7 @@ public final class TMath extends TObject {
|
||||||
bits -= 52L << 52L;
|
bits -= 52L << 52L;
|
||||||
} else {
|
} else {
|
||||||
int exponent = (int) (bits >> 52);
|
int exponent = (int) (bits >> 52);
|
||||||
bits = 1 << Math.max(0, exponent - 1);
|
bits = 1L << Math.max(0, exponent - 1);
|
||||||
}
|
}
|
||||||
return TDouble.longBitsToDouble(bits);
|
return TDouble.longBitsToDouble(bits);
|
||||||
}
|
}
|
||||||
|
@ -255,8 +270,8 @@ public final class TMath extends TObject {
|
||||||
|
|
||||||
int bits = TFloat.floatToIntBits(d);
|
int bits = TFloat.floatToIntBits(d);
|
||||||
bits &= 0x7F800000;
|
bits &= 0x7F800000;
|
||||||
if (bits >= 24L << 23L) {
|
if (bits >= 24 << 23) {
|
||||||
bits -= 23L << 23L;
|
bits -= 23 << 23;
|
||||||
} else {
|
} else {
|
||||||
int exponent = bits >> 23;
|
int exponent = bits >> 23;
|
||||||
bits = 1 << Math.max(0, exponent - 1);
|
bits = 1 << Math.max(0, exponent - 1);
|
||||||
|
@ -264,12 +279,32 @@ public final class TMath extends TObject {
|
||||||
return TFloat.intBitsToFloat(bits);
|
return TFloat.intBitsToFloat(bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JSBody(params = "d", script = "return Math.sign(d);")
|
||||||
|
@NoSideEffects
|
||||||
|
private static native double sign(double d);
|
||||||
|
|
||||||
public static double signum(double d) {
|
public static double signum(double d) {
|
||||||
return d > 0 ? 1 : d < -0 ? -1 : d;
|
if (PlatformDetector.isJavaScript()) {
|
||||||
|
return sign(d);
|
||||||
|
}
|
||||||
|
if (d == 0.0 || Double.isNaN(d)) {
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
return d < 0.0 ? -1.0 : 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JSBody(params = "d", script = "return Math.sign(d);")
|
||||||
|
@NoSideEffects
|
||||||
|
private static native float sign(float d);
|
||||||
|
|
||||||
public static float signum(float d) {
|
public static float signum(float d) {
|
||||||
return d > 0 ? 1 : d < -0 ? -1 : d;
|
if (PlatformDetector.isJavaScript()) {
|
||||||
|
return sign(d);
|
||||||
|
}
|
||||||
|
if (d == 0.0f || Float.isNaN(d)) {
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
return d < 0.0f ? -1.0f : 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double sinh(double x) {
|
public static double sinh(double x) {
|
||||||
|
@ -343,12 +378,14 @@ public final class TMath extends TObject {
|
||||||
if (TDouble.isNaN(d)) {
|
if (TDouble.isNaN(d)) {
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
if (d == 0.0d) {
|
||||||
|
return Double.MIN_VALUE;
|
||||||
|
}
|
||||||
if (d == TDouble.POSITIVE_INFINITY) {
|
if (d == TDouble.POSITIVE_INFINITY) {
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
long bits = TDouble.doubleToLongBits(d);
|
long bits = TDouble.doubleToLongBits(d);
|
||||||
boolean negative = (bits & (1L << 63)) != 0;
|
if (d < 0.0d) {
|
||||||
if (negative) {
|
|
||||||
bits--;
|
bits--;
|
||||||
} else {
|
} else {
|
||||||
bits++;
|
bits++;
|
||||||
|
@ -360,12 +397,14 @@ public final class TMath extends TObject {
|
||||||
if (TFloat.isNaN(d)) {
|
if (TFloat.isNaN(d)) {
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
if (d == 0.0f) {
|
||||||
|
return Float.MIN_VALUE;
|
||||||
|
}
|
||||||
if (d == TFloat.POSITIVE_INFINITY) {
|
if (d == TFloat.POSITIVE_INFINITY) {
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
int bits = TFloat.floatToIntBits(d);
|
int bits = TFloat.floatToIntBits(d);
|
||||||
boolean negative = (bits & (1L << 31)) != 0;
|
if (d < 0.0f) {
|
||||||
if (negative) {
|
|
||||||
bits--;
|
bits--;
|
||||||
} else {
|
} else {
|
||||||
bits++;
|
bits++;
|
||||||
|
@ -377,12 +416,14 @@ public final class TMath extends TObject {
|
||||||
if (TDouble.isNaN(d)) {
|
if (TDouble.isNaN(d)) {
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
if (d == 0.0d) {
|
||||||
|
return -Double.MIN_VALUE;
|
||||||
|
}
|
||||||
if (d == TDouble.NEGATIVE_INFINITY) {
|
if (d == TDouble.NEGATIVE_INFINITY) {
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
long bits = TDouble.doubleToLongBits(d);
|
long bits = TDouble.doubleToLongBits(d);
|
||||||
boolean negative = (bits & (1L << 63)) != 0;
|
if (d < 0.0d) {
|
||||||
if (negative) {
|
|
||||||
bits++;
|
bits++;
|
||||||
} else {
|
} else {
|
||||||
bits--;
|
bits--;
|
||||||
|
@ -394,12 +435,14 @@ public final class TMath extends TObject {
|
||||||
if (TFloat.isNaN(d)) {
|
if (TFloat.isNaN(d)) {
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
if (d == TFloat.POSITIVE_INFINITY) {
|
if (d == 0.0f) {
|
||||||
|
return -Float.MIN_VALUE;
|
||||||
|
}
|
||||||
|
if (d == TFloat.NEGATIVE_INFINITY) {
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
int bits = TFloat.floatToIntBits(d);
|
int bits = TFloat.floatToIntBits(d);
|
||||||
boolean negative = (bits & (1L << 31)) != 0;
|
if (d < 0.0f) {
|
||||||
if (negative) {
|
|
||||||
bits++;
|
bits++;
|
||||||
} else {
|
} else {
|
||||||
bits--;
|
bits--;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
package org.teavm.classlib.java.lang;
|
package org.teavm.classlib.java.lang;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.teavm.junit.TeaVMTestRunner;
|
import org.teavm.junit.TeaVMTestRunner;
|
||||||
|
@ -59,6 +60,32 @@ public class MathTest {
|
||||||
assertEquals(6, Math.getExponent(123.456));
|
assertEquals(6, Math.getExponent(123.456));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAbs() {
|
||||||
|
assertEquals(Float.valueOf(Float.POSITIVE_INFINITY), Float.valueOf(Math.abs(Float.NEGATIVE_INFINITY)));
|
||||||
|
assertEquals(Double.valueOf(Double.POSITIVE_INFINITY), Double.valueOf(Math.abs(Double.NEGATIVE_INFINITY)));
|
||||||
|
assertEquals(Double.valueOf(5.0), Double.valueOf(Math.abs(-5.0)));
|
||||||
|
assertEquals(Double.valueOf(3.0), Double.valueOf(Math.abs(3.0)));
|
||||||
|
assertEquals(Double.valueOf(3.0), Double.valueOf(Math.abs(-3.0)));
|
||||||
|
assertEquals(Double.valueOf(5.0), Double.valueOf(Math.abs(5.0)));
|
||||||
|
assertEquals(Float.valueOf(0.0f), Float.valueOf(Math.abs(-0.0f)));
|
||||||
|
assertEquals(Float.valueOf(0.0f), Float.valueOf(Math.abs(0.0f)));
|
||||||
|
assertEquals(Double.valueOf(0.0), Double.valueOf(Math.abs(-0.0)));
|
||||||
|
assertEquals(Double.valueOf(0.0), Double.valueOf(Math.abs(0.0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void signumWorks() {
|
||||||
|
assertEquals(Double.valueOf(0.0), Double.valueOf(Math.signum(0.0)));
|
||||||
|
assertEquals(Double.valueOf(-0.0), Double.valueOf(Math.signum(-0.0)));
|
||||||
|
assertTrue(Double.isNaN(Math.signum(Double.NaN)));
|
||||||
|
assertEquals(Float.valueOf(0.0f), Float.valueOf(Math.signum(0.0f)));
|
||||||
|
assertEquals(Float.valueOf(-0.0f), Float.valueOf(Math.signum(-0.0f)));
|
||||||
|
assertTrue(Float.isNaN(Math.signum(Float.NaN)));
|
||||||
|
assertEquals(Double.valueOf(-1.0), Double.valueOf(Math.signum(-Double.MIN_VALUE)));
|
||||||
|
assertEquals(Double.valueOf(1.0), Double.valueOf(Math.signum(Double.MIN_VALUE)));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void roundWorks() {
|
public void roundWorks() {
|
||||||
assertEquals(1, Math.round(1.3));
|
assertEquals(1, Math.round(1.3));
|
||||||
|
@ -66,4 +93,32 @@ public class MathTest {
|
||||||
assertEquals(-1, Math.round(-1.3));
|
assertEquals(-1, Math.round(-1.3));
|
||||||
assertEquals(-2, Math.round(-1.8));
|
assertEquals(-2, Math.round(-1.8));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void nextWorks() {
|
||||||
|
assertEquals(Double.valueOf(-Double.MIN_VALUE), Double.valueOf(Math.nextDown(0.0)));
|
||||||
|
assertEquals(Double.valueOf(Double.MIN_VALUE), Double.valueOf(Math.nextUp(0.0)));
|
||||||
|
assertEquals(Float.valueOf(-Float.MIN_VALUE), Float.valueOf(Math.nextDown(0.0f)));
|
||||||
|
assertEquals(Float.valueOf(Float.MIN_VALUE), Float.valueOf(Math.nextUp(0.0f)));
|
||||||
|
assertEquals(Double.valueOf(0.10000000000000002), Double.valueOf(Math.nextUp(0.1)));
|
||||||
|
assertEquals(Double.valueOf(0.9999999999999999), Double.valueOf(Math.nextDown(1.0)));
|
||||||
|
assertEquals(Double.valueOf(-0.09999999999999999), Double.valueOf(Math.nextUp(-0.1)));
|
||||||
|
assertEquals(Double.valueOf(-1.0000000000000002), Double.valueOf(Math.nextDown(-1.0)));
|
||||||
|
assertEquals(Float.valueOf(0.10000001f), Float.valueOf(Math.nextUp(0.1f)));
|
||||||
|
assertEquals(Float.valueOf(0.99999994f), Float.valueOf(Math.nextDown(1.0f)));
|
||||||
|
assertEquals(Float.valueOf(-0.099999994f), Float.valueOf(Math.nextUp(-0.1f)));
|
||||||
|
assertEquals(Float.valueOf(-1.0000001f), Float.valueOf(Math.nextDown(-1.0f)));
|
||||||
|
assertEquals(Float.valueOf(Float.NEGATIVE_INFINITY), Float.valueOf(Math.nextDown(Float.NEGATIVE_INFINITY)));
|
||||||
|
assertEquals(Float.valueOf(Float.intBitsToFloat(Float.floatToIntBits(Float.POSITIVE_INFINITY) - 1)),
|
||||||
|
Float.valueOf(Math.nextDown(Float.POSITIVE_INFINITY)));
|
||||||
|
assertEquals(Float.valueOf(Float.POSITIVE_INFINITY), Float.valueOf(Math.nextUp(Float.POSITIVE_INFINITY)));
|
||||||
|
assertEquals(Float.valueOf(Float.intBitsToFloat(Float.floatToIntBits(Float.NEGATIVE_INFINITY) - 1)),
|
||||||
|
Float.valueOf(Math.nextUp(Float.NEGATIVE_INFINITY)));
|
||||||
|
assertEquals(Double.valueOf(Double.NEGATIVE_INFINITY), Double.valueOf(Math.nextDown(Double.NEGATIVE_INFINITY)));
|
||||||
|
assertEquals(Double.valueOf(Double.longBitsToDouble(Double.doubleToLongBits(Double.POSITIVE_INFINITY) - 1)),
|
||||||
|
Double.valueOf(Math.nextDown(Double.POSITIVE_INFINITY)));
|
||||||
|
assertEquals(Double.valueOf(Double.POSITIVE_INFINITY), Double.valueOf(Math.nextUp(Double.POSITIVE_INFINITY)));
|
||||||
|
assertEquals(Double.valueOf(Double.longBitsToDouble(Double.doubleToLongBits(Double.NEGATIVE_INFINITY) - 1)),
|
||||||
|
Double.valueOf(Math.nextUp(Double.NEGATIVE_INFINITY)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user