Unsigned short in Java

Java does not have unsigned data types. Your options are:

Using a char

A char variable is meant to store characters (16-bit unicode code points), but can also be used for numerical values between 0 and 65,535.

char i = 65000;
char j = 10;
char sum  = (char) (i + j);  // 65010
char diff = (char) (i - j);  // 64990
char prod = (char) (j * j);  // 100
char quot = (char) (i / j);  // 6500

The casting is required, since a char is implicitly widened to an int during computations.

As expected, it wrapps around to 0 upon overflow:

char c = Character.MAX_VALUE;  // 65535
c++;
System.out.println((int) c);  // 0

An unsigned short

A short is always signed in Java, but nothing prevents you from viewing a short simply as 16 bits and interpret those bits as a value between 0 and 65,535.

Java short value Bits Interpreted as unsigned
0 0000000000000000 0
1 0000000000000001 1
32,767 0111111111111111 32,767
−32,768 1000000000000000 32,768
−2 1111111111111110 65,534
−1 1111111111111111 65,535

Keep in mind that there’s nothing you can do to force your interpretation upon someone else’s method. If a method accepts a short, then that method accepts a value between −32,768 and 32,767 unless explicitly stated otherwise.

Here are a couple of useful conversions / manipulations.

Printing an unsigned short

Use Short.toUnsignedInt and print the resulting int:

System.out.println("Value of my unsigned short: " + Short.toUnsignedInt(s));

Converting from int to unsigned short

Casting to short throws away all but the lowest 16 bits.

int i = 65000;        // 00000000 00000000 11111101 11101000
short s = (short) i;  //                   11111101 11101000

System.out.println(s);                       // -536
System.out.println(Short.toUnsignedInt(s));  // 65000

Converting from unsigned short to int

Use Short.toUnsignedInt to avoid sign extension.

short s = (short) (Short.MAX_VALUE + 7233);  // -25536 or 40000

int signed = s;                         // -25536 (with sign extension)
int unsigned = Short.toUnsignedInt(s);  //  40000 (without sign extension)

Or, equivalently:

int unsigned = s & 0xffff;

Parsing an unsigned short

short s = (short) Integer.parseInt("65000");

System.out.println(Short.toUnsignedInt(s)); // 65000

Comparing unsigned shorts

Convert to int and compare.

int cmp = Integer.compare(Short.toUnsignedInt(s1), Short.toUnsignedInt(s2));
// cmp = -1  =>  s1 < s2
// cmp =  0  =>  s1 = s2
// cmp =  1  =>  s1 > s2

Arithmetics

The 2-complement representation “just works” for addition, subtraction and multiplication.

// two unsigned shorts
short s1 = (short) 65000;
short s2 = 100;

short sum  = (short) (s1 + s2);  // 65100
short diff = (short) (s1 - s2);  // 64900
short prod = (short) (s2 * s2);  // 10000

For division and remainder, convert operands to int, and then convert the result back to short:

short q = (short) (Short.toUnsignedInt(s1) / Short.toUnsignedInt(s2));
short r = (short) (Short.toUnsignedInt(s1) % Short.toUnsignedInt(s2));

Comments

Be the first to comment!