This loop will continue indefinitely:
char a = 100;
for(a=100; a>=0;--a)
System.out.println(a);
Does it happen because a gets promoted to an int value for arithmetic operations and gets widened to 32 bits from 16 bit char value and hence will always stay positive?
It will indeed loop indefinitely — and the reason you stated is close. It happens because
acan’t represent any number that doesn’t satisfya >= 0—charis unsigned. Arithmetic underflow is well-defined in Java and unindicated. See the below relevant parts of the specification.§4.2.2
This means there is no indication of overflow/underflow other than just comparing the values… e.g. if
a<=--a, then that means an underflow occured.§15.15.2
So, we can see that there are two major steps here: binary numeric promotion, followed by a narrowing pritimive conversion.
§5.6.2
We can see that the decrement expression works with
atreated asint, thus performing a widening conversion. This allows it to represent the value -1.§5.1.3
Keeping only the n lowest order bits means that only the lowest 16 bits of the
intexpressiona - 1are kept. Since -1 is 0b11111111 11111111 11111111 11111111 here, only the lower 0b11111111 11111111 is saved. Sincecharis unsigned, all of these bits contribute to the result, giving 65535.Noticing something here? Essentially, this all means that Java integer arithmetic is modular; in this case, the modulus is 2^16, or 65536, because
charis a 16-bit datatype. -1 (mod 65536) ≡ 65535, so the decrement will wrap back around.