在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
。运行代码时,实际上会出现整数溢出。其他行都行。我忽略了什么吗?
答案 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。因此,没有溢出。