首先,抱歉我的英语不好......
今天我试图检查Integer.MAX_VALUE * Integer.MAX_VALUE
System.out.println("long*long= "+Long.MAX_VALUE*Long.MAX_VALUE);
System.out.println("int*int= "+Integer.MAX_VALUE*Integer.MAX_VALUE);
System.out.println("double*double= "+Double.MAX_VALUE*Double.MAX_VALUE);
System.out.println("float*float= "+Float.MAX_VALUE*Float.MAX_VALUE);
System.out.println("short*short= "+Short.MAX_VALUE*Short.MAX_VALUE);
结果:
long * long = 1
int * int = 1
double * double = Infinity
float * float = Infinity
短*短= 1073676289
为什么?如果浮动^ 2 =无穷大,那么长^ 2也应该是无限......而且1显然是一个错误... 有谁有任何想法? tnx
答案 0 :(得分:3)
http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.17.1说
如果整数乘法溢出,则结果为 一些数学产品的低阶位 足够大的二补码格式。
你的整数答案太大而不适合结果类型,所以真正的答案的高位被简单地丢弃。
(2 ^ n-1)*(2 ^ n -1)是2 ^ 2n - 2 * 2 ^ n + 1,这是1 modulo 2 ^ n - 所以你得到了预期的答案。
浮点类型的规则是不同的。
答案 1 :(得分:2)
长^ 2也应该是无限
只有浮点类型具有无穷大的特殊值。整数类型不;这包括long
。
Long.MAX_VALUE * Long.MAX_VALUE
评估为1
归因于integer overflow,因为((2**63 -1) ** 2) mod (2**64) == 1
(Wolfram Alpha)。
答案 2 :(得分:2)
要了解整数如何相乘,请使用二进制表示法。为简单起见,我使用4位有符号整数(MAX为7),但是byte,short,int和long的原理相同。
0111 x 0111
----
0111
0111
0111
-------
110001
The columns from right to left:
1) 1 => 1
2) 1+1 => 10 => 0 and carry 1c into 3)
3) 1+1+1+1c => 100 => 0 and carry 1c into 5) (sic! 5)
4) 1+1 => 10 => 0 and carry 1c into 5)
5) 1+1c+1c => 11
高阶位是无关紧要的,因为被截断了。
这甚至不是Java的特性 - 它是二进制补码算术模数^(位数)的结果。
答案 3 :(得分:0)
因为2 ^ 63 -1 * 2 ^ 63 -1不是无限的,你需要一个可以存储这个等式的答案的变量。默认调用无法打印它但它有答案。这反映在true(1)
上