Java 将两个正整数相乘到long的强制转换结果为负值
我有这样的代码:Java 将两个正整数相乘到long的强制转换结果为负值,java,android,jvm,dalvik,Java,Android,Jvm,Dalvik,我有这样的代码: int a = 629339; int b = 4096; long res = a*b; 结果是-1717194752 但是如果我在longlong res=((long)a)*b中添加一个手动强制转换或长分辨率=(长)a*b结果正确2577772544 谁能解释它是如何工作的。a*b是一个整数,而不是长的 因为它只是一个整数,所以它已经绕过了32位限制。 将此整数转换回long将无法神奇地恢复该数据 long res = a*b; a*b将被视为整数,除非在结束(或)强
int a = 629339;
int b = 4096;
long res = a*b;
结果是-1717194752
但是如果我在longlong res=((long)a)*b中添加一个手动强制转换代码>或长分辨率=(长)a*b代码>结果正确2577772544
谁能解释它是如何工作的。a*b
是一个整数,而不是长的
因为它只是一个整数,所以它已经绕过了32位限制。
将此整数转换回long将无法神奇地恢复该数据
long res = a*b;
a*b
将被视为整数,除非在结束(或)强制转换时添加“l”
依照
int数据类型是一个32位带符号2的补码整数。它的最小值为-2147483648,最大值为2147483647(含)。对于整数值,此数据类型通常是默认选择,除非有理由(如上所述)选择其他数据类型
您必须将赋值语句分解为多个部分,以了解其在上的操作:
long res = a*b;
步骤1是获取a
和b
的值
第2步是评估a*b
。由于a
和b
都是int
s,因此这是int
乘法。所以我们用629339
乘以629339
,即2577772544
。
不幸的是,2577772544
大于可能的最大Javaint
值。。。所以乘法运算会悄悄地溢出。。。我们得到的是-1717194752
步骤3:我们将RHS的值分配给LHS。因为RHS是int
,而LHS是float
,JLS说我们执行一个基本的加宽转换。。。它只是将-1717194752
转换为具有相同值的长
。然后将加宽的值指定给res
为了得到您期望的答案,我们必须使用long
算术强制执行乘法。例如:
long res = ((long) a) * b;
在这种情况下,我们将long
与int
相乘,这是通过将int
扩大到long
并执行long
相乘来处理的。这不再溢出(因为2577772544
远低于最大的long
值),因此当我们最终将值分配给res
时,这是您期望的数字。据我所知,java不会自动将类型转换为结果类型?是的,这是正确的。确定结果类型有一些规则。让我看看能否找到你的文件。我在C++中知道所有算术运算的结果都被铸造成结果类型。java不do-doo这个自动化/在爪哇,结果类型的扩展发生在最终的赋值中,并且不影响RHS表达式的评估方式。而且,我的C++是生锈的,但是我相信C++在这方面的行为与java相同。谢谢你提醒我,我已经离开C和C++的原因之一