我只是在弄乱Integer.toBinaryString(int)
方法。
当我传递正数7时,它输出111
但是当我传递负数7时,它输出11111111111111111111111111111001
。我知道Java使用2的补码来表示负数,但为什么是32位(我也知道int是32位长,但不适合答案)?
答案 0 :(得分:3)
好的,所以我做了一些挖掘...
我写了一个可能接近你所做的小程序。
public class IntTest {
public static void main(String[] args){
int a = 7;
int b = -7;
System.out.println(Integer.toBinaryString(a));
System.out.println(Integer.toBinaryString(b));
}
}
我的输出:
111
11111111111111111111111111111001
如果它前面有29“0”,那么111是相同的。那只是浪费空间和时间。
如果我们按照这个人here的两个赞美的说明,你可以看到我们必须做的是翻转位(零变为1,1变为零)然后我们将1加到结果中。
所以0000 0000 0000 0000 0000 0000 0000 0111成为1111 1111 1111 1111 1111 1111 1111 1001
这些不能被抛弃,因为它们在两个赞美表示中是重要的。这就是为什么在第二种情况下你有32位的原因。
希望这有帮助! - 代码!!!
答案 1 :(得分:2)
它输出最小的数字,剥离前导零。在负数的情况下,32位的第一位是符号位(即-1是1,30个零,另一个是1)。因此,由于它必须输出符号位(它很重要),它输出所有32位。
这是使用符号位和无符号移位运算符的一个很酷的半相关示例:)。如果你这样做:
int x = {positive_value};
int y = {other_positive_value};
int avg = (x + y) >>> 1;
x和y整数都可以使用前31位,因为第32位是符号。这样,如果它们溢出,它们会溢出到符号位并使值为负。 >>>是一个无符号移位运算符,它将值向右移一位,实际上是一个除以二和平面操作,这给出了一个适当的平均值。
另一方面,如果你做了:
int x = {value};
int y = {other_value};
int avg = (x + y) / 2;
你得到了溢出,你最终会得到错误的结果,因为你将负值除以2。
答案 2 :(得分:2)
因为Java int是32位签名的。如果使用负数,则第一位必须为1.
System.out.println(Integer.toBinaryString(0));
System.out.println(Integer.toBinaryString(Integer.MAX_VALUE)); // 31 bits
System.out.println(Integer.toBinaryString(Integer.MAX_VALUE - 1)); // 31 bits
System.out.println(Integer.toBinaryString(Integer.MAX_VALUE + 1)); // 32 bits
System.out.println(Integer.SIZE);
输出
0
1111111111111111111111111111111
1111111111111111111111111111110
10000000000000000000000000000000
32
请注意,Integer.MAX_VALUE + 1
为Integer.MIN_VALUE
(并且它有一个额外的位)。