VS13 C ++意外的积分溢出

时间:2015-11-02 09:07:51

标签: c++ visual-studio-2013

在VS13中考虑这个C ++代码:

long long Number;
Number =  10000000000*900;
Number =     10000000*214;
Number =     10000000*215;
Number =    (long long) 10000000*215;

编译时,第4行会得到warning C4307: '*' : integral constant overflow。运行代码时,实际上会出现整数溢出。其他行都行。我忽略了什么吗?

2 个答案:

答案 0 :(得分:2)

默认情况下,10000000常量(字面值)被视为int常量,因为它符合int类型:

  

整数文字的类型是值的第一种类型   可以适合,取决于哪个数字类型的类型列表   以及使用了哪个整数后缀

http://en.cppreference.com/w/cpp/language/integer_literal

因此乘法在int类型内完成(不会发生整数提升)。你可以考虑一下这行

Number =     10000000*215;
好像是

const int tmp1 = 10000000;
const int tmp2 = 215;
Number = tmp1*tmp2;

显然这会产生溢出,同样第三行和最后一行也不会产生溢出。对于第二行,编译器理解10000000000既不适合int也不适合long,因此使用long long

您可以使用ll后缀强制常量为long long

Number =     10000000ll*215;

答案 1 :(得分:1)

默认情况下,字面数字被理解为int类型。在Visual Studio中,它是一个32位整数。将两个整数相乘得到一个int。

因此这个表达式:

10000000*215   // (hex value is 0x80266580.)

已经溢出,因为预期值不能表示为32位正整数。编译器会将其解释为-2144967296,这与2150000000完全不同。

因此,对于强制表达式为64位,这些操作数中的至少一个必须是64位。因此,这很好用:

Number =     10000000LL * 215; // LL qualifies the literal number as a "long long"

它强制将整个表达式(long long乘以int)视为long long。因此,没有溢出。