Java 如何将有符号整数转换为无符号长整数
我似乎无法从根本上理解如何将有符号int转换为无符号long 下面的代码中到底发生了什么? 在什么情况下,您希望将int转换为无符号long? 为什么不将带符号的long(而不是Int)转换为无符号的longJava 如何将有符号整数转换为无符号长整数,java,Java,我似乎无法从根本上理解如何将有符号int转换为无符号long 下面的代码中到底发生了什么? 在什么情况下,您希望将int转换为无符号long? 为什么不将带符号的long(而不是Int)转换为无符号的long public static long getUnsignedInt(int x) { return x & 0x00000000ffffffffL; } 什么是0x00000000ffffffffffl?一个int不能表示大于2^31-1的值,因为int的最高位是符号位
public static long getUnsignedInt(int x) {
return x & 0x00000000ffffffffL;
}
什么是0x00000000ffffffffffl?一个
int
不能表示大于2^31-1的值,因为int
的最高位是符号位。如果要将负的int
视为符号位是常规位(即,将其视为无符号int),则也可以表示介于2^31到2^31-1之间的数字,但此类数字不能存储在int
中
这就是getUnsignedInt
发挥作用的地方。通过对FFFFFFFF L(相当于320
位后接321
位)执行逐位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)转换为无符号的long
这是不可能的,因为Java没有无符号long类型。任何最高位为1的long都是负数。一个
int
不能表示高于2^31-1的值,因为int
的最高位是符号位。如果要将负数int
视为符号位,则(即,将其视为无符号整数),您也可以表示2^31到2^31-1之间的数字,但此类数字不能存储在int
中
这就是getUnsignedInt
发挥作用的地方。通过使用ffffffffffl执行按位AND(相当于320
位后跟321
位),如果原始int
x
为负数,则此方法的值将是具有与原始负数x
相同位表示形式的无符号数(不计算额外的320
位)
比如说,
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)转换为无符号的long
这是不可能的,因为Java没有无符号长类型。任何最高位为1的长类型都是负的。一个
int
的范围是-231到231-1,而数据类型本身需要32个字节。最高有效位位32用作符号位
现在,如果您可以使用此位作为数字“绝对值”的一部分,范围将从0到232。这将使int
无符号,但Java数据类型是有符号的。因此,这是不可能的,除非您移动到一个可以保存32位而不影响符号位的数据类型
232=1111111111111111111111111111111111111111111111
现在,将其移动到下一个更大的数据类型long,它可以容纳64位,63位表示绝对值,最高有效位表示符号位
232=0000 0000 0000 0000 0000 0000 1111111111111111111111111111111111111111111111111111111111
0xffffffffL=0000 0000 0000 0000 0000 0000 1111111111111111111111111111111111111111111111111111111111
现在,看看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(0xFFFFFFFFFFL);
)
你得到
0000 0000 0000 0000 0000 0000 0000 0000 1111 1111 1111 1111 1111 1111 1111 1110
它恰好是4294967294=232-2。正如预期的那样。:一个
int
的范围是-231到231-1,而数据类型本身需要32个字节。最高有效位32用作符号位
现在,如果您可以使用此位作为数字“绝对值”的一部分,范围将从0到232。这将使int
无符号,但Java数据类型是有符号的。因此,这是不可能的,除非您移动到一个可以保存32位而不影响符号位的数据类型
232=1111111111111111111111111111111111111111111111
现在,将其移动到下一个更大的数据类型long,它可以容纳64位,63位表示绝对值,最高有效位表示符号位
232=0000 0000 0000 0000 0000 0000 1111111111111111111111111111111111111111111111111111111111
0xffffffffL=0000 0000 0000 0000 0000 0000 1111111111111111111111111111111111111111111111111111111111
现在,看看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(0xFFFFFFFFFFL);
)
你得到
0000 0000 0000 0000 0000 0000 0000 0000 1111 1111 1111 1111 1111 1111 1111 1110
正好是4294967294=232-2。正如预期的那样。:)不应该(2^32)