private static Number convertUnsigned(Number value, Signedness signedness) { if (signedness == Signedness.UNSIGNED) { // Handle integral types that should be treated as unsigned by widening them if necessary. return DataType.widenNumberIfNegative(value); } else { return value; } }
public String toString() { StringBuilder sbuff = new StringBuilder(); IndexIterator ii = getIndexIterator(); while (ii.hasNext()) { Object value = ii.getObjectNext(); if (isUnsigned()) { assert value instanceof Number : "A data type being unsigned implies that it is numeric."; // "value" is an unsigned number, but it will be treated as signed when we print it below, because Java only // has signed types. If it's large enough ( >= 2^(BIT_WIDTH-1) ), its most-significant bit will be interpreted // as the sign bit, which will result in an invalid (negative) value being printed. To prevent that, we're // going to widen the number before printing it, but only if the unsigned number is being seen as negative. value = DataType.widenNumberIfNegative((Number) value); } sbuff.append(value); sbuff.append(" "); } return sbuff.toString(); }
@Test public void convertUnsignedLong() { // The maximum signed long is 9223372036854775807. // So, the number below fits in an unsigned long, but not a signed long. BigInteger tenQuintillion = new BigInteger("10000000000000000000"); // Nineteen zeros. // Widen regardless assertSameNumber(BigInteger.valueOf(3372036854775L), DataType.widenNumber((long) 3372036854775L)); // Widen only if negative. assertSameNumber(3372036854775L, DataType.widenNumberIfNegative((long) 3372036854775L)); assertSameNumber(tenQuintillion, DataType.widenNumberIfNegative(tenQuintillion.longValue())); assertSameNumber(new BigInteger("18446620616920539271"), DataType.widenNumberIfNegative((long) -123456789012345L)); }
@Test public void convertUnsignedByte() { // Widen regardless assertSameNumber((short) 12, DataType.widenNumber((byte) 12)); // Widen only if negative. assertSameNumber((byte) 12, DataType.widenNumberIfNegative((byte) 12)); assertSameNumber((short) 155, DataType.widenNumberIfNegative((byte) 155)); assertSameNumber((short) 224, DataType.widenNumberIfNegative((byte) -32)); }
@Test public void convertUnsignedShort() { // Widen regardless assertSameNumber((int) 3251, DataType.widenNumber((short) 3251)); // Widen only if negative. assertSameNumber((short) 3251, DataType.widenNumberIfNegative((short) 3251)); assertSameNumber((int) 40000, DataType.widenNumberIfNegative((short) 40000)); assertSameNumber((int) 43314, DataType.widenNumberIfNegative((short) -22222)); }
@Test public void convertUnsignedInt() { // Widen regardless assertSameNumber((long) 123456, DataType.widenNumber((int) 123456)); // Widen only if negative. assertSameNumber((int) 123456, DataType.widenNumberIfNegative((int) 123456)); assertSameNumber((long) 3500000000L, DataType.widenNumberIfNegative((int) 3500000000L)); assertSameNumber((long) 4289531025L, DataType.widenNumberIfNegative((int) -5436271)); }
value = DataType.widenNumberIfNegative((Number) value); value = DataType.widenNumberIfNegative((Number) value);