简体   繁体   中英

Assign negative int to long in java

I've 2 integer values stored in a bytebuffer, in little-endian format. These integers are actually the 32-bit pieces of a long. I've to store them as a class' member variables, loBits and hiBits .

This is what I did:

long loBits = buffer.getInt(offset);
long hiBits = buffer.getInt(offset + Integer.BYTES);

I want to know why directly assigning signed int to long is wrong. I kind of know what's going on, but would really appreciate an explanation.

The int I read from the buffer is signed (because Java). If it is negative then directly assigning it to a long value (or casting it like (long) ) would change all the higher order bits in the long to the signed bit value.

For eg Hex representation of an int, -1684168480 is 9b9da0e0 . If I assign this int to a long, all higher order 32 bits would become F .

int negativeIntValue = -1684168480;
long val1 = negativeIntValue;
long val2 = (long) negativeIntValue;

Hex representation of:

negativeIntValue is 0x9b9da0e0
val1 is 0xffffffff9b9da0e0
val2 is 0xffffffff9b9da0e0

However, if I mask the negativeIntValue with 0x00000000FFFFFFFFL , I get a long which has the same hex representation as negativeIntValue and a positive long value of 2610798816 .

So my questions are:

  • Is my understanding correct?
  • Why does this happen?

Yes, your understanding is correct (at least if I understood your understanding correctly).

The reason this happens is because (most) computers use 2's complement to store signed values. So when assigning a smaller datatype to a larger one, the value is sign extended meaning that the excess part of the datatype is filled with 0 or 1 bits depending on whether the original value was positive or negative.

Also related is the difference between >> and >>> operators in Java. The first one performs sign extending (keeping negative values negative) the second one does not (shifting a negative value makes it positive).

The reason for this is that negative values are stored as two's complement .

Why do we use two's complement?

In a fixed width numbering system what happens, if you substract 1 from 0 ?

0000b - 0001b -> 1111b

and what is the next lesser number to 0 ? It is -1 .

Therfore we thread a binary number with all bits set (for a signed datatype) as -1

The big advantage is that the CPU does not need to do any special operation when changing from positive to negative numbers. It handles 5 - 3 the same as 3 - 5

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM