Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/google-maps/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么最大整数乘法的结果是1_Java_Int - Fatal编程技术网

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

Java 为什么最大整数乘法的结果是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

我想不需要太多解释,为什么下面的计算结果为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 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字节的内存分配。你的乘法运算比它的给定值大得多