将两个正整数乘以长的铸造结果为负值

时间:2012-10-12 15:03:09

标签: java android jvm dalvik

我有这样的代码:

int a = 629339;
int b = 4096;
long res = a*b;

结果是-1717194752 但如果我向长long res = ((long)a)*b;long res = (long) a*b;添加一个手动广播,结果是正确的2577772544 谁能解释它是如何运作的。

3 个答案:

答案 0 :(得分:6)

a*b是一个整数,而不是长整数。

因为它只是一个整数,所以它已经包含了32位的限制 将此整数强制转换为long将不会神奇地恢复该数据。

答案 1 :(得分:5)

您必须将赋值语句分解为其部分,以了解正在执行的操作:

long res = a*b;

第1步是获取ab的值。

第2步是评估a * b。由于ab都是int s,因此这是一个int乘法。因此,我们将629339乘以629339 2577772544。 不幸的是,2577772544大于最大可能的Java int值...因此乘法操作静默溢出 ...而我们得到-1717194752。< / p>

步骤3我们将RHS的值分配给LHS。由于RHS为int且LHS为float,因此JLS表示我们执行原始扩展转换...只需将-1717194752转换为long 1}}具有相同的值。然后将加宽的值分配给res


要获得您期望的答案,我们必须使用long算法强制执行乘法。例如:

long res = ((long) a) * b;

在这种情况下,我们将longint相乘,并通过将int扩展为long并执行{{}来处理此问题。 1}}乘以。这不再溢出(因为long远低于最大2577772544值),所以当我们最终将值分配给long时,它就是您期望的数字。

答案 2 :(得分:4)

long res = a*b;

a*b将被视为整数,除非您在结束(或)演员表中添加“l”。

根据java tutorial

  

int数据类型是32位带符号的二进制补码整数。它的最小值为-2,147,483,648,最大值为2,147,483,647(含)。对于整数值,除非有理由(如上所述)选择其他内容,否则此数据类型通常是默认选择。