posted 2 years ago

The error is occurring with this piece of code ...

When the i variable is something large (say one million), then the j variable will be larger (say one trillion, or one million times one million). Anyway, one trillion is much larger than can be held in an int variable. So, the variable will overflow -- and become negative.

Henry

Rrohit rakesh upadhyay wrote:

i do not understand how the index becomes negative and how come it is going out of bounds at all.

The error is occurring with this piece of code ...

When the i variable is something large (say one million), then the j variable will be larger (say one trillion, or one million times one million). Anyway, one trillion is much larger than can be held in an int variable. So, the variable will overflow -- and become negative.

Henry

Mike. J. Thompson

Bartender

Posts: 689

17

posted 2 years ago

In Java ints are signed 32 bit numbers, stored 2's complement form. That means that an int can only store 2^32 (approx 4 billion) different values, and roughly half of those are negative. To view the largest possible int value print out Integer.MAX_VALUE.

Your code is calculating up to 1000000 squared, which is way bigger than Integer.MAX_VALUE. When you overflow the maximum possible int value you jump to the smallest possible int value (Integer.MIN_VALUE). So as soon as you get a value of i big enough such that i^2 is bigger than Integer.MAX_VALUE then your index becomes negative.

Edit: Beaten to it by Henry, I need to type faster.

Your code is calculating up to 1000000 squared, which is way bigger than Integer.MAX_VALUE. When you overflow the maximum possible int value you jump to the smallest possible int value (Integer.MIN_VALUE). So as soon as you get a value of i big enough such that i^2 is bigger than Integer.MAX_VALUE then your index becomes negative.

Edit: Beaten to it by Henry, I need to type faster.

Campbell Ritchie

Marshal

Posts: 56527

172

posted 2 years ago

This is not a Java specific standard. Java follows the Twos Complement standard with int (and related) types, and that standard has been around since (I would guess) the 1950s or 1960s.

Henry

Rrohit rakesh upadhyay wrote:I knew about the limits of the int data type in java but i did not know that it is assigned negative value if overflow happens.

This is not a Java specific standard. Java follows the Twos Complement standard with int (and related) types, and that standard has been around since (I would guess) the 1950s or 1960s.

Henry

posted 2 years ago

Byte is a 8 bits signed two's complement integer, which can hold values in range -128 and 127. So, byte type integer 127 is a 01111111 in two's complement notation (1st bit is a sign bit) .

What happens if you try to store for instance integer 128 (remember, max value can store is 127) in byte data type. So you get 10000000 in binary. As byte is only 8 bits long, 1st bit is a sign bit (1 negative, 0 positive), so in this case you get -128 in two's complement notation.

And you could try this code to see it yourself:

And what is interesting, that these negative values are not random numbers. Lets take simple example to understand what is happening.Rrohit rakesh upadhyay wrote:I knew about the limits of the int data type in java but i did not know that it is assigned negative value if overflow happens.

Byte is a 8 bits signed two's complement integer, which can hold values in range -128 and 127. So, byte type integer 127 is a 01111111 in two's complement notation (1st bit is a sign bit) .

What happens if you try to store for instance integer 128 (remember, max value can store is 127) in byte data type. So you get 10000000 in binary. As byte is only 8 bits long, 1st bit is a sign bit (1 negative, 0 positive), so in this case you get -128 in two's complement notation.

And you could try this code to see it yourself:

posted 2 years ago

Does this mean if i assign a number that is greater than the upper bound, the two's compliment of that number is calculated and the binary number that we get after two's compliment (10000000 in case of 128) is just represented as an integer with a negative sign?

What happens if you try to store for instance integer 128 (remember, max value can store is 127) in byte data type. So you get 10000000 in binary. As byte is only 8 bits long, 1st bit is a sign bit (1 negative, 0 positive), so in this case you get -128 in two's complement notation.

And you could try this code to see it yourself:

Does this mean if i assign a number that is greater than the upper bound, the two's compliment of that number is calculated and the binary number that we get after two's compliment (10000000 in case of 128) is just represented as an integer with a negative sign?

posted 2 years ago

Lets take another example of 257. In binary it is 1 0000 0001 (9 bits). Since byte can hold only 8 bits, you take only 8

No. You not simply invert the sign.Rrohit rakesh upadhyay wrote:Does this mean if i assign a number that is greater than the upper bound, the two's compliment of that number is calculated and the binary number that we get after two's compliment (10000000 in case of 128)is just represented as an integer with a negative sign?

Lets take another example of 257. In binary it is 1 0000 0001 (9 bits). Since byte can hold only 8 bits, you take only 8

__right most__bits and you have left 0000 0001 in binary, which is 1 in two's complement notation. So assigning 257 to byte data type variable, after you print it out you'd get 1. Don't forget, in order to assign 257 you'd need to cast to byte "b = (byte)257", in this case you'd let Java know, that you know what you're doing and you can loose some precision.

Campbell Ritchie

Marshal

Posts: 56527

172

posted 2 years ago

What happens is that the arithmetic produces something which won't fit into the 31 bits available; if you only go into the 32nd bit you change the sign of the number. If your arithmetic produces something which will only fit into 33+ bits, the bits over 32 disappear into cyber‑limbo never to be seen again and you end up with something which bears no apparent similarity to the expected result. Look at the following code which does repeated multiplications. Before you run it, tell me how many times it will print out:-you should be able to see where the overflow occurs and you cannot see how those results are obtained by multiplying the previous factorials, because 33rd bits and more have vanished.

You cannot have numbers greater than the largest bound. Try this and it won't compile:-Rrohit rakesh upadhyay wrote: . . . if i assign a number that is greater than the upper bound,. . . .

`int i = 12345678987654321;`

What happens is that the arithmetic produces something which won't fit into the 31 bits available; if you only go into the 32nd bit you change the sign of the number. If your arithmetic produces something which will only fit into 33+ bits, the bits over 32 disappear into cyber‑limbo never to be seen again and you end up with something which bears no apparent similarity to the expected result. Look at the following code which does repeated multiplications. Before you run it, tell me how many times it will print out:-you should be able to see where the overflow occurs and you cannot see how those results are obtained by multiplying the previous factorials, because 33rd bits and more have vanished.