关于Integral Promotions

 

节选自:http://www.cnitblog.com/guopingleee/archive/2009/01/18/53849.html

 

 

1. 所有的位移操作的右操作数必须小于左操作数的位长度,否则结果未定义
2. 右移操作对于unsigned系列,高位一直补0。对于signed系列,高位补符号位
3. 在操作过程当中,有可能产生Integral Promotions。这就比较复杂了。C++中采用和C相同的策略,提升后的的量总是“保值的”,即原有的bit值不变;但不一定是“保号的”。运算中,如果char/bit field不能保持全部的值,就会被提升到int型,如果int也不能保存全部的值就会被提升至unsigned。有几种罕见的情况,保值和保号的运算会导致不同的值: 
(1) /, %, /=, %=, <, <=, >, >=
 运算依赖于符号,应用时可能导致不同结果。
(2)>>, >>= 运算有时依赖于符号位。
(3)函数重载参数可能依赖于符号。

由此可见,上述程式的位操作次数大于等于了整数的位数,输出结果不确定也是正常的。为了完全理解这个问题,再作下面的试验:

 int a = 31;
 int x = 0xFFFFFFFF;
 cout << typeid(0xFFFFFFFF).name() << endl;
 cout << typeid(0x0FFFFFFF).name() << endl;
 cout << int(0xFFFFFFFF >> 31) << endl;
 cout << int(x >> 31) << endl;
 cout << int(0xFFFFFFFF >> a) << endl;

输出:Debug/Release下均为 unsigned int, int, 1, -1, 1
这里能清晰地看到
0xFFFFFFFF之内被unsigned int放下,所以其类型是unsigned int;而0x0FFFFFFF一个int就能放下了,所以类型是int。两个1的输出没什么好说的。-1的输出是因为x为有符号数,且符号位是1,所以高位补1,结果总不变。但这个1和-1的差异的确够隐晦的。

总结经验:当对变量进行位移操作时,逻辑上应该尽可能使用无符号数。位移长度应严格控制在字长以内。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值