长过int除法
Long over int division
之前有人问过这个问题。我不同意这个答案。为什么除法会这样?请看 long aslong=n/(a*b)
这一行
仅供参考。几年前的类似问题。
Unexpected result in long/int division
long n=8589934592l; // =2^33
int nasint=(int)n; // it can't fit into int so it's zero.
int a=2097152; int b=1024;
int asint=(int) n/(a*b); // n is cast into zero. so answer is zero.
long aslong=n/(a*b); // don't the int get cast into long?
long aslong2=n/((long)a*(long)b); // as expected
System.out.println("long n=" + n + " as int=" + nasint); // long n=8589934592 as int=0
System.out.println("asint=" + asint); // asint=0
System.out.println("aslong=" + aslong); // aslong=-4
System.out.println("aslong2=" + aslong2); // aslong2=4
Java 语言规范说明如下。
15.7.3.“计算尊重括号和优先级”:
The Java programming language respects the order of evaluation indicated explicitly by parentheses and implicitly by operator precedence.
15.7.2.“在操作前评估操作数”:
The Java programming language guarantees that every operand of an operator (except the conditional operators &&
, ||
, and ? :
) appears to be fully evaluated before any part of the operation itself is performed.
这意味着 (a*b)
在 n/(a*b)
中的除法运算符 之前计算 ,因为 a
和 b
是 int
个变量,乘法是 int
。然后将结果进行“Widening Primitive Conversion”到long
的除法。
既然我引用了 JLS,那我也引用一下这个吧(特别感谢 David Wallace 的关注):
3.10.1.“整数文字”:
An integer literal is of type long
if it is suffixed with an ASCII letter L
or l
(ell); otherwise it is of type int
(§4.2.1).
The suffix L
is preferred, because the letter l
(ell) is often hard to distinguish from the digit 1
(one).
之前有人问过这个问题。我不同意这个答案。为什么除法会这样?请看 long aslong=n/(a*b)
这一行仅供参考。几年前的类似问题。 Unexpected result in long/int division
long n=8589934592l; // =2^33
int nasint=(int)n; // it can't fit into int so it's zero.
int a=2097152; int b=1024;
int asint=(int) n/(a*b); // n is cast into zero. so answer is zero.
long aslong=n/(a*b); // don't the int get cast into long?
long aslong2=n/((long)a*(long)b); // as expected
System.out.println("long n=" + n + " as int=" + nasint); // long n=8589934592 as int=0
System.out.println("asint=" + asint); // asint=0
System.out.println("aslong=" + aslong); // aslong=-4
System.out.println("aslong2=" + aslong2); // aslong2=4
Java 语言规范说明如下。
15.7.3.“计算尊重括号和优先级”:
The Java programming language respects the order of evaluation indicated explicitly by parentheses and implicitly by operator precedence.
15.7.2.“在操作前评估操作数”:
The Java programming language guarantees that every operand of an operator (except the conditional operators
&&
,||
, and? :
) appears to be fully evaluated before any part of the operation itself is performed.
这意味着 (a*b)
在 n/(a*b)
中的除法运算符 之前计算 ,因为 a
和 b
是 int
个变量,乘法是 int
。然后将结果进行“Widening Primitive Conversion”到long
的除法。
既然我引用了 JLS,那我也引用一下这个吧(特别感谢 David Wallace 的关注):
3.10.1.“整数文字”:
An integer literal is of type
long
if it is suffixed with an ASCII letterL
orl
(ell); otherwise it is of typeint
(§4.2.1).The suffix
L
is preferred, because the letterl
(ell) is often hard to distinguish from the digit1
(one).