diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TDouble.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TDouble.java index dac196fd7..5efb84a82 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TDouble.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TDouble.java @@ -243,10 +243,18 @@ public class TDouble extends TNumber implements TComparable { } double abs = TMath.abs(value); int exp = TMath.getExponent(abs); + int negExp = -exp + 52; if (exp < -1022) { exp = -1023; + negExp = 1022 + 52; } - long mantissa = (long)(abs * binaryExponent(exp + 52)) & 0xFFFFFFFFFFFFFL; + double doubleMantissa; + if (negExp <= 1022) { + doubleMantissa = abs * binaryExponent(negExp); + } else { + doubleMantissa = abs * 0x1p1022 * binaryExponent(negExp - 1022); + } + long mantissa = (long)(doubleMantissa) & 0xFFFFFFFFFFFFFL; return mantissa | ((exp + 1023L) << 52) | (value < 0 ? (1L << 63) : 0); } @@ -281,7 +289,13 @@ public class TDouble extends TNumber implements TComparable { char[] buffer = new char[30]; int sz = 0; long bits = doubleToLongBits(d); + boolean subNormal = false; + int exp = (int)((bits >>> 52) & 0x7FF) - 1023; long mantissa = bits & 0xFFFFFFFFFFFFFL; + if (exp == -1023) { + ++exp; + subNormal = true; + } for (int i = 0; i < 13; ++i) { int digit = (int)(mantissa & 0xF); if (digit > 0 || sz > 0) { @@ -293,16 +307,11 @@ public class TDouble extends TNumber implements TComparable { buffer[sz++] = '0'; } buffer[sz++] = '.'; - int exp = (int)((bits >>> 52) & 0x7FF); - if (exp == -1023) { - buffer[sz++] = '0'; - ++exp; - } else { - buffer[sz++] = '1'; - } + + buffer[sz++] = subNormal ? '0' : '1'; buffer[sz++] = 'x'; buffer[sz++] = '0'; - if ((bits & (1L << 63)) == 0) { + if ((bits & (1L << 63)) != 0) { buffer[sz++] = '-'; } int half = sz / 2; @@ -325,7 +334,7 @@ public class TDouble extends TNumber implements TComparable { buffer[sz++] = TCharacter.forDigit(digit, 10); first = false; } - digit *= 10; + exp %= pos; pos /= 10; } if (first) { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TMath.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TMath.java index 6e01979d6..fa15c57d2 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TMath.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TMath.java @@ -216,7 +216,7 @@ public final class TMath extends TObject { if (d > 1) { int expBit = 1 << (exponents.length - 1); for (int i = exponents.length - 1; i >= 0; --i) { - if (d > exponents[i]) { + if (d >= exponents[i]) { d *= negativeExponents[i]; exp |= expBit; } @@ -225,12 +225,12 @@ public final class TMath extends TObject { } else if (d < 1) { int expBit = 1 << (negativeExponents.length - 1); int offset = 0; - if (d < 0x1P-1024) { - d *= 0x1P52; + if (d <= 0x1p-1023) { + d *= 0x1p52; offset = 52; } for (int i = negativeExponents.length - 1; i >= 0; --i) { - if (d < negativeExponents[i]) { + if (d <= negativeExponents[i]) { d *= exponents[i]; exp |= expBit; } @@ -268,9 +268,9 @@ public final class TMath extends TObject { } private static class ExponentConstants { - public static double[] exponents = { 0x1P1, 0x1P2, 0x1P4, 0x1P8, 0x1P16, 0x1P32, 0x1P64, 0x1P128, 0x1P256, - 0x1P256, 0x1P512 }; - public static double[] negativeExponents = { 0x1P-1, 0x1P-2, 0x1P-4, 0x1P-8, 0x1P-16, 0x1P-32, 0x1P-64, - 0x1P-128, 0x1P-256, 0x1P-256, 0x1P-512 }; + public static double[] exponents = { 0x1p1, 0x1p2, 0x1p4, 0x1p8, 0x1p16, 0x1p32, 0x1p64, 0x1p128, + 0x1p256, 0x1p512 }; + public static double[] negativeExponents = { 0x1p-1, 0x1p-2, 0x1p-4, 0x1p-8, 0x1p-16, 0x1p-32, + 0x1p-64, 0x1p-128, 0x1p-256, 0x1p-512 }; } } diff --git a/teavm-classlib/src/test/java/org/teavm/classlib/java/lang/DoubleTest.java b/teavm-classlib/src/test/java/org/teavm/classlib/java/lang/DoubleTest.java index 7ed5ee8b8..6c89e7469 100644 --- a/teavm-classlib/src/test/java/org/teavm/classlib/java/lang/DoubleTest.java +++ b/teavm-classlib/src/test/java/org/teavm/classlib/java/lang/DoubleTest.java @@ -78,7 +78,8 @@ public class DoubleTest { assertEquals("0x1.8p1", Double.toHexString(3)); assertEquals("0x1.0p-1", Double.toHexString(0.5)); assertEquals("0x1.0p-2", Double.toHexString(0.25)); - assertEquals("0x1.0p-1022", Double.toHexString(Double.MIN_NORMAL)); - assertEquals("0x0.0000000000001p-1022", Double.toHexString(Double.MIN_VALUE)); + 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)); } } diff --git a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java index 23397c78e..298cfa8d2 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java @@ -817,7 +817,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext visitBinary(expr, "<<"); break; case LEFT_SHIFT_LONG: - visitBinaryFunction(expr, "Long_shr"); + visitBinaryFunction(expr, "Long_shl"); break; case RIGHT_SHIFT: visitBinary(expr, ">>"); diff --git a/teavm-core/src/main/java/org/teavm/optimization/ClassSetOptimizer.java b/teavm-core/src/main/java/org/teavm/optimization/ClassSetOptimizer.java index d2faf84c4..3a67b82c7 100644 --- a/teavm-core/src/main/java/org/teavm/optimization/ClassSetOptimizer.java +++ b/teavm-core/src/main/java/org/teavm/optimization/ClassSetOptimizer.java @@ -36,8 +36,8 @@ public class ClassSetOptimizer { } private List getOptimizations() { - return Arrays.asList(new CommonSubexpressionElimination(), - new UnusedVariableElimination()); + // TODO: repair CommonSubexpressionElimination and get it back here + return Arrays.asList(new UnusedVariableElimination()); } public void optimizeAll(ListableClassHolderSource classSource) {