减去长整型出错

7
long freeSize = ((Main.maxSPace-Main.usedSpace)*1000*1000);

maxSpace = 20000
usedSpace = 8

--> freeSize = -1482836480

为什么结果是负数?

这个负数结果是由于计算机使用二进制补码表示有符号整数。在这种表示方式中,最高位(即符号位)被用来表示正负性,1代表负数,0代表正数。因此,当一个整数的最高位是1时,它就会被解释为负数。


2
maxSpace和usedSpace的值是什么? - Justin
1
你是在算术运算后声明maxSpace和usedSpace,还是只是告诉我们它们的值?你需要发布更多的代码。 - Jonny Henly
变量maxSpace和usedSpace是什么类型? - Sava Vranešević
您可能正在遇到长整型溢出。 让我们看一下:20000 - 8 = 19992``19992 * 1000000 = 19992000000 哎呀,没关系,这比 Long.MAX_VALUE 小。 - Justin
你确定 maxSpaceusedSpace 是以兆字节为单位(即1024字节,而不是1000字节),而不是以字节为单位吗? - Dai
4个回答

6

maxSpaceusedSpace的类型从int更改为long。 如果您无法执行此操作,则只需将代码更改为以下内容

long freeSize = 1000L*1000*(Main.maxSPace - Main.usedSpace);

所以结果将会被计算为long,而不是int

现在它是这样计算的

Main.maxSPace-Main.usedSpace              -> 19992
(Main.maxSPace-Main.usedSpace)*1000       -> 19992000
(Main.maxSPace-Main.usedSpace)*1000*1000L -> 19992000000

这里的问题是我们正在操作整数,所以结果也必须是整数,但整数的最大值为

2147483647 so
19992000000 is out of range

所以Java只会取结果的最后32位并将其转换为整数。
10010100111100111011011011000000000 -> 19992000000
   10100111100111011011011000000000 -> -1482836480

3

maxSpaceusedSpace 被声明为整数,因此所有的算术运算都是使用整数进行的。只有在将结果赋值给 freeSize 时才将其转换为长整型,但溢出已经发生了。

尝试用 1000L 替换数字 1000,以使强制转换提前发生:

long freeSize = ((Main.maxSPace-Main.usedSpace)*1000L*1000L);

3
你可能会得到一个负数是因为 maxSpaceusedSpace 是整型。 20000 - 8 = 1999219992 * 1000000 = 19992000000 小于 Long.MAX_VALUE(263 - 1),但大于 Integer.MAX_VALUE(231 - 1)。19992000000 - Integer.MAX_VALUE = 17844516353,仍然超出整型的范围。你应该让 maxSpaceusedSpace 成为长整型。

2
当maxSpace和usedSpace的类型为int时,由于类型溢出会得到一个负值。将变量maxSpace和usedSpace都改为long类型即可。或者,如果您无法更改Main的属性类型,可以将代码更改为:
long freeSize = ((Main.maxSPace-Main.usedSpace)*1000L*1000L);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接