如何将有符号整数转换为无符号长整数

时间:2016-03-29 06:48:30

标签: java

我似乎无法从根本上理解如何将signed int转换为unsigned long works。

以下代码中究竟发生了什么? 在什么情况下你想将int转换为unsigned long? 为什么不将带符号的long(而不是Int)转换为unsigned long?

public static long getUnsignedInt(int x) {
    return x & 0x00000000ffffffffL;
}

Best way to convert a signed integer to an unsigned long?

什么是0x00000000ffffffffL?

2 个答案:

答案 0 :(得分:2)

int不能代表高于2 ^ 31-1的值,因为int的最高位是符号位。如果你想将负int视为符号位是常规位(即将其视为无符号整数),那么你也可以表示2 ^ 31到2 ^ 31-1之间的数字,但是这些数字不能存储在int中。

这是getUnsignedInt发挥作用的地方。通过使用ffffffff(相当于32 0位,后跟32 1位)执行按位AND,如果原始int x为负,则此方法的值为将是具有与原始否定x相同的位表示的无符号数(不包括额外的32 0位)。

例如,

int

1000...0000 (1 followed by 31 0s)

是-2 ^ 31的2的补码表示。

当您将该号码传递给getUnsignedInt时,您会获得long

000...0001000...0000 (32 0s followed by 1 followed by 31 0s)

是2 ^ 31的二进制表示,不能表示为int

  

为什么不将带符号的long(而不是Int)转换为unsigned long

这是不可能的,因为Java没有unsigned long类型。任何最高位为1的长都是负数。

答案 1 :(得分:2)

int的范围从-2 31 到2 31 -1,而数据类型本身需要32个字节。最高位(位32)用作符号位。

现在,如果您可以将此位用作绝对值的一部分'数量,范围将从0到2 32 。这将使int无符号,但Java数据类型已签名。因此,这是不可能的,除非您将移动到可以容纳32位的数据类型,而不会影响符号位。

2 32 = 1111 1111 1111 1111 1111 1111 1111 1111

现在,将它移动到下一个更大的数据类型long,它可以容纳64位,63位表示绝对值,最高位表示符号位。完全相同的数字看起来像这样。

2 32 = 0000 0000 0000 0000 0000 0000 0000 0000 1111 1111 1111 1111 1111 1111 1111 1111

0xffffffffL = 0000 0000 0000 0000 0000 0000 0000 0000 1111 1111 1111 1111 1111 1111 1111 1111

现在,查看int值(尝试此Integer.toBinaryString(-2);)。比如,你有一些int喜欢-2。在二进制中,它表示为

                                        1111 1111 1111 1111 1111 1111 1111 1110

"和"这与0xffffffffL [最后的L表示它是long] [f十六进制是二进制的1111; 8 f,所以8 1111 s](试试这个Long.toBinaryString(0xffffffffL);

0000 0000 0000 0000 0000 0000 0000 0000 1111 1111 1111 1111 1111 1111 1111 1111 

你得到了,

0000 0000 0000 0000 0000 0000 0000 0000 1111 1111 1111 1111 1111 1111 1111 1110

碰巧是4294967294 = 2 32 - 2.正如预期的那样。 :)