programming forums Java Java JSRs Mobile Certification Databases Caching Books Engineering OS Languages Paradigms IDEs Build Tools Frameworks Products This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
Sheriffs:
Saloon Keepers:
Bartenders:

# Type conversion and the most significant bit

Bora Sabrioglu
Ranch Hand
Posts: 100
Hi guys,

I'm referring to an example at page 187 in the SCJP6 Study Guide (Bates/Sierra):

If I type

I get a negative number as a result.

But if I append an L to the hex number:

the resulting number is a positive one.

Can one tell me what the difference is between those two lines:

and

(same as above, but without the suffix L).

If I don't append the L, is the msb (most significant bit) somehow still carried over to the resulting long variable and in the latter case, where I append an L, it is not and instead the value is filled up with 32 leading zeros (4 Byte difference between int and long)?

Paweł Baczyński
Bartender
Posts: 2082
44
• 1
0xDeadCafe is int literal. This is 11011110101011011100101011111110 in binary. The most significant bit is 1 so the number is negative.
0xDeadCafeL is long literal. This is 0000000000000000000000000000000011011110101011011100101011111110 in binary. The most significant bit is 0 so the number is positive.

0xDeadCafe is int. 11011110101011011100101011111110 in binary. 32 bits.
When you assign it to long variable it will be promoted to long in a way that it holds the same value in Two's_complement notation on 64 bits.
The original int was negative, so resulting long value will be negative too.
And it will be 1111111111111111111111111111111111011110101011011100101011111110 in binary.

Bora Sabrioglu
Ranch Hand
Posts: 100
Pawel Pawlowicz wrote:
0xDeadCafe is int. 11011110101011011100101011111110 in binary. 32 bits.
When you assign it to long variable it will be promoted to long in a way that it holds the same value in Two's_complement notation on 64 bits.
The original int was negative, so resulting long value will be negative too.

... as I suspected...

Thanks alot.

Campbell Ritchie
Marshal
Posts: 56533
172
To add to what PP said:
Obscure confusing feature, which you will find in the Java Language Specification: all integer literals are unsigned. Decimal int literals are in the range 0..2147483648 inclusive, but the biggest number must be preceded by the sign change operator. If you write −123 that is not a negative number. It is the unsigned number 123 and the sign change operator −. Hex int literals occupy the range 0x0..0xffffffff, so half that range represent negative numbers. A number like 0xCafeBabe has an unsigned value greater than 0x7fffffff, so it can be written as unsigned and is interpreted as negative.
Since longs have a bigger range, 0xCafeBabeL is under half the range (< 0x7fffffffffffffff), so it is seen an unsigned and interpreted as positive.

You know that 0xCafeBabe is the Java® “magic number”?

Bora Sabrioglu
Ranch Hand
Posts: 100
Campbell Ritchie wrote:Obscure confusing feature

good to know ;)
You know that 0xCafeBabe is the Java® “magic number”?

Bora Sabrioglu
Ranch Hand
Posts: 100
Check this out:

If I type

... it does not matter if I write the minus in front of the hex number or not... the result is ALWAYS the same negative value... now THIS really sucks...
[if I append an L at the end of the hex literal the outcome is as expected (only negative in the case of minus in front of the literal) of course]

But if I write for example:

then the outcome is as expected... positive value (1) with the minus in front of the literal as seen above in the code snippet and negative value (-1) without the minus in front of it...

Henry Wong
author
Sheriff
Posts: 23295
125
• 1
Bora Sabrioglu wrote:
If I type

... it does not matter if I write the minus in front of the hex number or not... the result is ALWAYS the same negative value... now THIS really sucks...

That is a quirk of twos complement notation -- and not specific to Java.

Henry

Bora Sabrioglu
Ranch Hand
Posts: 100
you're right!

Thanks!

Campbell Ritchie
Marshal
Posts: 56533
172
Try multiplying 0b1000_0000_0000_0000_0000_0000_0000_0000_0000 by 0b1111_1111_1111_1111_1111_1111_1111_1111_1111. Remember that you get exactly 32 bits numbered 0‑31 and any carry bits in bit 32+ simply vanish in to cyber‑limbo never to be seen again.
…or something like that. The xs represent 1 bits which have disappeared by being carried beyond the capacity of the datatype, a sort of overflow.

Bora Sabrioglu
Ranch Hand
Posts: 100
yeah, I was thinking about something similiar too... that's why there can never be something like -0 using twos complement because if you try to do that you will get an carry over bit that is at position n+1, n being the number of bits you have... so... the result is still zero (n zeros, say n=32: 00....00, twos complement: 11....11 +1 => 100....000, the 1 being at the 33rd position => cut off. Result: 00....00 = 0)

 Did you see how Paul cut 87% off of his electric heat bill with 82 watts of micro heaters?