Unsigned short in Java
Java does not have unsigned data types. Your options are:
- Use a
char
- Use an
int
- Use a
short
and “manually” interpret the bits unsigned (described below)
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 short
s
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));