From 136edd4e44c9674fc0b2594b4619760e05a8d810 Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Sat, 8 Mar 2014 14:38:32 +0400 Subject: [PATCH] Completes java.lang.Integer emulation --- .../teavm/classlib/java/lang/TInteger.java | 102 ++++++++++++++++++ .../teavm/classlib/java/lang/IntegerTest.java | 56 ++++++++++ 2 files changed, 158 insertions(+) diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TInteger.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TInteger.java index 236b78e15..8d75bcf3a 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TInteger.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TInteger.java @@ -251,4 +251,106 @@ public class TInteger extends TNumber implements TComparable { public static int compare(int x, int y) { return x > y ? 1 : x < y ? -1 : 0; } + + public static int numberOfLeadingZeros(int i) { + if (i == 0) { + return SIZE; + } + int n = 0; + if (i >>> 16 != 0) { + i >>>= 16; + n |= 16; + } + if (i >>> 8 != 0) { + i >>>= 8; + n |= 8; + } + if (i >>> 4 != 0) { + i >>>= 4; + n |= 4; + } + if (i >>> 2 != 0) { + i >>>= 2; + n |= 2; + } + if (i >>> 1 != 0) { + i >>>= 1; + n |= 1; + } + return SIZE - n - 1; + } + + public static int numberOfTrailingZeros(int i) { + if (i == 0) { + return SIZE; + } + int n = 0; + if (i << 16 != 0) { + i <<= 16; + n |= 16; + } + if (i << 8 != 0) { + i <<= 8; + n |= 8; + } + if (i << 4 != 0) { + i <<= 4; + n |= 4; + } + if (i << 2 != 0) { + i <<= 2; + n |= 2; + } + if (i << 1 != 0) { + i <<= 1; + n |= 1; + } + return SIZE - n - 1; + } + + public static int highestOneBit(int i) { + return 0x80000000 >>> numberOfLeadingZeros(i); + } + + public static int lowestOneBit(int i) { + return 1 << numberOfTrailingZeros(i); + } + + public static int bitCount(int i) { + i = (i & 0xAAAAAAAA) >> 1 + i & 0x55555555; + i = (i & 0xCCCCCCCC) >> 2 + i & 0x33333333; + i = (i & 0x30303030) >> 4 + i & 0x03030303; + i = (i & 0x07000700) >> 8 + i & 0x00070007; + i = (i & 0x000F0000) >> 16 + i & 0x0000000F; + return i; + } + + public static int rotateLeft(int i, int distance) { + distance &= 0x1F; + return (i << distance) | (i >>> (32 - distance)); + } + + public static int rotateRight(int i, int distance) { + distance &= 0x1F; + return (i >>> distance) | (i << (32 - distance)); + } + + public static int reverse(int i) { + i = (i & 0xAAAAAAAA) >> 1 + (i & 0x55555555) << 1; + i = (i & 0xCCCCCCCC) >> 2 + (i & 0x33333333) << 2; + i = (i & 0xF0F0F0F0) >> 4 + (i & 0x0F0F0F0F) << 4; + i = (i & 0xFF00FF00) >> 8 + (i & 0x00FF00FF) << 8; + i = (i & 0xFFFF0000) >> 16 + (i & 0x0000FFFF) << 16; + return i; + } + + public static int reverseBytes(int i) { + i = (i & 0xFF00FF00) >> 8 + (i & 0x00FF00FF) << 8; + i = i >> 16 + i << 16; + return i; + } + + public static int signum(int i) { + return (i >> 31) | (-i >>> 31); + } } diff --git a/teavm-classlib/src/test/java/org/teavm/classlib/java/lang/IntegerTest.java b/teavm-classlib/src/test/java/org/teavm/classlib/java/lang/IntegerTest.java index 49abb4458..485663cf2 100644 --- a/teavm-classlib/src/test/java/org/teavm/classlib/java/lang/IntegerTest.java +++ b/teavm-classlib/src/test/java/org/teavm/classlib/java/lang/IntegerTest.java @@ -67,4 +67,60 @@ public class IntegerTest { assertEquals(Integer.valueOf(-255), Integer.decode("-0xFF")); assertEquals(Integer.valueOf(2748), Integer.decode("+#ABC")); } + + @Test + public void numberOfLeadingZerosComputed() { + assertEquals(1, Integer.numberOfLeadingZeros(0x40000000)); + assertEquals(1, Integer.numberOfLeadingZeros(0x40000123)); + assertEquals(1, Integer.numberOfLeadingZeros(0x7FFFFFFF)); + assertEquals(31, Integer.numberOfLeadingZeros(1)); + assertEquals(30, Integer.numberOfLeadingZeros(2)); + assertEquals(30, Integer.numberOfLeadingZeros(3)); + assertEquals(0, Integer.numberOfLeadingZeros(0x80000000)); + assertEquals(0, Integer.numberOfLeadingZeros(0x80000123)); + assertEquals(0, Integer.numberOfLeadingZeros(0xFFFFFFFF)); + assertEquals(32, Integer.numberOfLeadingZeros(0)); + } + + @Test + public void numberOfTrailingZerosComputed() { + assertEquals(1, Integer.numberOfTrailingZeros(0xFFFFFFFE)); + assertEquals(1, Integer.numberOfTrailingZeros(0x40000002)); + assertEquals(1, Integer.numberOfTrailingZeros(0x00000002)); + assertEquals(31, Integer.numberOfTrailingZeros(0x80000000)); + assertEquals(30, Integer.numberOfTrailingZeros(0x40000000)); + assertEquals(30, Integer.numberOfTrailingZeros(0xC0000000)); + assertEquals(0, Integer.numberOfTrailingZeros(0x00000001)); + assertEquals(0, Integer.numberOfTrailingZeros(0x12300003)); + assertEquals(0, Integer.numberOfTrailingZeros(0xFFFFFFFF)); + assertEquals(32, Integer.numberOfTrailingZeros(0)); + } + + @Test + public void bitsCounted() { + assertEquals(0, Integer.bitCount(0)); + assertEquals(1, Integer.bitCount(1)); + assertEquals(1, Integer.bitCount(0x400)); + assertEquals(1, Integer.bitCount(0x80000000)); + assertEquals(8, Integer.bitCount(0x11111111)); + assertEquals(8, Integer.bitCount(0x30303030)); + assertEquals(8, Integer.bitCount(0xFF000000)); + assertEquals(8, Integer.bitCount(0x000000FF)); + assertEquals(32, Integer.bitCount(0xFFFFFFFF)); + assertEquals(13, Integer.bitCount(0x5DC6F)); + } + + @Test + public void bitsReversed() { + assertEquals(0, Integer.reverse(0)); + assertEquals(0x80000000, Integer.reverse(1)); + assertEquals(0x00200000, Integer.reverse(0x400)); + assertEquals(0x00000001, Integer.reverse(0x80000000)); + assertEquals(0x88888888, Integer.reverse(0x11111111)); + assertEquals(0x0C0C0C0C, Integer.reverse(0x30303030)); + assertEquals(0x000000FF, Integer.reverse(0xFF000000)); + assertEquals(0xFF000000, Integer.reverse(0x000000FF)); + assertEquals(0xFFFFFFFF, Integer.reverse(0xFFFFFFFF)); + assertEquals(0xF63BA000, Integer.reverse(0x5DC6F)); + } }