我有这样的代码:
int a = 629339;
int b = 4096;
long res = a*b;
结果为-1717194752
但是如果我向长long res = ((long)a)*b;
或long res = (long) a*b;
添加一个手动转换,则结果是正确的2577772544
谁能解释它是如何工作的。
您必须将赋值语句分解为多个部分才能理解在上执行的操作
long res = a*b;
步骤1是得到a
和b
的值。
步骤2是评估a * b
。由于a
和b
都是int
s,所以这是int
的乘法。因此,我们将629339
乘以629339
,即2577772544
。不幸的是,2577772544
大于可能的最大Javaint
值。。。所以乘法运算静默地溢出。。。而我们得到CCD_ 17。
第3步,我们将RHS的值分配给LHS。由于RHS是int
,LHS是float
,JLS说我们执行基元加宽转换。。。其简单地将CCD_ 20变为具有相同值的CCD_。然后将加宽的值分配给CCD_ 22。
为了得到您所期望的答案,我们必须强制使用long
算法进行乘法运算。例如:
long res = ((long) a) * b;
在这种情况下,我们有一个long
乘以int
,这是通过将int
扩展为long
并执行long
乘法来处理的。它不再溢出(因为2577772544
远低于最大的long
值),所以当我们最终将值分配给res
时,它就是您所期望的数字。
a*b
是一个整数,而不是长。
因为它只是一个整数,所以它已经绕过了32位的限制
将此整数重新设置为long不会神奇地恢复数据。
long res = a*b;
除非在末尾(或)强制转换处添加"l",否则a*b
将被视为整数。
根据java教程
int数据类型是一个32位有符号的2的补码整数。它的最小值为-2147483648,最大值为2147483647(含)。对于整数值,这种数据类型通常是默认的选择,除非有理由(如上所述)选择其他类型。