之前曾问过这个问题。我不同意答案。为什么师这样工作?请看长线aslong = n /(a * b)
FYI。几年前一个类似的问题。 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
答案 0 :(得分:1)
Java语言规范说明如下。
15.7.3."评估尊重括号和优先顺序":
Java编程语言遵循括号明确指示的评估顺序,并隐含运算符优先级。
15.7.2."在操作前评估操作数":
Java编程语言保证运算符的每个操作数(条件运算符除外
&&
,||
和? :
)在执行任何部分操作之前进行全面评估。
这意味着(a*b)
在n/(a*b)
中的分区运算符之前进行了评估,因为a
和b
都是{{1}变量,乘法以int
完成。结果然后经历了一个" Widening Primitive Conversion"到int
进行分工。
由于我引用了JLS,让我引用这个(特别感谢David Wallace注意):
3.10.1." Integer Literals":
如果整数文字的后缀为ASCII字母
long
或long
(ell),则其类型为L
;否则它是l
(§4.2.1)类型。后缀
int
是首选 ,因为字母L
(ell)通常难以与数字{区分开来} {1}}(一)。