(int)(a - b)并不安全,其中a和b均为unsigned int

<pre name="code" class="cpp">return (int)(a - b);
 

其中a和b均为unsigned int。

这段代码是有隐患的。

如果要理解为什么有隐患,首先你要温习下计算机内如何表示负数和减法如何实现(有很多详尽的文章描述,这里仅以例子int为说明)

  • 负数表示

第31位为负数表示位,0表示正数,1表示负数

  • 减法实现

减一个数,就是加这个数的负数:A - B = A + (-B)

什么是补码?简而言之,正数的补码就是原码,负数的补码就是反码+1

1)如果补码的符号位为“0”,表示是一个正数,所以补码就是该数的原码;

2)如果补码的符号位为“1”,表示是一个负数,求原码的操作可以是:符号位为1,其余各位取反,然后再整个数加1。 

如:
                                原码                   反码                  补码
-127 -〉127    1000 0001  -〉 0111 1110  -〉 0111 1111
127 -〉-127    0111 1111  -〉 1000 0000  -〉 1000 0001
-128 -〉128    1000 0000  -〉 0111 1111  -〉 1000 0000
128 -〉-128    1000 0000  -〉 0111 1111  -〉 1000 0000


但是呢,这只是int下的原理,因为unsigned int是无符号的,所以其补码是所有位取反后加1


回到例题:

如a = 1,  b =0x80000002,它的计算过程如下

   00000001          00000001

- 80000002  =  + 7FFFFFFE = 7FFFFFFF

即a - b > 0(a > b)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值