[英]Casting result of multiplication two positive integers to long is negative value
I have code like this:我有这样的代码:
int a = 629339;
int b = 4096;
long res = a*b;
The result is -1717194752
but if I add one manual cast to long long res = ((long)a)*b;
结果是-1717194752
但如果我将一个手动转换添加到 long long res = ((long)a)*b;
or long res = (long) a*b;
或long res = (long) a*b;
the result is correct 2577772544
Who can explain how does it works.结果是正确的2577772544
谁能解释它是如何工作的。
You have to break the assignment statement into its parts to understand what is doing on:您必须将赋值语句分解成多个部分才能了解在做什么:
long res = a*b;
Step 1 is to get the values of a
and b
.第 1 步是获取a
和b
的值。
Step 2 is to evaluate a * b
.第 2 步是评估a * b
。 Since a
and b
are both int
s, this is an int
multiplication.因为a
和b
都是int
s,所以这是一个int
乘法。 So we multiply 629339
by 629339
which would be 2577772544
.所以我们将629339
乘以629339
就是2577772544
。 Unfortunately, 2577772544
is larger than the largest possible Java int
value... so the multiplication operation silently overflows ... and we get -1717194752
instead.不幸的是, 2577772544
大于最大可能的 Java int
值...所以乘法运算会悄无声息地溢出...我们得到-1717194752
。
Step 3 we assign the value of the RHS to the LHS.第 3 步,我们将 RHS 的值分配给 LHS。 Since the RHS is int
and the LHS is float
, the JLS says we perform a primitive widening conversion... which simply turns -1717194752
into a long
with the same value.由于 RHS 是int
而 LHS 是float
,JLS 说我们执行原始扩大转换......它只是将-1717194752
转换为具有相同值的long
。 The widened value is then assigned to res
.然后将加宽的值分配给res
。
To get the answer that you are expecting, we have to force multiplication to be performed using long
arithmetic.为了得到您期望的答案,我们必须强制使用long
算术执行乘法。 For example:例如:
long res = ((long) a) * b;
In this case, we have a multiplication of a long
by an int
, and this is handled by widening the int
to a long
and performing a long
multiply.在这种情况下,我们将一个long
乘以一个int
,这是通过将int
扩展为long
并执行long
乘法来处理的。 This no longer overflows (because 2577772544
is well below the largest long
value), so when we finally assign the value to res
, it is the number that you were expecting.这不再溢出(因为2577772544
远低于最大的long
值),所以当我们最终将值分配给res
时,它就是您期望的数字。
a*b
is an integer, not a long. a*b
是整数,不是长整数。
Because it's only an integer, it has already wrapped around the 32-bit limit.因为它只是一个整数,所以它已经绕过了 32 位限制。
Casting this integer back to long will not magically recover that data.将此整数转换回 long 不会神奇地恢复该数据。
long res = a*b;
a*b
will be treated as integer unless you add 'l' at end (or) cast. a*b
将被视为整数,除非您在结尾(或)强制转换时添加“l”。
As per java tutorial按照java教程
The int data type is a 32-bit signed two's complement integer. int 数据类型是 32 位有符号二进制补码整数。 It has a minimum value of -2,147,483,648 and a maximum value of 2,147,483,647 (inclusive).它的最小值为-2,147,483,648,最大值为2,147,483,647(含)。 For integral values, this data type is generally the default choice unless there is a reason (like the above) to choose something else.对于整数值,此数据类型通常是默认选择,除非有理由(如上述)选择其他类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.