补码

C++里面带符号整数类型(例如int)对负数的二进制存储是用补码进行的.对补码的解释一般是"对负数的绝对值按位取反再+1".
不过我觉得"按位取反再+1"只是用到补码的时候对的求法.
更符合补码的原理,对补码更加自然的解释是对于一个负数-x,"若数据类型为n个二进制位,则补码为2^n-x".也就是说,这个补码其实就是-x,只不过是对2的n次方取模之后的-x.这样就能理解,为什么减去一个数等于加上这个数的补码,因为补码无非是这个数在模意义下的负数.
自行验证一下,按位取反再+1和2^n-x的结果是完全一样的.按位取反相当于2^n-1再减去x.

#include<cstdio>
int main(){
    unsigned int a = -1;
    printf("%d\n",a);
    printf("%u\n",a);
    printf("%x\n",a);
    return 0;
}

unsigned int a = -1 这个赋值语句首先要把-1转化为二进制补码表示,然后把这串补码表示的二进制数直接赋值给a,赋给a的值当然就是2^32-1.

printf("%d\n",a) 却能完美地输出-1.

这里涉及到int如何分辨正数和负数.int有32个二进制位,用最高位分辨正负.如果最高位为1,就是负数,最高位为0,就是正数(或者0).

int存储范围是[-2^31,2^31-1].我们把负数(-x)都用补码表示,也就是说用(2^32-x)表示.[-2^31,-1]这个范围的整数.可以看到,这个范围的数字得到的补码恰好都是最高位为1的.(-2^31的补码是"最小"的补码,只有最高的二进制位是1,其他二进制位都是0,而-1的补码所有二进制位都是1).而int能表示的最大正数2^31-1,就是令最高位为0,其他数位都是1.
0的补码仍为0,所以补码表示法解决了0的正负问题.

回过头来看那段代码,printf("%d\n",a)里面的%d把a的二进制表示按照int类型解释,自然就解释出了-1的值,输出结果是-1.

总结一下,int补码表示法的的本质是在模2的32次方的意义下表示负数.

转载于:https://www.cnblogs.com/liu-runda/p/9789522.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值