I have the following loop:
for (byte i = 0 ; i < 128; i++) {
System.out.println(i + 1 + " " + name);
}
When I execute my programm it prints all numbers from -128 to 127 in an infinite loop. Why does this happen?
I have the following loop:
for (byte i = 0 ; i < 128; i++) {
System.out.println(i + 1 + " " + name);
}
When I execute my programm it prints all numbers from -128 to 127 in an infinite loop. Why does this happen?
byte is a 1-byte type so can vary between -128...127, so condition i < 128 is always true. When you add 1 to 127 it overflows and becomes -128 and so on in a (infinite) loop...
After 127, when it increments, it will become -128, so your condition won't match .
byte: The
byte
data type is an 8-bit signed two's complement integer. It has a minimum value of-128
and a maximum value of127
(inclusive). Thebyte
data type can be useful for saving memory in large arrays, where the memory savings actually matters. They can also be used in place ofint
where their limits help to clarify your code; the fact that a variable's range is limited can serve as a form of documentation.
It will work like this:
0, 1, 2, ..., 126, 127, -128, -127, ...
as 8 bits can represent a signed number up to 127.
See here for the primitive data types.
Picture says more than words
Because bytes are signed in Java so they will always be less than 128.
Why Java chose signed bytes is a mystery from the depths of time. I've never been able to understand why they corrupted a perfectly good unsigned data type :-)
Try this instead:
for (byte i = 0 ; i >= 0; ++i ) {
or, better yet:
for (int i = 0 ; i < 128; ++i ) {
because when i == 127 and and you executes i++ it overflows to -128.
The type byte has a range of -128..127. So i
is always less than 128.
Alright, so the reason behind this has been answered already, but in case you were interested in some background:
A bit
is the smallest unit of storage which the computer can recognize (n.b. not the smallest number). A bit is either a 0
or a 1
.
A byte
is an 8 bit data type, meaning it is composed of 8 bit strings such as 10101010
or 0001110
. Using simple combinatorics, we know that there are 2^8 = 256
possible combinations of bytes.
If we wanted to only represent positive numbers, we could do a straight conversion from base 2 to base 10. The way that works is, for a bit string b7b6b5b4b3b2b1b0
the number in decimal is dec = sum from n=0 to 7 of (bn * 2^n)
.
By only representing positive numbers ( an unsigned byte
) we can represent 256 possible numbers in the range 0
to 255
inclusive.
The problem comes in when we want to represent signed data. A naive approach (n.b. this is for background, not the way java does it) is to take the left most bit and make it the sign bit where 1
is negative and 0
is positive. So for example 00010110
would be 21
and 10010110
would be -21
.
There are two major problems with such a system. The first is that 00000000
is 0
and 10000000
is -0
, but as everyone knows, there is no -0
that is somehow different from 0
, but such a system allows for the number and 0 ≠ -0
. The second problem is that, due to representing two zeroes, the system only allows for representing numbers from -127
to 127
, a range of only 254
(2
less than before).
A much better system (and the one which most systems use) is called Two's Compliment. In Two's Compliment, the positive numbers are represented with their normal bit string where the leftmost bit is 0. Negative numbers are represented with the left most bit as a 1 and then calculating the two's compliment for that number (from whence the system gets its name)
Although mathematically it is a slightly more complex process, because we are dealing with the number 2
there are some short cuts. Essentially, you can take the positive version and (from right to left) take all zeroes until you hit a 1. Copy those zeroes and one, then take the NOT
of the rest of the bits. So for example, to get -21
, positive 21
is 00010110
we take the 10
and not the rest to get 11101010
, the two's compliment representation of -21
.
Two's Compliment is a much more difficult system to grasp, but it avoids the previously stated problems, and for an n-bit number can represent all digits from -2^(n-1)
to 2^(n-1)-1
which for our byte means -128
to 127
(hence the problem in this question)
A couple of notes:
- This is for integer representation only. Real number representation is another system entirely (if there is a request for it, I'm sure we could make a number representation CW post)
- Wikipedia has a couple more number representation systems if you're interested.
Best is if you do
for (byte i = 0 ; i < Byte.MAX_VALUE; i++ ) {
System.out.println( i + 1 + " " + name );
}
this should work
for (byte i = 0 ; i<128; ++i ) {
if(i==-128)
break;
System.out.println( i + 1 + " " + "name" );
}