user-0 提问: -9223372036854775808为什么会溢出？

回复:
user: user-1
content: 常量也有类型！

user: user-0
content: 引用 4 楼 拥抱Linux 的回复:你给的cppreference的整数常量的页面里，谈到了这一点啊。 引用注意 没有负整数常量。如 -1 的表达式是将一元负运算符应用到常量所表示的值，可能会引起隐式类型转换。 页面上也给出了相应的正确的语句写法。还提到了： 引用若整数常量过大从而无法符合后缀/底结合所允许的任何类型，且编译器支持扩展整数类型（譬如 __int128 ），则常量可能以扩展整数类型给出；否则程序为病式。 另外，在本地和在线编译器上试了一下，不同的编译器、不同的版本给出的Warning不尽相同。本地 gcc 5.4.0 给的是：  2.c: In function ‘main’: 2.c:7:37: warning: integer constant is so large that it is unsigned   printf("format of %%lld, %lld\n", -9223372036854775808ll);                                      ^ 2.c:7:9: warning: format ‘%lld’ expects argument of type ‘long long int’, but argument 2 has type ‘__int128’ [-Wformat=]   printf("format of %%lld, %lld\n", -9223372036854775808ll);  不过，结果还是期望的「 -9223372036854775808」，这个估计和具体的系统环境、编译器都有关系，不单单是c99而已。 ～   谢谢你！我用的编译器是dev c++自带的，版本较老了。tdm gcc4.8.1版本。

user: user-0
content: 引用 1 楼 636f6c696e 的回复:linux下加入-std=c99编译选项不会有这告警，输出也是对的，你的编译环境是什么？ 我也已经加过这个选项了

user: user-0
content: 引用 1 楼 636f6c696e 的回复:linux下加入-std=c99编译选项不会有这告警，输出也是对的，你的编译环境是什么？ dev c++ gcc

user: user-2
content: 你给的cppreference的整数常量的页面里，谈到了这一点啊。 引用注意 没有负整数常量。如 -1 的表达式是将一元负运算符应用到常量所表示的值，可能会引起隐式类型转换。 页面上也给出了相应的正确的语句写法。还提到了： 引用若整数常量过大从而无法符合后缀/底结合所允许的任何类型，且编译器支持扩展整数类型（譬如 __int128 ），则常量可能以扩展整数类型给出；否则程序为病式。 另外，在本地和在线编译器上试了一下，不同的编译器、不同的版本给出的Warning不尽相同。本地 gcc 5.4.0 给的是：  2.c: In function ‘main’: 2.c:7:37: warning: integer constant is so large that it is unsigned   printf("format of %%lld, %lld\n", -9223372036854775808ll);                                      ^ 2.c:7:9: warning: format ‘%lld’ expects argument of type ‘long long int’, but argument 2 has type ‘__int128’ [-Wformat=]   printf("format of %%lld, %lld\n", -9223372036854775808ll);  不过，结果还是期望的「 -9223372036854775808」，这个估计和具体的系统环境、编译器都有关系，不单单是c99而已。 ～

user: user-1
content: 单步printf语句对应的汇编代码几步后，就会来到printf对应的C源代码output.c处。

user: user-1
content: 理解和讨论之前请先学会如何观察！  提醒：printf是开源的。 参考：Microsoft Visual Studio 10.0\VC\crt\src\output.c  Visual C++ 2010 Express简体中文版http://pan.baidu.com/s/1bnwRVLt

user: user-3
content: linux下加入-std=c99编译选项不会有这告警，输出也是对的，你的编译环境是什么？

user: user-0
content: 谢谢大家。我总结一下。 输出-9223372036854775808的正确方式为：  printf("%lld\n", -9223372036854775807ull - 1);    // 组成有符号值 -9223372036854775808 的正确方式 或  printf("%lld\n", -9223372036854775808ull);   这样是把数值-2^63（或-2^63+1）转成了无符号长长整数，其值为2^63（或2^63+1），值为2^63+1时，减去1后，仍为2^63。而在输出时用%lld，因为在内存中2^63是以1000，0000,0000，此处省略48个0，0000存储的，所以正好是-2^63。这样也不会溢出还能正确的输出值。只是这个技巧让我感觉计算机里的东西“有点东拼西凑投机取巧的感觉”，透出一种无奈。唉没有完美的东西吧。 谢谢各位兄弟的回帖！对我有很大的帮助与启发。谢谢你们！！

user: user-0
content: 但是可以试想即使支持128位，也会有一个负数正好是MIN=-2^127-1。这个数依旧溢出啊  引用 9 楼 拥抱Linux 的回复:[quote=引用 7 楼 liuzhenpolestar 的回复:] 谢谢你！我用的编译器是dev c++自带的，版本较老了。tdm gcc4.8.1版本。  试试根据你给的 cppreference 的 整数常量 的页面里给出的 正确的 语句，在你的 编译器里 再运行看看会是什么结果呢？ ～[/quote] 它给出的运行结果是对的。我想明白了。这样是把数值-2^63转成了无符号长长整数，其值为2^63，而在输出时用%lld，因为在内存中它,是以1000，0000,0000，此处省略48个0，0000存储的，所以正好是-2^63。这样也不会溢出还能正确的输出值。只是这个技巧让我感觉计算机里的东西“有点东拼西凑投机取巧的感觉”。唉没有完美的东西吧。谢谢各位兄弟的回帖！对我有很大的帮助与启发。谢谢你们！！

user: user-2
content: 引用 7 楼 liuzhenpolestar 的回复:谢谢你！我用的编译器是dev c++自带的，版本较老了。tdm gcc4.8.1版本。  试试根据你给的 cppreference 的 整数常量 的页面里给出的 正确的 语句，在你的 编译器里 再运行看看会是什么结果呢？ ～

user: user-4
content: windows下我在dev-c++的编译环境中虽然出现了警告，但还是正确输出结果了的，这个应该和你的编译环境有关系！附上我的代码和截图：  #include<stdio.h> #include<math.h> #include<iostream> using namespace std; main(void ) { 	long long a=-9223372036854775808; 	printf("%lld\n", a);  }