为什么最大整数乘法结果为1

时间:2016-09-24 07:22:12

标签: java int

我认为不需要多解释,为什么以下计算结果为1?

int a = 2147483647;
int b = 2147483647;

int c = a * b;
long d = a * b;
double e = a * b;

System.out.println(c);  //1
System.out.println(d);  //1
System.out.println(e);  //1.0

6 个答案:

答案 0 :(得分:11)

整数2147483647的二进制表示如下:

componentWillMount() {
    this.setState({loading: true});
    ajaxCall().then(responses => {
      // process response
      this.setState({loading: false});
    });
  }

将其与自身相乘会产生数字4611686014132420609,其二进制表示形式为:

01111111 11111111 11111111 11111111

这对于只有32位的00111111 11111111 11111111 11111111 00000000 00000000 00000000 00000001 类型来说太大了。 int的乘法仅作为整数乘法完成,而不管分配结果的变量类型(可能会进行扩展转换,但仅在乘法后)。

因此,结果只是切断了不适合32位的所有位,只留下以下结果:

a * b

这只是值1。

如果要保留信息,则必须使用64位的00000000 00000000 00000000 00000001 类型进行乘法运算:

long

如果您需要更多位进行计算,可以考虑BigInteger(对于整数)或BigDecimal(对于十进制数)。

答案 1 :(得分:5)

2147483647 * 2147483647 = 4611686014132420609

在Hexa = 3FFFFFFF 00000001中,截断后只剩下00000001,代表1。

答案 2 :(得分:4)

首先,三次尝试都给出相同答案的原因是它们都在执行32位乘法并且乘法溢出,导致“信息丢失”。在将RHS 1 表达式的值分配给LHS上的变量之前,发生信息溢出/丢失。

在第二种和第三种情况下,您可以使用64位或浮点来计算表达式:

int c = a * b;
long d = ((long) a) * b;
double e = ((double) a) * b;

你不会溢出。

至于为何在32位情况下出现溢出,这很简单。结果大于32位。其他答案解释了为什么答案是1

只是为了好玩,这是一个非正式的证明。

假设我们正在谈论一个模数系统,其数字范围为2 N-1 至2 N-1 - 1.在这样的数字系统中,对于所有整数X,X * 2 N 映射到零...

如果我们自己乘以最大值,我们得到

  

(2 N-1 - 1)*(2 N-1 - 1)

     

- > 2 2N-2 - 2 * 2 N-1 + 1

     

- > 2 2N-2 - 2 N + 1

现在将其映射到原始范围:

  

2 2N-2 映射到0

     

2 N 映射0

     

1映射到1

     

0 + 0 + 0 - > 1

1 - LHS ==左手边,RHS ==右手边。

答案 3 :(得分:1)

您所看到的只是整数溢出的结果,遵循以下规则:

Integer.MAX_VALUE + 1 = Integer.MIN_VALUE

查看正在发生的事情的一种方法是将Java的int类型设置为-77,同样的规则仍在应用。让我们看看当我们乘以7*7时会发生什么:

 7 + 7 = 14 -> -2   (7 x 2)
-2 + 7 = 5          (7 x 3)
 5 + 7 = 12 -> -4   (7 x 4)
-4 + 7 = 3          (7 x 5)
 3 + 7 = 10 -> -6   (7 x 6)
-6 + 7 = 1          (7 x 7, one is leftover)

您的代码中也会发生同样的事情,2147483647根据以下内容溢出:

2147483647 + 1 = -2147483648

答案 4 :(得分:0)

<强>因为:

2147483647 * 2147483647 = 4611686014132420609

  

整数容量= 4294967295

4611686014132420609%4294967295 = 1

答案 5 :(得分:-2)

整数只有3字节的内存分配以及双倍的8字节内存分配你的乘法是如此之大,只有它的启动它有(0000 0001)2 = 1