简体   繁体   English

两个正整数乘以long的结果为负值

[英]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 步是获取ab的值。

Step 2 is to evaluate a * b .第 2 步是评估a * b Since a and b are both int s, this is an int multiplication.因为ab都是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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM