From fc49094d96556d39a10e60d7c0da5377446d2200 Mon Sep 17 00:00:00 2001 From: Ivan Hetman Date: Fri, 27 Oct 2023 17:52:33 +0300 Subject: [PATCH] classlib: fix support of positive/negative zeros in Float/Double.toHexString (#830) --- .../src/main/java/org/teavm/classlib/java/lang/TDouble.java | 6 +++++- .../src/main/java/org/teavm/classlib/java/lang/TFloat.java | 6 +++++- .../test/java/org/teavm/classlib/java/lang/DoubleTest.java | 2 ++ .../test/java/org/teavm/classlib/java/lang/FloatTest.java | 2 ++ 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/classlib/src/main/java/org/teavm/classlib/java/lang/TDouble.java b/classlib/src/main/java/org/teavm/classlib/java/lang/TDouble.java index 4c4f3d362..526fcefaf 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/lang/TDouble.java +++ b/classlib/src/main/java/org/teavm/classlib/java/lang/TDouble.java @@ -293,9 +293,13 @@ public class TDouble extends TNumber implements TComparable { int sz = 0; long bits = doubleToLongBits(d); boolean subNormal = false; + boolean negative = (bits & (1L << 63)) != 0; int exp = (int) ((bits >>> 52) & 0x7FF) - 1023; long mantissa = bits & 0xFFFFFFFFFFFFFL; if (exp == -1023) { + if (mantissa == 0) { + return negative ? "-0x0.0p0" : "0x0.0p0"; + } ++exp; subNormal = true; } @@ -314,7 +318,7 @@ public class TDouble extends TNumber implements TComparable { buffer[sz++] = subNormal ? '0' : '1'; buffer[sz++] = 'x'; buffer[sz++] = '0'; - if ((bits & (1L << 63)) != 0) { + if (negative) { buffer[sz++] = '-'; } int half = sz / 2; diff --git a/classlib/src/main/java/org/teavm/classlib/java/lang/TFloat.java b/classlib/src/main/java/org/teavm/classlib/java/lang/TFloat.java index 14c31ebba..6553cc9f2 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/lang/TFloat.java +++ b/classlib/src/main/java/org/teavm/classlib/java/lang/TFloat.java @@ -289,9 +289,13 @@ public class TFloat extends TNumber implements TComparable { int sz = 0; int bits = floatToIntBits(f); boolean subNormal = false; + boolean negative = (bits & (1 << 31)) != 0; int exp = ((bits >>> 23) & 0xFF) - 127; int mantissa = (bits & 0x7FFFFF) << 1; if (exp == -127) { + if (mantissa == 0) { + return negative ? "-0x0.0p0" : "0x0.0p0"; + } ++exp; subNormal = true; } @@ -310,7 +314,7 @@ public class TFloat extends TNumber implements TComparable { buffer[sz++] = subNormal ? '0' : '1'; buffer[sz++] = 'x'; buffer[sz++] = '0'; - if ((bits & (1L << 31)) != 0) { + if (negative) { buffer[sz++] = '-'; } int half = sz / 2; diff --git a/tests/src/test/java/org/teavm/classlib/java/lang/DoubleTest.java b/tests/src/test/java/org/teavm/classlib/java/lang/DoubleTest.java index 4f3a67429..178e7bec2 100644 --- a/tests/src/test/java/org/teavm/classlib/java/lang/DoubleTest.java +++ b/tests/src/test/java/org/teavm/classlib/java/lang/DoubleTest.java @@ -131,6 +131,8 @@ public class DoubleTest { assertEquals("0x1.0p-1022", Double.toHexString(0x1.0p-1022)); assertEquals("0x0.8p-1022", Double.toHexString(0x0.8p-1022)); assertEquals("0x0.001p-1022", Double.toHexString(0x0.001p-1022)); + assertEquals("0x0.0p0", Double.toHexString(0.0D)); + assertEquals("-0x0.0p0", Double.toHexString(-0.0D)); } @Test diff --git a/tests/src/test/java/org/teavm/classlib/java/lang/FloatTest.java b/tests/src/test/java/org/teavm/classlib/java/lang/FloatTest.java index 80bac2282..57190126c 100644 --- a/tests/src/test/java/org/teavm/classlib/java/lang/FloatTest.java +++ b/tests/src/test/java/org/teavm/classlib/java/lang/FloatTest.java @@ -112,6 +112,8 @@ public class FloatTest { assertEquals("0x1.0p-2", Float.toHexString(0.25f)); assertEquals("0x1.0p-126", Float.toHexString((float) Math.pow(2, -126))); assertEquals("0x0.001p-126", Float.toHexString(0x0.001p-126f)); + assertEquals("0x0.0p0", Float.toHexString(0.0F)); + assertEquals("-0x0.0p0", Float.toHexString(-0.0F)); } @Test