在这个特定的情况下,真的被java数据类型搞糊涂了

时间:2016-05-11 08:03:11

标签: java long-integer

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实际上是错误的!

3 个答案:

答案 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