C/C++中的有符号和无符号的位运算问题

是对C/C++下面的结果感到困惑?

printf("%d\n", ((unsigned char)~0 >> 1)); //结果为127

printf("%d\n", -((unsigned char)~0 >> 1));  //结果为-127

printf("%d\n", ((signed char)~0 >> 1));  //结果为-1

printf("%d\n", -((signed char)~0 >> 1));  //结果为1

我们来一步一步分析一下!


一、运算符优化级


~按位取反运算符 优先级高于 >>右移位运算符

(unsigned char)~0 >> 1 //0取反为二进制11111111,无符号数右移1位为01111111,结果为127

(signed char)~0 >> 1 //0取反为二进制11111111,有符号数右移1位为11111111,结果为-1


二、有符号数和无符号数的右移


为什么无符号数11111111右移1位为01111111,而有符号数11111111右移1位为11111111呢?

移位时,移出的位数全部丢弃,移出的空位补入的数与左移还是右移有关。如果是左移,则规定补入的数全部是0;如果是右移,还与被移位的数据是否带符号有关。若是不带符号数,则补入的数全部为0;若是带符号数,则补入的数全部等于原数的最左端位上的原数(即原符号位)


三、原码与补码

为什么无符号数01111111为127,有符号数11111111为-1?

在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理。此外,补码与原码相互转换,其运算过程是相同的。

补码的表示方法是:正数的补码就是其本身;负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1,即在反码的基础上+1。

所以对于负数, 补码表示方式也是人脑无法直观看出其数值的. 通常也需要转换成原码在计算其数值.



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值