简体   繁体   English

为什么这会导致长整数溢出

[英]why this would result in long integer overflow

I checked the document that long = int64 has range more than 900,000,000,000,000 我检查了文件long = int64范围超过900,000,000,000,000

Here is my code: 这是我的代码:

int r = 99;
long test1 = r*r*r*r*r;

at runtime it gives me 919,965,907 instead of the correct 9,509,900,499. 在运行时它给了我919,965,907而不是正确的9,509,900,499。

another test 另一个考验

long test2 = 99*99*99*99*99;

It refuses to compile, saying integer overflow. 它拒绝编译,说整数溢出。

But if i do this 但如果我这样做

long test3 = 10100200300;

This works fine. 这很好用。

The problem is that the literal "99" is being treated as an int. 问题是文字“99”被视为int。 If you add "L" it will treat it as a long. 如果你添加“L”,它将把它视为一个长期。 To fix your compilation problem: 要修复编译问题:

long test2 = 99L * 99L * 99L * 99L * 99L;

And to fix the "incorrect result" caused by integer overflow: 并修复整数溢出导致的“错误结果”:

long r = 99;
long test1 = r * r * r * r * r;

The key point is that the expression to the right of the "=" is evaluated before the assignment to long r is done. 关键点是在完成对long r的赋值之前评估“=”右侧的表达式。

There are other literal suffixes you might be interested in: 您可能还有其他一些字面后缀:

Type    Suffix    Example
uint    U or u    100U
long    L or l    100L
ulong   UL or ul  100UL
float   F or f    123.45F
decimal M or m    123.45M

@m.edmonson, regarding your question about why it comes out to 919965907. What's happening, is that the value is "wrapping" around int.MaxValue. @ m.edmonson,关于为什么它出现在919965907的问题。发生了什么,是值“包裹”在int.MaxValue周围。 You can see this with a little test program: 你可以通过一个小测试程序看到这个:

int i = 99; // 99
i *= 99;    // 9801
i *= 99;    // 970299
i *= 99;    // 96059601
i *= 99;    // 919965907        should be 9509900499 but comes out to 919965907
            //                      which is (9509900499 % int.MaxValue)

long k = 9509900499 % int.MaxValue;

What is meant by "wrapping around"? 什么是“环绕”? When you exceed int.MaxValue by 1, the value "goes back" to int.MinValue . 当你将int.MaxValue超过1时,值“返回”到int.MinValue

int j = int.MaxValue;
j++;

bool isNowMinValue = (j == int.MinValue);   // true, the value has "wrapped around"

This is a bit simplistic; 这有点过分了; if you search for "integer overflow" you will get a better explanation. 如果你搜索“整数溢出”,你会得到一个更好的解释。 It's worth understanding how integers (and other numeric types) are represented with 32 bits: 值得理解整数(和其他数字类型)如何用32位表示:

http://en.wikipedia.org/wiki/Signed_number_representations http://en.wikipedia.org/wiki/Signed_number_representations

It's using integer multiplication : 它使用整数乘法:

long r = 99;
long test1 = r*r*r*r*r;

As the other have said, but: 正如对方所说,但是:

long test2 = 99L * 99 * 99 * 99 * 99;

This will give you the correct result with less L around :-) 这将为您提供正确的结果,减少L左右:-)

This happens because the first 99L is a long , so all the multiplications are done in the long "field" and all the other integers are upcasted to long before the multiplication (clearly the multiplication is always between 2 numbers and it's from left to right, so it's like (((99L * 99) * 99) * 99) * 99 and each "partial" result is a long and causes the next operand to be converted to long.) 发生这种情况是因为第一个99L是一个long ,所以所有的乘法都是在long “字段”中完成的,所有其他整数在乘法之前long (很明显乘法总是在2个数字之间,它是从左到右,所以它就像(((99L * 99)* 99)* 99)* 99而每个“部分”结果都是一个长整数并导致下一个操作数被转换为long。)

Your second test fails because each 99 is an integer; 你的第二次测试失败,因为每个99都是一个整数; replace it with the following and it compiles. 用以下内容替换它并编译。

long test2 = 99L * 99L * 99L * 99L * 99L;

See the MSDN Long Documentation for details. 有关详细信息,请参阅MSDN长文档

The compiler is looking at 99 as integers, even though the final result will be long. 编译器将99视为整数,即使最终结果很长。

This will work. 这会奏效。

long test2 = 99L*99L*99L*99L*99L;

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

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