作者descent (「雄辩是银,沉默是金」)
看板C_and_CPP
标题Re: [问题] C unsigned long的问题
时间Tue Jul 18 21:36:44 2017
※ 引述《final01 (牛顿运动定律)》之铭言:
: 开发平台(Platform): (Ex: Win10, Linux, ...)
: Linux
: 编译器(Ex: GCC, clang, VC++...)+目标环境(跟开发平台不同的话需列出)
: GCC
: 额外使用到的函数库(Library Used): (Ex: OpenGL, ...)
: 问题(Question):
: #include <stdio.h>
: void print_x(unsigned long x)
: {
: printf("=> 0x%lx\n",x);
: }
: int main()
: {
: print_x(0x80000000);
: print_x((1<<31));
: }
: 想问为何同样是数字一个不会overflow 一个会??
: 喂入的资料(Input):
: 0x80000000
: 1<<31
我猜测你平台的 long 是 64bit。
0x80000000 的 type 是 unsigned int, 所以是 2147483648。
1<<31 运算後结果 0x80000000 的 type 是 int, 所以是 -2147483648。
很奇怪, 一个是 unsigned int, 一个却是 int 是吧!
把 int -2147483648 传给 unsigned long 时, 16 进位便是 0xffffffff80000000,
而不是 80000000。
--
纸上得来终觉浅,绝知此事要躬行。
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 117.19.8.137
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1500385012.A.4DE.html
1F:→ PkmX: 32-bit int的话 1<<31 就已经是 undefined behavior 了 07/18 22:13
感谢, ref N1570 p95 第4点, 还真的不容易看, 英文不好, 请大家帮忙确认一下。
2F:推 final01: 有spec说明0x80000000就是unsigned int?? 1<<31就是int 07/18 22:37
3F:→ final01: 这是我比较想知道的XDD 07/18 22:37
ref N1570 6.4.4.1 integer constants
4F:→ remizu: 标准规格书中有Types of integer constants的表 07/18 22:59
5F:推 LPH66: 一般来说没附字尾的整数是 int, 除非 int 装不下 07/19 08:22
6F:→ LPH66: 装不下的时候会有一定的程序往上试型态, 试到装下了就用 07/19 08:22
7F:→ LPH66: 这是为什麽 0x80000000 是 unsigned int 的原因 07/19 08:22
8F:→ LPH66: 1<<31 则是 1 和 31 这两个常数进行运算 07/19 08:23
9F:→ LPH66: bitshift 看左边, 1 是 int 所以结果就是 int 07/19 08:23
10F:→ LPH66: 这就是为什麽一般对 bitmask 的值会写成 1U<<31 的原因 07/19 08:24
11F:→ LPH66: 加个 U 就是说这个 1 是 unsigned int 07/19 08:24
12F:→ LPH66: 顺带一提的是, C/C++ 没有负 literal, 所有看起来是负数的 07/19 08:25
13F:→ LPH66: 常数都是正常数加负号, 所以某些负值会产生很意外的结果 07/19 08:26
※ 编辑: descent (175.98.141.254), 07/19/2017 09:32:57