classlib: improve and fix Integer/Long long bit operations

This commit is contained in:
Ivan Hetman 2023-05-16 12:08:05 +03:00 committed by GitHub
parent 73d2379185
commit ac8cb377c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 43 additions and 7 deletions

View File

@ -331,11 +331,11 @@ public class TInteger extends TNumber implements TComparable<TInteger> {
}
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) {

View File

@ -254,10 +254,6 @@ public class TLong extends TNumber implements TComparable<TLong> {
}
}
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<TLong> {
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) {

View File

@ -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));

View File

@ -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));