classlib: follow-up for math fixes

This commit is contained in:
Alexey Andreev 2023-09-19 11:32:35 +02:00
parent 4372dd7806
commit 617ce67871
3 changed files with 44 additions and 42 deletions

View File

@ -28,6 +28,9 @@ public class MathNativeGenerator implements Generator {
if (name.endsWith("Impl")) { if (name.endsWith("Impl")) {
name = name.substring(0, name.length() - 4); name = name.substring(0, name.length() - 4);
} }
if (name.equals("signum")) {
name = "sign";
}
function(context, writer, "Math." + name, methodRef.parameterCount()); function(context, writer, "Math." + name, methodRef.parameterCount());
} }

View File

@ -21,7 +21,6 @@ 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 {
@ -215,26 +214,36 @@ public final class TMath extends TObject {
return n >= 0 ? n : -n; return n >= 0 ? n : -n;
} }
@JSBody(params = "d", script = "return Math.abs(d);") @GeneratedBy(MathNativeGenerator.class)
@NoSideEffects @NoSideEffects
private static native float jsAbs(float d); private static native float absImpl(float d);
@Import(name = "fabs")
private static native float absC(float d);
public static float abs(float n) { public static float abs(float n) {
if (PlatformDetector.isJavaScript()) { if (PlatformDetector.isJavaScript()) {
return jsAbs(n); return absImpl(n);
} else if (PlatformDetector.isC()) {
return absC(n);
} }
return n <= 0.0f ? 0.0f - n : n; return n <= 0f ? 0f - n : n;
} }
@JSBody(params = "d", script = "return Math.abs(d);") @GeneratedBy(MathNativeGenerator.class)
@NoSideEffects @NoSideEffects
private static native double jsAbs(double d); private static native double absImpl(double d);
@Import(name = "fabs")
private static native double absC(double d);
public static double abs(double n) { public static double abs(double n) {
if (PlatformDetector.isJavaScript()) { if (PlatformDetector.isJavaScript()) {
return jsAbs(n); return absImpl(n);
} else if (PlatformDetector.isC()) {
return absC(n);
} }
return n <= 0.0d ? 0.0d - n : n; return n <= 0.0 ? 0.0 - n : n;
} }
public static double ulp(double d) { public static double ulp(double d) {
@ -279,7 +288,7 @@ public final class TMath extends TObject {
return TFloat.intBitsToFloat(bits); return TFloat.intBitsToFloat(bits);
} }
@JSBody(params = "d", script = "return Math.sign(d);") @GeneratedBy(MathNativeGenerator.class)
@NoSideEffects @NoSideEffects
private static native double sign(double d); private static native double sign(double d);
@ -287,13 +296,13 @@ public final class TMath extends TObject {
if (PlatformDetector.isJavaScript()) { if (PlatformDetector.isJavaScript()) {
return sign(d); return sign(d);
} }
if (d == 0.0 || Double.isNaN(d)) { if (Double.isNaN(d)) {
return d; return d;
} }
return d < 0.0 ? -1.0 : 1.0; return d < 0 ? -1 : d > 0 ? 1 : d;
} }
@JSBody(params = "d", script = "return Math.sign(d);") @GeneratedBy(MathNativeGenerator.class)
@NoSideEffects @NoSideEffects
private static native float sign(float d); private static native float sign(float d);
@ -301,10 +310,10 @@ public final class TMath extends TObject {
if (PlatformDetector.isJavaScript()) { if (PlatformDetector.isJavaScript()) {
return sign(d); return sign(d);
} }
if (d == 0.0f || Float.isNaN(d)) { if (Double.isNaN(d)) {
return d; return d;
} }
return d < 0.0f ? -1.0f : 1.0f; return d < 0 ? -1 : d > 0 ? 1 : d;
} }
public static double sinh(double x) { public static double sinh(double x) {
@ -375,17 +384,11 @@ public final class TMath extends TObject {
} }
public static double nextUp(double d) { public static double nextUp(double d) {
if (TDouble.isNaN(d)) { if (TDouble.isNaN(d) || d == TDouble.POSITIVE_INFINITY) {
return d;
}
if (d == 0.0d) {
return Double.MIN_VALUE;
}
if (d == TDouble.POSITIVE_INFINITY) {
return d; return d;
} }
long bits = TDouble.doubleToLongBits(d); long bits = TDouble.doubleToLongBits(d);
if (d < 0.0d) { if (d < 0) {
bits--; bits--;
} else { } else {
bits++; bits++;
@ -394,17 +397,11 @@ public final class TMath extends TObject {
} }
public static float nextUp(float d) { public static float nextUp(float d) {
if (TFloat.isNaN(d)) { if (TFloat.isNaN(d) || d == TFloat.POSITIVE_INFINITY) {
return d;
}
if (d == 0.0f) {
return Float.MIN_VALUE;
}
if (d == TFloat.POSITIVE_INFINITY) {
return d; return d;
} }
int bits = TFloat.floatToIntBits(d); int bits = TFloat.floatToIntBits(d);
if (d < 0.0f) { if (d < 0) {
bits--; bits--;
} else { } else {
bits++; bits++;
@ -413,17 +410,14 @@ public final class TMath extends TObject {
} }
public static double nextDown(double d) { public static double nextDown(double d) {
if (TDouble.isNaN(d)) { if (TDouble.isNaN(d) || d == TDouble.NEGATIVE_INFINITY) {
return d; return d;
} }
if (d == 0.0d) { if (d == 0.0d) {
return -Double.MIN_VALUE; return -Double.MIN_VALUE;
} }
if (d == TDouble.NEGATIVE_INFINITY) {
return d;
}
long bits = TDouble.doubleToLongBits(d); long bits = TDouble.doubleToLongBits(d);
if (d < 0.0d) { if (d <= 0) {
bits++; bits++;
} else { } else {
bits--; bits--;
@ -432,17 +426,14 @@ public final class TMath extends TObject {
} }
public static float nextDown(float d) { public static float nextDown(float d) {
if (TFloat.isNaN(d)) { if (TFloat.isNaN(d) || d == TFloat.NEGATIVE_INFINITY) {
return d; return d;
} }
if (d == 0.0f) { if (d == 0) {
return -Float.MIN_VALUE; return -Float.MIN_VALUE;
} }
if (d == TFloat.NEGATIVE_INFINITY) {
return d;
}
int bits = TFloat.floatToIntBits(d); int bits = TFloat.floatToIntBits(d);
if (d < 0.0f) { if (d <= 0) {
bits++; bits++;
} else { } else {
bits--; bits--;

View File

@ -76,6 +76,11 @@ public class MathTest {
@Test @Test
public void signumWorks() { public void signumWorks() {
assertEquals(Double.valueOf(1.0), Double.valueOf(Math.signum(3.0)));
assertEquals(Double.valueOf(-1.0), Double.valueOf(Math.signum(-4.0)));
assertEquals(Float.valueOf(1f), Float.valueOf(Math.signum(3f)));
assertEquals(Float.valueOf(-1f), Float.valueOf(Math.signum(-4f)));
assertEquals(Double.valueOf(0.0), Double.valueOf(Math.signum(0.0))); assertEquals(Double.valueOf(0.0), Double.valueOf(Math.signum(0.0)));
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))); assertTrue(Double.isNaN(Math.signum(Double.NaN)));
@ -84,6 +89,9 @@ public class MathTest {
assertTrue(Float.isNaN(Math.signum(Float.NaN))); 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)));
assertEquals(Double.valueOf(1.0), Double.valueOf(Math.signum(Double.MIN_VALUE))); assertEquals(Double.valueOf(1.0), Double.valueOf(Math.signum(Double.MIN_VALUE)));
assertEquals(Float.valueOf(-1), Float.valueOf(Math.signum(Float.NEGATIVE_INFINITY)));
assertEquals(Float.valueOf(1), Float.valueOf(Math.signum(Float.POSITIVE_INFINITY)));
} }
@Test @Test