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
但是如果我在long
long 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
大于可能的最大Java
int
值。。。所以乘法运算会悄悄地溢出。。。我们得到的是
-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++的原因之一