在Visual Studio 2010上的以下程序
#include <iostream>
using std::cout;
int main()
{
cout << -2147483646 << '\n';
cout << -2147483647 << '\n';
cout << -2147483648 << '\n'; // numeric_limits<int>::min()
cout << -2147483649 << '\n';
cout << -2147483650 << '\n';
cout << "..." << '\n';
cout << -4294967293 << '\n';
cout << -4294967294 << '\n';
cout << -4294967295 << '\n'; // -numeric_limits<unsigned int>::max()
cout << -4294967296 << '\n';
cout << -4294967297 << '\n';
}
Run Code Online (Sandbox Code Playgroud)
生成以下输出
-2147483646
-2147483647
2147483648
2147483647
2147483646
...
3
2
1
-4294967296
-4294967297
Run Code Online (Sandbox Code Playgroud)
到底是怎么回事?
这是标准行为还是Visual Studio错误?
编辑:有几个人指出,没有负整数文字这样的东西.有关详细信息,请参阅下面的Keith Thompson的优秀答案.
Kei*_*son 16
-2147483648例如,不是整数文字; 它是一个由-应用于文字的一元运算符组成的表达式2147483648.
在新的C++ 2011标准之前,C++不需要存在任何大于32位的类型(C++ 2011添加long long),因此文字2147483648是不可移植的.
十进制整数文字是其值适合的以下第一种类型:
int
long int
long long int (new in C++ 2011)
Run Code Online (Sandbox Code Playgroud)
请注意,它从来不是标准C++中的无符号类型.在1998和2003版本的C标准(没有long long int)中,十分大小的文字太大而不适合long int导致未定义的行为.在C++ 2011中,如果十进制整数文字不适合long long int,则程序"格式错误".
但是gcc(至少从版本4.6.1开始,我拥有的最新版本)没有实现C++ 2011语义.文字2147483648不适合32位长,unsigned long至少在我的32位系统上被视为.(这对于C++ 98或C++ 2003来说很好;行为是未定义的,因此编译器可以做任何喜欢的事情.)
所以给定一个典型的32位二进制补码int类型,这个:
cout << -2147483647 << '\n';
Run Code Online (Sandbox Code Playgroud)
获取int值2147483647,否定它,并打印结果,该结果与您期望的数学结果相匹配.但是这个:
cout << -2147483648 << '\n';
Run Code Online (Sandbox Code Playgroud)
(当使用gcc 4.6.1编译时)获取long或unsigned long值2147483648,将其否定为unsigned int,产生2147483648并打印出来.
正如其他人所提到的,您可以使用后缀来强制使用特定类型.
这是一个小程序,可用于显示编译器如何处理文字:
#include <iostream>
#include <climits>
const char *type_of(int) { return "int"; }
const char *type_of(unsigned int) { return "unsigned int"; }
const char *type_of(long) { return "long"; }
const char *type_of(unsigned long) { return "unsigned long"; }
const char *type_of(long long) { return "long long"; }
const char *type_of(unsigned long long) { return "unsigned long long"; }
int main()
{
std::cout << "int: " << INT_MIN << " .. " << INT_MAX << "\n";
std::cout << "long: " << LONG_MIN << " .. " << LONG_MAX << "\n";
std::cout << "long long: " << LLONG_MIN << " .. " << LLONG_MAX << "\n";
std::cout << "2147483647 is of type " << type_of(2147483647) << "\n";
std::cout << "2147483648 is of type " << type_of(2147483648) << "\n";
std::cout << "-2147483647 is of type " << type_of(-2147483647) << "\n";
std::cout << "-2147483648 is of type " << type_of(-2147483648) << "\n";
}
Run Code Online (Sandbox Code Playgroud)
当我编译它时,我得到一些警告:
lits.cpp:18:5: warning: this decimal constant is unsigned only in ISO C90
lits.cpp:20:5: warning: this decimal constant is unsigned only in ISO C90
Run Code Online (Sandbox Code Playgroud)
和以下输出,即使gcc -std=c++0x:
int: -2147483648 .. 2147483647
long: -2147483648 .. 2147483647
long long: -9223372036854775808 .. 9223372036854775807
2147483647 is of type int
2147483648 is of type unsigned long
-2147483647 is of type int
-2147483648 is of type unsigned long
Run Code Online (Sandbox Code Playgroud)
我使用VS2010获得相同的输出,至少使用默认设置.
| 归档时间: |
|
| 查看次数: |
2883 次 |
| 最近记录: |