十六进制数用int吗_你真的懂补码吗?

0eee3abd0a0f85a16650869c55c479af.png

有点编程基础的人都知道负数在计算机中是用补码表示的.但是你知道为什么补码 = 反码 + 1吗?它的表示和C++编程有什么关系?通过阅读本文章,你不仅可以加深对这些问题的理解,更重要的是,可以学会十进制与二进制补码的快速转换、区分C语言中usigned int和普通int的二进制表示方法,那么让我们开始吧.

1. 补码的本质

补码(Two's complement)是为了解决计算机的减法问题而设计的.它是人为规定的一种编码方式.早期的计算机出现过在数的末尾加上一个符号位的方式来表示负数.以4-bit补码为例,其原码和补码的表示如下:

%4位数原码和补码的表示
%假设4位数从左到右分别叫x3,x2,x1,x0
1111  15        0111   7
1110  14        0110   6
1101  13        0101   5
1100  12        0100   4
1011  11        0011   3
1010  10        0010   2
1001   9        0001   1
1000   8        0000   0
--------        --------
0111   7        1111  -1
0110   6        1110  -2
0101   5        1101  -3
0100   4        1100  -4
0011   3        1011  -5
0010   2        1010  -6
0001   1        1001  -7
0000   0        1000  -8
  原码            补码

可以发现,所谓补码不过是将原本和8~15对应的二进制变成了-8~-1,这就是补码的编码方式.

2. 有趣的"111...1"

十进制中,一个正数与相应的负数相加为零.同样的,在二进制里也应该满足这样的条件.

为什么"1111"要表示-1?将"0001"(十进制的1)和"1111"(十进制的-1)相加可以得到10000.如果我们使用的计算电路是一个四位的全加法器,那么由于溢出,电路的输出为"0000",恰好对应十进制的0.这样的一个特性给硬件电路的设计带来了极大的方便.

另外一个有意思的是一个二进制数的反码(按位取反)与原码相加恰好是"1111",这就为补码和原码的相互转化提供了一个捷径.

标题的"111...1"中间我加了省略号,是因为无论多少位的二进制补码,当所有位都为1的时候对应的十进制数都是-1.

3. 为什么补码 = 原码的反码 + 1?

这种计算是基于这样的事实:一个数和它的按位取反结果相加,和一定是111...111,即-1,因此:

所以得到:

根据这个简单的证明过程,我们不难发现同样的原码 = 补码的反码 + 1.

4. 符号位与数的扩展

让我们在回去看看第一小节原码和补码的表示.我在每一列的中间画了一个分割线,将二进制数按

的不同分成了两组.在这里
就叫做
符号位,其中
为0的时候代表正数,为1的时候代表负数.

现在的计算机总线基本都是32位或者64的位的,那么怎么将4位二进制数补码扩展成32位的呢?很简单,在前面补上28个符号位就行.比如2对应的32位补码为"00..0010",-3对应的32位补码为"11...1101".64位的扩展也是同理哦.

下面来个小测验吧,假设一个十六进制补码为0xFFFFFFFB,那么他对应的十进制数为多少?(答案见下一小节)

5. usigned int 和int

我们都知道C语言中整数类型对应4个字节(32位),有无符号整数(usigned int)和有符号整数(int)区分,他们在计算机中的存储格式就是对应的原码和补码的表达方式.

上一小节中的十六进制补码0xFFFFFFFB,就是有符号整数,对应的值为-5(你算对了嘛◉‿◉),如果定义的是usigned int,那将会是一个很大的数,这里就不计算了.

6. 二进制到十进制的计算

假设一个n位的二进制数每个位用

来表示,那么原码转化为十进制的计算公式为:

补码转化为十进制的计算公式为:

这样可以得到n位补码的取值范围为

~
.

7. 结束语

感谢你能看到文章的最后,本文内容参考了《计算机组成与硬件软件接口》、《深入理解计算机系统》、《编码》等相关书籍.结合了自己的一些思考.

如果觉得对你产生帮助话,麻烦点个赞,让更多的看到并受益,啾咪~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值