Java 为什么最大整数乘法的结果是1
我想不需要太多解释,为什么下面的计算结果为1Java 为什么最大整数乘法的结果是1,java,int,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 整数2147483647的二进制表示如下: 01111111 11111111 11111111
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
整数2147483647的二进制表示如下:
01111111 11111111 11111111 11111111
将其与自身相乘,得到数字4611686014132420609,其二进制表示为:
00111111 11111111 11111111 11111111 00000000 00000000 00000000 00000001
这对于只有32位的int
类型来说太大了。a*b
的乘法仅作为整数乘法进行,而不考虑将结果赋给的变量类型(这可能会进行加宽转换,但仅在乘法之后)
因此,结果只是切断了所有不适合32位的位,只留下以下结果:
00000000 00000000 00000000 00000001
这就是值1
如果要保留信息,必须与具有64位的long
类型相乘:
long a = 2147483647;
long b = 2147483647;
long mult = a * b;
System.out.println((int) mult); // 1
System.out.println(mult); // 4611686014132420609
System.out.println((double) mult); // 4.6116860141324206E18
如果你需要更多的比特来进行计算,你可以考虑(整数)或(对于十进制数)。< /P> < P>整数2147483647的二进制表示如下:
01111111 11111111 11111111 11111111
将其与自身相乘,得到数字4611686014132420609,其二进制表示为:
00111111 11111111 11111111 11111111 00000000 00000000 00000000 00000001
这对于只有32位的int
类型来说太大了。a*b
的乘法仅作为整数乘法进行,而不考虑将结果赋给的变量类型(这可能会进行加宽转换,但仅在乘法之后)
因此,结果只是切断了所有不适合32位的位,只留下以下结果:
00000000 00000000 00000000 00000001
这就是值1
如果要保留信息,必须与具有64位的long
类型相乘:
long a = 2147483647;
long b = 2147483647;
long mult = a * b;
System.out.println((int) mult); // 1
System.out.println(mult); // 4611686014132420609
System.out.println((double) mult); // 4.6116860141324206E18
如果你需要更多的比特来计算,你可以考虑(整数)或(对于数字数)。
<2147483647×2147483647=461168601413242060</p>其中以六边形表示=3FFFFFF0000000 1, 截断后只剩下0000000 1,表示1。2147483647*2147483647=4611686014132420609
其中以六边形表示=3FFFFFF0000000 1, 截断后只剩下0000000 1,表示1。首先,三次尝试都给出相同答案的原因是它们都在执行32位乘法和乘法溢出,导致“信息丢失”。信息溢出/丢失发生在RHS1表达式的值分配给LHS上的变量之前 在第二种和第三种情况下,可以使用64位或浮点计算表达式:
int c = a * b;
long d = ((long) a) * b;
double e = ((double) a) * b;
这样你就不会得到溢出
至于为什么在32位的情况下会出现溢出,这很简单。结果大于32位。其他答案解释了为什么答案是1
只是为了好玩,这里有一个非正式的证明
假设我们讨论的是一个模数系统,其数字范围为2N-1到2N-1-1。在这样的数字系统中,X*2N映射到零。。。对于所有整数X
如果我们把最大值乘以它本身,我们得到
(2N-1-1)*(2N-1-1)
->22N-2-2*2N-1+1
->22N-2-2N+1
现在将其映射到原始范围:
22N-2映射到0
2N映射0
1映射到1
0+0+0->1
1-LHS==左侧,RHS==右侧。首先,三次尝试都给出相同答案的原因是它们都在执行32位乘法和乘法溢出,导致“信息丢失”。信息溢出/丢失发生在RHS1表达式的值分配给LHS上的变量之前 在第二种和第三种情况下,可以使用64位或浮点计算表达式:
int c = a * b;
long d = ((long) a) * b;
double e = ((double) a) * b;
这样你就不会得到溢出
至于为什么在32位的情况下会出现溢出,这很简单。结果大于32位。其他答案解释了为什么答案是1
只是为了好玩,这里有一个非正式的证明
假设我们讨论的是一个模数系统,其数字范围为2N-1到2N-1-1。在这样的数字系统中,X*2N映射到零。。。对于所有整数X
如果我们把最大值乘以它本身,我们得到
(2N-1-1)*(2N-1-1)
->22N-2-2*2N-1+1
->22N-2-2N+1
现在将其映射到原始范围:
22N-2映射到0
2N映射0
1映射到1
0+0+0->1
1-LHS==左手边,RHS==右手边。因为:
2147483647*2147483647=4611686014132420609 整数容量=4294967295
4611686014132420609%4294967295=1因为:
2147483647*2147483647=4611686014132420609 整数容量=4294967295
4611686014132420609%4294967295=1您看到的只是整数溢出的结果,它遵循以下规则:
Integer.MAX_VALUE + 1 = Integer.MIN_VALUE
了解发生了什么的一种方法是设计Java的int
类型,范围从-7
到7
,同样的规则仍然适用。让我们看看当我们乘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
您看到的只是整数溢出的结果,它遵循以下规则:
Integer.MAX_VALUE + 1 = Integer.MIN_VALUE
了解发生了什么的一种方法是设计Java的int
类型,范围从-7
到7
,同样的规则仍然适用。让我们看看当我们乘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
整数只有3字节的内存分配,而double只有8字节的内存分配。你的乘法运算比它的给定值大得多