public class Test {
public static void main(String [] s) {
int x = 99999;
long y = 99999;
long res = x * x;
System.out.println("x^2 = " + res);
res = y * y;
System.out.println("y^2 = " + res);
}
}
Output:
x^2 = 1409865409
y^2 = 9999800001
我真的很困惑,看到上面代码段的输出。我希望得到相同(正确)的答案,但这里x ^ 2实际上是错误的!
答案 0 :(得分:8)
99999 * 99999
= 1001010100000010001101011011000001
(如果算上这些,你会发现你需要34位代表这个数字在内存中)。
int 32位长,因此会删除两个 MSB 。
结果为您提供01010100000010001101011011000001b
= 1409865409
小数。
将此值分配给64位长不会改变结果,两个整数的乘法会得到整数作为结果。
答案 1 :(得分:3)
这是因为你乘以integers
x * x
,其结果将是integer
(临时变量,我们在这里谈论x * x
操作的结果,而不是{ {1}}部分)。由于结果会比res =
大一些,你会得到一些“奇怪”的数字。然后将该数字放在Integer.MAX_VALUE
类型的变量中。
这是您解决此问题的方法:
long
现在,它会计算long res = 1l * x * x;
,因为第一个数字是1l * x
,它会将其计算为long
,然后乘以long
,再次,数字为x
,结果为long
,然后此结果将放在变量long
中。
以类似的方式修复丢失小数的问题,例如:
res
结果为int a = 10;
int b = 3;
double d = a / b;
。但是,如果你这样做:
3.0
两者都是double d = (1d *a) / b;
d = a / (b * 1d);
d = (double) a / d;
(此3.3333333333333335
,这就是另一个问题......)。
另外,其中一个变量的加倍也是有效的(感谢@Aconcagua)。
答案 2 :(得分:3)
因为在x * x
空格中完成了int
,所以只有结果才会被放入long
。因此,即使long
变量足够大以容纳结果,在将结果放入long
之前,它首先计算为int
产品,结果会被截断,因为它不会适合int