diff --git a/classlib/src/main/java/org/teavm/classlib/java/lang/TInteger.java b/classlib/src/main/java/org/teavm/classlib/java/lang/TInteger.java index a42a2a358..e5203eebb 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/lang/TInteger.java +++ b/classlib/src/main/java/org/teavm/classlib/java/lang/TInteger.java @@ -331,11 +331,11 @@ public class TInteger extends TNumber implements TComparable { } public static int highestOneBit(int i) { - return 0x80000000 >>> numberOfLeadingZeros(i); + return i & (0x80000000 >>> numberOfLeadingZeros(i)); } public static int lowestOneBit(int i) { - return 1 << numberOfTrailingZeros(i); + return -i & i; } public static int bitCount(int i) { diff --git a/classlib/src/main/java/org/teavm/classlib/java/lang/TLong.java b/classlib/src/main/java/org/teavm/classlib/java/lang/TLong.java index d7b9e0881..21210fb7f 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/lang/TLong.java +++ b/classlib/src/main/java/org/teavm/classlib/java/lang/TLong.java @@ -254,10 +254,6 @@ public class TLong extends TNumber implements TComparable { } } - public static long highestOneBit(long i) { - return 0x8000000000000000L >>> numberOfLeadingZeros(i); - } - public static int numberOfLeadingZeros(long i) { if (i == 0) { return SIZE; @@ -322,9 +318,12 @@ public class TLong extends TNumber implements TComparable { return SIZE - n - 1; } + public static long highestOneBit(long i) { + return i & (0x8000000000000000L >>> numberOfLeadingZeros(i)); + } public static long lowestOneBit(long i) { - return 1L << numberOfTrailingZeros(i); + return -i & i; } public static int bitCount(long i) { diff --git a/tests/src/test/java/org/teavm/classlib/java/lang/IntegerTest.java b/tests/src/test/java/org/teavm/classlib/java/lang/IntegerTest.java index 6405b8bfa..aff6ef5b9 100644 --- a/tests/src/test/java/org/teavm/classlib/java/lang/IntegerTest.java +++ b/tests/src/test/java/org/teavm/classlib/java/lang/IntegerTest.java @@ -26,6 +26,12 @@ import org.teavm.junit.WholeClassCompilation; @RunWith(TeaVMTestRunner.class) @WholeClassCompilation public class IntegerTest { + @Test + public void testRightUnsignedShift() { + assertEquals(1 << 31, Integer.MIN_VALUE >>> Integer.parseInt("0")); + assertEquals(-1, -1 >>> Integer.parseInt("0")); + } + @Test public void parsesInteger() { assertEquals(0, Integer.parseInt("0", 10)); @@ -86,6 +92,7 @@ public class IntegerTest { @Test public void numberOfLeadingZerosComputed() { + assertEquals(0, Integer.numberOfLeadingZeros(-1)); assertEquals(1, Integer.numberOfLeadingZeros(0x40000000)); assertEquals(1, Integer.numberOfLeadingZeros(0x40000123)); assertEquals(1, Integer.numberOfLeadingZeros(0x7FFFFFFF)); @@ -112,6 +119,21 @@ public class IntegerTest { assertEquals(32, Integer.numberOfTrailingZeros(0)); } + @Test + public void highestOneBit() { + assertEquals(1 << 31, Integer.highestOneBit(-1)); + assertEquals(1 << 31, Integer.highestOneBit(Integer.MIN_VALUE)); + assertEquals(0, Integer.highestOneBit(0)); + assertEquals(16, Integer.highestOneBit(31)); + } + + @Test + public void lowestOneBit() { + assertEquals(0, Integer.lowestOneBit(0)); + assertEquals(2, Integer.lowestOneBit(50)); + assertEquals(1, Integer.lowestOneBit(-1)); + } + @Test public void bitsCounted() { assertEquals(0, Integer.bitCount(0)); diff --git a/tests/src/test/java/org/teavm/classlib/java/lang/LongTest.java b/tests/src/test/java/org/teavm/classlib/java/lang/LongTest.java index 1d4bfdfda..3b970e8a6 100644 --- a/tests/src/test/java/org/teavm/classlib/java/lang/LongTest.java +++ b/tests/src/test/java/org/teavm/classlib/java/lang/LongTest.java @@ -64,6 +64,21 @@ public class LongTest { assertEquals(0xF63BA00000000000L, Long.reverse(0x5DC6F)); } + @Test + public void highestOneBit() { + assertEquals(1L << 63, Long.highestOneBit(-1L)); + assertEquals(1L << 63, Long.highestOneBit(Long.MIN_VALUE)); + assertEquals(0, Long.highestOneBit(0L)); + assertEquals(16L, Long.highestOneBit(31L)); + } + + @Test + public void lowestOneBit() { + assertEquals(0L, Long.lowestOneBit(0L)); + assertEquals(2L, Long.lowestOneBit(50L)); + assertEquals(1L, Long.lowestOneBit(-1L)); + } + @Test public void bitsCounted() { assertEquals(39, Long.bitCount(2587208649207147453L));