Luisk4
Luisk4

Reputation: 377

How does overflow work in java?

I've read about overflow, I know that "Overflow is when a number is so large that it will no longer fit within the data type, so the system “wraps around” to the next lowest value and counts up from there".

For example:

short s = (short)1921222; // Stored as 20678

In that example we started counting from -32768 (Short.MIN_VALUE), but when I try to prove in another integer data types, it doesn't seem work the same way...

byte b = (byte)400; // Stored as -112

The example above started counting from 0 that was the only way I found to get -112

I don't know if I am doing something wrong.

Upvotes: 18

Views: 3625

Answers (4)

Kylos
Kylos

Reputation: 1938

The cast is truncating the number. (JLS)

0000 0001 1001 0000

loses the high byte to become

1001 0000

which is -112.

Upvotes: 15

The Java Language Specification says:

The integral types are byte, short, int, and long, whose values are 8-bit, 16-bit, 32-bit and 64-bit signed two's-complement integers, respectively, and char, whose values are 16-bit unsigned integers representing UTF-16 code units.

So, short and byte are both two's complement integers.

short is 16 bits, meaning it can hold 2^16 = 65536 different values. After the 65536th value, it overflows.
1921222 modulo 65536 is 20678 . This is less than 32768 (2^15, the turning point for the two's complement) so we keep a positive number.

byte is 8 bits, meaning it can hold 2^8 = 256 different values. This one overflows after the 256hth value. 400 modulo 256 is 144. This value is higher than 128, the turning point for the two's complement - hence it will be interpreted as a negative two's complement number.

Upvotes: 18

cнŝdk
cнŝdk

Reputation: 32145

In java, byte primitive type is an 8 bit signed integer, that's why you got -112 from calling:

byte b = (byte) 400;

You can avoid that and get its un-signed value, by binary adding it with 0xFF like this:

int b = (byte) 400 & 0xFF;

For further details you can check:

Upvotes: 6

QBrute
QBrute

Reputation: 4536

In addition to the other answers, you can get to that answer by manual calculation as well.

In Java, the data type byte is an 8-bit, signed integer. So the values are in the interval [-128, 127]. If you have a value of 400 and you want to see the actual value for that type, you can subtract the size of the interval from that number until you reach a value that's inside the interval.

As I said, byte is 8 bit, so the size of the interval is 256. Subtract that from your initial value: 400 - 256 = 144. This value is still outside of the interval so you have to subtract again: 144 - 256 = -112. This value is now inside the interval and is indeed the value you've seen in your test.

The same is true for your first example: short is 16 bit and signed, so the interval is [-32768, 32767] with size 65536. Doing repeated subtraction from the value 1921222 will eventually give you the value 20678 as seen in your test.

Upvotes: 4

Related Questions