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

时间:2011-10-14 11:36:50

标签: c# integer

我查看的文件long = int64的范围超过900,000,000,000,000

这是我的代码:

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

在运行时它给了我919,965,907而不是正确的9,509,900,499。

另一个测试

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

它拒绝编译,说整数溢出。

但如果我这样做

long test3 = 10100200300;

这很好用。

5 个答案:

答案 0 :(得分:48)

问题是文字“99”被视为int。如果你添加“L”,它将把它视为一个长期。要修复编译问题:

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

修复整数溢出引起的“错误结果”:

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

关键是在完成long r的分配之前,评估了“=”右侧的表达式。

您可能感兴趣的还有其他文字后缀:

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,关于为什么它出现在919965907的问题。发生了什么,是值“包裹”在int.MaxValue周围。你可以通过一个小测试程序看到这个:

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;

“环绕”是什么意思?当您将int.MaxValue超过1时,值“会返回”int.MinValue

int j = int.MaxValue;
j++;

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

这有点过分了;如果你搜索“整数溢出”,你会得到一个更好的解释。值得理解整数(和其他数字类型)如何用32位表示:

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

答案 1 :(得分:5)

它使用整数乘法:

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

答案 2 :(得分:4)

正如对方所说,但是:

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

这将为您提供正确的结果,而L周围的内容更少: - )

这是因为第一个99L是long,因此所有乘法都在long“字段中完成”,并且所有其他整数在乘法之前被上升到long(显然乘法总是在2个数字之间,它是从左到右,所以它就像(((99L * 99)* 99)* 99)* 99,每个“部分”结果都是一个长的并导致下一个操作数被转换很久。)

答案 3 :(得分:3)

你的第二次测试失败,因为每个99都是一个整数;用以下内容替换它并编译。

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

有关详细信息,请参阅MSDN Long Documentation

答案 4 :(得分:1)

编译器将99视为整数,即使最终结果很长。

这样可行。

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