From ffb73cefec1a2dcb383880a1ad33315486108098 Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Mon, 13 Jan 2025 21:07:50 -0600 Subject: [PATCH] CLDC 8: Integer --- c/memory_allocator.c | 10 +- classes/java/lang/Integer.java | 297 +++++++++++++++++++-- classes/java/lang/Number.java | 19 ++ classes/test/TestIntegerBitCount.java | 26 ++ classes/test/TestIntegerDecode.java | 26 ++ classes/test/TestIntegerToString.java | 29 ++ classes/test/TestIntegerTrailingZeros.java | 30 +++ classes/test/TestParseInteger.java | 18 ++ 8 files changed, 435 insertions(+), 20 deletions(-) create mode 100644 classes/java/lang/Number.java create mode 100644 classes/test/TestIntegerBitCount.java create mode 100644 classes/test/TestIntegerDecode.java create mode 100644 classes/test/TestIntegerToString.java create mode 100644 classes/test/TestIntegerTrailingZeros.java create mode 100644 classes/test/TestParseInteger.java diff --git a/c/memory_allocator.c b/c/memory_allocator.c index de57e67..33a8c30 100644 --- a/c/memory_allocator.c +++ b/c/memory_allocator.c @@ -6,8 +6,8 @@ #define block_power (5UL) #define block_size (1UL << block_power) -static uint8_t memory[0x400]; -//static uint8_t memory[0x100000]; +//static uint8_t memory[0x400]; +static uint8_t memory[0x100000]; static uint8_t free_list[((sizeof (memory)) / block_size)]; const int free_list_length = (sizeof (free_list)); static uint32_t free_ix; @@ -70,8 +70,10 @@ void * memory_allocate(uint32_t size) while (true) { uint32_t ix_offset = find_contiguous_blocks(blocks, &zero_crossings); - if (zero_crossings > 1) - return nullptr; // memory allocation failed + if (zero_crossings > 1) { + printf("memory-allocate: memory allocation failed\n"); + return nullptr; + } if (ix_offset == blocks) break; uint32_t next_free_ix = (free_ix + ix_offset + 1) & (free_list_length - 1); diff --git a/classes/java/lang/Integer.java b/classes/java/lang/Integer.java index 2067096..be45d06 100644 --- a/classes/java/lang/Integer.java +++ b/classes/java/lang/Integer.java @@ -2,8 +2,221 @@ package java.lang; import java.lang.DecimalDigits; -public class Integer { - public static int stringSize(int n) { + +public final class Integer + extends Number + implements Comparable { + + public static final int MAX_VALUE = 2147483647; + + public static final int MIN_VALUE = -2147483648; + + public static final int SIZE = 32; + + private final int value; + + public Integer(int value) { + this.value = value; + } + + public Integer(String s) + throws NumberFormatException { + this.value = parseInt(s, 10); + } + + public static int bitCount(int i) { + int c; + i = i - ((i >> 1) & 0x55555555); + i = (i & 0x33333333) + ((i >> 2) & 0x33333333); + c = ((i + (i >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; + return c; + } + + public byte byteValue() { + return (byte)value; + } + + public int compareTo(Integer anotherInteger) { + if (value == anotherInteger.value) + return 0; + if (value < anotherInteger.value) + return -1; + else + return 1; + } + + public static Integer decode(String nm) + throws NumberFormatException { + int length = nm.length(); + if (length == 0) + throw new NumberFormatException(nm); + int index = 0; + char c; + c = nm.charAt(index); + if (c == '-' || c == '+') + index += 1; + boolean negative = (c == '-'); + int n; + if (index >= length) + throw new NumberFormatException(nm); + c = nm.charAt(index); + + if (nm.startsWith("0x", index) || nm.startsWith("0X", index)) { + String s = nm.substring(index + 2); + n = parseInt(s, 16); + } else if (c == '#') { + String s = nm.substring(index + 1); + n = parseInt(s, 16); + } else if (c == '0') { + String s = nm.substring(index + 1); + n = parseInt(s, 8); + } else { + n = parseInt(nm, 10); + } + if (negative) + n = -n; + return new Integer(n); + } + + public double doubleValue() { + return (double)value; + } + + public boolean equals(Object obj) { + return obj instanceof Integer && value == ((Integer)obj).value; + } + + public float floatValue() { + return (float)value; + } + + public int hashCode() { + return value; + } + + public static int highestOneBit(int i) { + i |= i >>> 1; + i |= i >>> 2; + i |= i >>> 4; + i |= i >>> 8; + i |= i >>> 16; + return i ^ (i >>> 1); + } + + public int intValue() { + return value; + } + + public long longValue() { + return (long)value; + } + + public static int lowestOneBit(int value) { + return value & (-value); + } + + public static int numberOfLeadingZeros(int i) { + int c = 0; + if (i <= 0x0000ffff) { c += 16; i <<= 16; } + if (i <= 0x00ffffff) { c += 8 ; i <<= 8 ; } + if (i <= 0x0fffffff) { c += 4 ; i <<= 4 ; } + if (i <= 0x3fffffff) { c += 2 ; i <<= 2 ; } + if (i <= 0x7fffffff) { c += 1 ; } + return c; + } + + public static int numberOfTrailingZeros(int i) { + int c = 32; + i &= -i; + if (i != 0) c--; + if ((i & 0x0000FFFF) != 0) c -= 16; + if ((i & 0x00FF00FF) != 0) c -= 8; + if ((i & 0x0F0F0F0F) != 0) c -= 4; + if ((i & 0x33333333) != 0) c -= 2; + if ((i & 0x55555555) != 0) c -= 1; + return c; + } + + public static int parseInt(String s) + throws NumberFormatException { + return parseInt(s, 10); + } + + public static int parseInt(String s, int radix) + throws NumberFormatException { + int length = s.length(); + if (length == 0) + throw new NumberFormatException(s); + int index = 0; + char c = s.charAt(index); + if (c == '-' || c == '+') + index += 1; + boolean negative = (c == '-'); + if (index >= length) + throw new NumberFormatException(s); + if (length - index > 10) + throw new NumberFormatException(s); + int n = 0; + while (index < length) { + int value = Character.digit(s.charAt(index), radix); + if (value < 0) + throw new NumberFormatException(s); + n *= radix; + n += value; + index += 1; + } + if (n < 0) // overflow + throw new NumberFormatException(s); + if (negative) + n = -n; + return n; + } + + public static int reverse(int i) { + i = ((i >> 1) & 0x55555555) | ((i & 0x55555555) << 1); + i = ((i >> 2) & 0x33333333) | ((i & 0x33333333) << 2); + i = ((i >> 4) & 0x0F0F0F0F) | ((i & 0x0F0F0F0F) << 4); + i = ((i >> 8) & 0x00FF00FF) | ((i & 0x00FF00FF) << 8); + i = ( i >> 16 ) | ( i << 16); + return i; + } + + public static int reverseBytes(int i) { + return (((i >> 24) & 0x000000ff) | + ((i >> 8 ) & 0x0000ff00) | + ((i << 8 ) & 0x00ff0000) | + ((i << 24) & 0xff000000)); + } + + public static int rotateLeft(int i, int distance) { + return (i << distance) | (i >>> (-distance)); + } + + public static int rotateRight(int i, int distance) { + return (i << (-distance)) | (i >>> distance); + } + + public short shortValue() { + return (short)value; + } + + public static int signum(int i) { + return (i >> 31) | ((-i) >>> 31); + } + + public static String toBinaryString(int i) { + return toString(i, 2); + } + + public static String toHexString(int i) { + return toString(i, 16); + } + + public static String toOctalString(int i) { + return toString(i, 8); + } + + private static int stringSize(int n) { int sign_digits = 0; if (n < 0) { sign_digits = 1; @@ -20,37 +233,89 @@ public class Integer { return 10 + sign_digits; } - public static String toString(int n) { - int pos = stringSize(n); - byte[] buf = new byte[pos]; - buf[0] = (char)'0'; + public String toString() + { + return toString(value); + } - boolean sign = n < 0; + public static String toString(int i) { + if (i == 0) + return "0"; + if (i == MIN_VALUE) + return "-2147483648"; + + int pos = stringSize(i); + byte[] buf = new byte[pos]; + + boolean sign = i < 0; if (sign) { - n = -n; + i = -i; } - while (n >= 10) { - int div = n / 100; - pos -= 2; - int mod = n - (div * 100); + while (i >= 10) { + int div = i / 100; + int mod = i - (div * 100); short digits = DecimalDigits.DIGITS[mod]; + pos -= 2; buf[pos] = (byte)(digits >> 8); buf[pos+1] = (byte)(digits); - n = div; + i = div; } - if (n != 0) { + if (i != 0) { pos -= 1; - buf[pos] = (byte)('0' + n); + buf[pos] = (byte)('0' + i); } if (sign) { pos -= 1; - buf[pos] = (byte)('-'); + buf[pos] = (byte)'-'; } return new String(buf); } + + public static String toString(int i, int radix) { + if (i == 0) + return "0"; + if (radix == 10) + return toString(i); + int pos = 32; + byte[] buf = new byte[32]; + + boolean sign = i < 0; + if (sign) { + i = -i; + } + + while (i != 0) { + int div = i / radix; + int mod = i - (div * radix); + char digit = Character.forDigit(mod, radix); + pos -= 1; + buf[pos] = (byte)digit; + i = div; + } + + if (sign) { + pos -= 1; + buf[pos] = (byte)'-'; + } + return new String(buf, pos, 32 - pos); + } + + public static Integer valueOf(int i) { + return new Integer(i); + } + + public static Integer valueOf(String s) + throws NumberFormatException { + return new Integer(Integer.parseInt(s)); + } + + public static Integer valueOf(String s, int radix) + throws NumberFormatException { + return new Integer(Integer.parseInt(s, radix)); + } } diff --git a/classes/java/lang/Number.java b/classes/java/lang/Number.java new file mode 100644 index 0000000..f24abdc --- /dev/null +++ b/classes/java/lang/Number.java @@ -0,0 +1,19 @@ +package java.lang; + +public class Number { + public byte byteValue() { + return (byte)intValue(); + } + + public abstract double doubleValue(); + + public abstract float floatValue(); + + public abstract int intValue(); + + public abstract long longValue(); + + public short shortValue() { + return (byte)shortValue(); + } +} diff --git a/classes/test/TestIntegerBitCount.java b/classes/test/TestIntegerBitCount.java new file mode 100644 index 0000000..71fe810 --- /dev/null +++ b/classes/test/TestIntegerBitCount.java @@ -0,0 +1,26 @@ +package test; + +class TestIntegerBitCount { + public static void main() { + System.out.println(Integer.bitCount(-1180362717)); + System.out.println(Integer.bitCount(2066224197)); + System.out.println(Integer.bitCount(-1284335467)); + System.out.println(Integer.bitCount(-273003009)); + System.out.println(Integer.bitCount(-609640137)); + System.out.println(Integer.bitCount(-1299058518)); + System.out.println(Integer.bitCount(1291028711)); + System.out.println(Integer.bitCount(-1690239603)); + System.out.println(Integer.bitCount(877411871)); + /* + 14 + 13 + 16 + 24 + 18 + 15 + 17 + 17 + 16 + */ + } +} diff --git a/classes/test/TestIntegerDecode.java b/classes/test/TestIntegerDecode.java new file mode 100644 index 0000000..73d0efe --- /dev/null +++ b/classes/test/TestIntegerDecode.java @@ -0,0 +1,26 @@ +package test; + +class TestIntegerDecode { + public static void main() { + System.out.println(Integer.decode("-#12aff1e1")); + System.out.println(Integer.decode("-0x3c07714b")); + System.out.println(Integer.decode("-0X3bbbfcef")); + System.out.println(Integer.decode("0x7eb38fbd")); + System.out.println(Integer.decode("-0X4a2db9bb")); + + System.out.println(Integer.decode("02637651")); + + System.out.println(Integer.decode("2637651")); + + + /* + -313520609 + -1007120715 + -1002175727 + 2125696957 + -1244510651 + 737193 + 2637651 + */ + } +} diff --git a/classes/test/TestIntegerToString.java b/classes/test/TestIntegerToString.java new file mode 100644 index 0000000..00f522b --- /dev/null +++ b/classes/test/TestIntegerToString.java @@ -0,0 +1,29 @@ +package test; + +class TestIntegerToString { + public static void main() { + System.out.println(Integer.toString(0x12aff1e1, 16)); + System.out.println(Integer.toString(-0x3c07714b, 16)); + System.out.println(Integer.toString(0x3bbbfcef, 16)); + System.out.println(Integer.toString(-0x7eb38fbd, 16)); + System.out.println(Integer.toString(-0x4a2db9bb, 16)); + + System.out.println(Integer.toString(02637651, 8)); + + System.out.println(Integer.toString(2637651, 10)); + + System.out.println(Integer.toString(0b111101111, 2)); + + + /* + 12aff1e1 + -3c07714b + 3bbbfcef + -7eb38fbd + -4a2db9bb + 2637651 + 2637651 + 111101111 + */ + } +} diff --git a/classes/test/TestIntegerTrailingZeros.java b/classes/test/TestIntegerTrailingZeros.java new file mode 100644 index 0000000..323744e --- /dev/null +++ b/classes/test/TestIntegerTrailingZeros.java @@ -0,0 +1,30 @@ +package test; + +class TestIntegerTrailingZeros { + public static void main() { + System.out.println(Integer.numberOfTrailingZeros(-1180362717)); + System.out.println(Integer.numberOfTrailingZeros(2066224196)); + System.out.println(Integer.numberOfTrailingZeros(805306368)); + System.out.println(Integer.numberOfTrailingZeros(-273003009)); + System.out.println(Integer.numberOfTrailingZeros(-609746944)); + System.out.println(Integer.numberOfTrailingZeros(-1299058518)); + System.out.println(Integer.numberOfTrailingZeros(1291028711)); + System.out.println(Integer.numberOfTrailingZeros(-1690243072)); + System.out.println(Integer.numberOfTrailingZeros(877411840)); + System.out.println(Integer.numberOfTrailingZeros(0)); + System.out.println(Integer.numberOfTrailingZeros(-2147483648)); + /* + 0 + 2 + 28 + 0 + 19 + 1 + 0 + 12 + 9 + 32 + 31 + */ + } +} diff --git a/classes/test/TestParseInteger.java b/classes/test/TestParseInteger.java new file mode 100644 index 0000000..d2d92a1 --- /dev/null +++ b/classes/test/TestParseInteger.java @@ -0,0 +1,18 @@ +package test; + +class TestParseInteger { + public static void main() { + System.out.println(Integer.parseInt("0", 10)); // returns 0 + System.out.println(Integer.parseInt("473", 10)); // returns 473 + System.out.println(Integer.parseInt("+42", 10)); // returns 42 + System.out.println(Integer.parseInt("-0", 10)); // returns 0 + System.out.println(Integer.parseInt("-FF", 16)); // returns -255 + System.out.println(Integer.parseInt("1100110", 2)); // returns 102 + System.out.println(Integer.parseInt("2147483647", 10)); // returns 2147483647 + System.out.println(Integer.parseInt("-2147483648", 10)); // returns -2147483648 + System.out.println(Integer.parseInt("2147483648", 10)); // throws a NumberFormatException + System.out.println(Integer.parseInt("99", 8)); // throws a NumberFormatException + System.out.println(Integer.parseInt("Kona", 10)); // throws a NumberFormatException + System.out.println(Integer.parseInt("Kona", 27)); // returns 411787 + } +}