简体   繁体   English

为什么“ x * y / z”会导致错误的负值?

[英]Why does “x*y/z” result in an incorrect negative value?

System.out.println(1000*16777216/4890);

OUTPUT: -82342 输出: -82342

...but should be: 3430923 ...但应该是: 3430923

How can I fix this? 我怎样才能解决这个问题?

Just add an L to either 1000 or 16777216 (or both)...and that will do the trick. 只需在L100016777216 (或两者)之间加上L即可解决问题。

The reason, like Rod_Algonquin stated, it's a positive overflow of the integer value , and it's happening when you multiply 1000 by 16777216 ; 就像Rod_Algonquin所说的那样,这是整数值正溢出 ,并且发生在您将1000乘以16777216 that eventually will be greater than (the max allowed) Integer.MAX_VALUE , so it wraps up and starts from Integer.MIN_VALUE (in your case the value would be -402653184 ; divide it by 4890 and you will get the unexpected result -82342 ). 最终将大于(允许的最大值) Integer.MAX_VALUE ,因此它从Integer.MIN_VALUE开始包装(在您的情况下,该值为-402653184 ;将其除以4890 ,您将得到意外的结果-82342 ) 。

Have a look (notice the yellow highlighted section; IDEA will warn you with Numeric overflow in expression ): 看一眼(注意黄色突出显示的部分; IDEA会警告您表达式中的数字溢出 ):

在此处输入图片说明

As pointed out by @Rod_Algonquin , 1000*16777216 exceeds the range of int ( int takes value between -2 31 to 2 31 - 1 ), so it causes overflow. 正如指出的@Rod_Algonquin1000*16777216超出范围intint需要-2 31之间的值,以二月31日至1 ),所以它会导致溢出。

In order to prevent overflow from happening, you can perform the computation using long by adding the letter L after the number literals like the following: 为了防止发生溢出,可以通过在数字文字之后添加字母L来使用long进行计算,如下所示:

1000L * 16777216 / 4890

By default, 1000 is an int literal in Java, whereas 1000L is a long literal. 默认情况下, 1000是Java中的int文字,而1000Llong文字。

First of all note it's integer arithmetic.Whatever the inbetween calculation would be there stored as integer. 首先要注意的是整数运算,无论中间计算如何,都将存储为整数。 1000*16777216 will give 16777216000 which is out of the range of integer. 1000*16777216将给出16777216000 ,该值超出整数范围。 So now system tries to manage this integer over flow during runtime.As 16777216000 > Integer.MAX_VALUE and now it moves for the negative ranged values to handle the overflow.. 因此,现在系统尝试在运行时期间管理此整数溢出16777216000 > Integer.MAX_VALUE现在移动为负范围值以处理溢出。

Try like this Integer.MAX_VALUE + 1 will give you -2147483648 .Better way to manage this is to use long primitive or you can use double for floating point value. 像这样尝试Integer.MAX_VALUE + 1将为您提供-2147483648更好的方法是使用long原语,也可以将double用于浮点值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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