Java 为什么这个程序的输出是-1?
我正在准备AP计算机科学的期末考试,我遇到了这个问题:Java 为什么这个程序的输出是-1?,java,Java,我正在准备AP计算机科学的期末考试,我遇到了这个问题: int sum = 0, p = 1; for (int count = 1; count <= 50; count++) { sum += p; p *= 2; } 输出为-1;但是我不明白为什么会这样。如果有人能给我解释一下,那就太棒了。通过加1,2,4,8,…,你基本上用1来填充sum的二进制表示形式 因为111..1是-1的表示,所以实际上生成了这个数字 这通常被认为是。通过添加1,2,4,8,…,基本上可以
int sum = 0, p = 1;
for (int count = 1; count <= 50; count++)
{
sum += p;
p *= 2;
}
输出为-1;但是我不明白为什么会这样。如果有人能给我解释一下,那就太棒了。通过加1,2,4,8,…,你基本上用1来填充sum的二进制表示形式 因为111..1是-1的表示,所以实际上生成了这个数字
这通常被认为是。通过添加1,2,4,8,…,基本上可以用1填充sum的二进制表示形式 因为111..1是-1的表示,所以实际上生成了这个数字
这通常被认为是对前面答案的补充 java中的整数由表示。因此,很容易看出可以用int表示的最大值是:
1111 1111 1111 1111 1111 1111 1111 1111 (which is 32 1's)
这个值等于:
(1)*2^0 + (1)*2^1 + (1)*2^2 + ... + (1)*2^31 = 2^32 - 1 = 4294967295
但是整数怎么表示负数呢
答案是,上述计算和限制仅适用于使用32位表示的无符号值
负数用对应于最左边位或的表示
如果符号位=1,如110中所示,则数字为负数
反之亦然
此外,由于有符号数字需要留出一位来跟踪符号,因此有符号数字永远无法表示比无符号数字大的数字,因为它们的位较少
知道MSB只是有符号值的符号位,我们如何知道实际数字是多少
答案是使用。根据维基百科的说法,2的补充只是一种确保:
…正数和负数可以自然共存
二的补码可以将符号位为0的正有符号整数X转换为负-X
例如,使用8位:
0110 1001 is the 2^0 + 2^3 + 2^5 + 2^6 = 105
为了得到-105的表示形式,我们使用二的补码,通过以下方式完成:
翻转所有位,因此0->1和1->0
在结果中添加一个
在我们的例子中,-105可以表示为:
翻转所有位,因此0->1和1->0
0110 1001 -> 1001 0110
1111 1111 1111 1111 1111 1111 1111 1111 -> 0000 0000 0000 0000 0000 0000 0000 0000
将一个添加到结果中
1001 0110 + 0000 0001 = 1001 0111
0000 0000 0000 0000 0000 0000 0000 0000 + 0001 = 0001
因此,我们得到10010111作为-105的表示
那么,这一切与这个问题有什么关系呢
程序输出-1的原因是int是一个有符号数变量。正如前面提到的答案,程序将分配给int和的32位填充为1
如果放入print语句,您可以很好地看到这一点,如System.out.printsum+;随着循环的进行,打印出sum的值,您最终看到的是这样的:
1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535, 131071, 262143, 524287, 1048575, 2097151, 4194303, 8388607, 16777215, 33554431, 67108863, 134217727, 268435455, 536870911, 1073741823, 2147483647, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
以二进制形式表示的是:
1, 11, 111, 1111, 1 1111, ....
如果您添加一个if语句来捕获sum变为-1时count的值,您会发现当count=32时它会变为-1。这很有意义,因为一旦程序在MSB或符号位中填充了1,32位数字就会被视为负数
现在使用二的补码,我们可以通过利用这样一个事实,找到负数到底是什么,你不仅可以得到一个数的负表示,而且如果给你一个负数,你也可以得到正表示。因此,我们:
翻转所有位,因此0->1和1->0
0110 1001 -> 1001 0110
1111 1111 1111 1111 1111 1111 1111 1111 -> 0000 0000 0000 0000 0000 0000 0000 0000
将一个添加到结果中
1001 0110 + 0000 0001 = 1001 0111
0000 0000 0000 0000 0000 0000 0000 0000 + 0001 = 0001
它代表数字1。因此,我们发现1111111111111111111111111111111111111111是-1的表示。补充前面的答案 java中的整数由表示。因此,很容易看出可以用int表示的最大值是:
1111 1111 1111 1111 1111 1111 1111 1111 (which is 32 1's)
这个值等于:
(1)*2^0 + (1)*2^1 + (1)*2^2 + ... + (1)*2^31 = 2^32 - 1 = 4294967295
但是整数怎么表示负数呢
答案是,上述计算和限制仅适用于使用32位表示的无符号值
负数用对应于最左边位或的表示
如果符号位=1,如110中所示,则数字为负数
反之亦然
此外,由于有符号数字需要留出一位来跟踪符号,因此有符号数字永远无法表示比无符号数字大的数字,因为它们的位较少
知道MSB只是有符号值的符号位,我们如何知道实际数字是多少
答案是使用。根据维基百科的说法,2的补充只是一种确保:
…正数和负数可以自然共存
二的补码可以将符号位为0的正有符号整数X转换为负-X
例如,使用8位:
0110 1001 is the 2^0 + 2^3 + 2^5 + 2^6 = 105
为了得到-105的表示形式,我们使用二的补码,通过以下方式完成:
翻转所有位,因此0->1和1->0
在结果中添加一个
在我们的例子中,-105可以表示为:
翻转所有位,因此0->1和1->0
0110 1001 -> 1001 0110
1111 1111 1111 1111 1111 1111 1111 1111 -> 0000 0000 0000 0000 0000 0000 0000 0000
将一个添加到结果中
1001 0110 + 0000 0001 = 1001 0111
0000 0000 0000 0000 0000 0000 0000 0000 + 0001 = 0001
因此我们得到1001011
1作为-105的代表
那么,这一切与这个问题有什么关系呢
程序输出-1的原因是int是一个有符号数变量。正如前面提到的答案,程序将分配给int和的32位填充为1
如果放入print语句,您可以很好地看到这一点,如System.out.printsum+;随着循环的进行,打印出sum的值,您最终看到的是这样的:
1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535, 131071, 262143, 524287, 1048575, 2097151, 4194303, 8388607, 16777215, 33554431, 67108863, 134217727, 268435455, 536870911, 1073741823, 2147483647, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
以二进制形式表示的是:
1, 11, 111, 1111, 1 1111, ....
如果您添加一个if语句来捕获sum变为-1时count的值,您会发现当count=32时它会变为-1。这很有意义,因为一旦程序在MSB或符号位中填充了1,32位数字就会被视为负数
现在使用二的补码,我们可以通过利用这样一个事实,找到负数到底是什么,你不仅可以得到一个数的负表示,而且如果给你一个负数,你也可以得到正表示。因此,我们:
翻转所有位,因此0->1和1->0
0110 1001 -> 1001 0110
1111 1111 1111 1111 1111 1111 1111 1111 -> 0000 0000 0000 0000 0000 0000 0000 0000
将一个添加到结果中
1001 0110 + 0000 0001 = 1001 0111
0000 0000 0000 0000 0000 0000 0000 0000 + 0001 = 0001
它代表数字1。因此,我们发现1111111111111111111111111111111111111111是-1的表示