首页 > 代码库 > 0.1.2 二进制补码

0.1.2 二进制补码

《编程导论(Java)·0.1.2 二进制补码》


p6:【冯?诺伊曼体系结构计算机使用二进制。人类之所以习惯十进制,据说是因为用手指头来计算比较方便,而人正好有10个指头。】

本节就2面(page6和p7)纸。虽然二进制补码属于每个程序员都应该熟练掌握的内容,但通常安排同学们自学。

重点要理解:为什么要采用补码?


将10进制数转换为二进制数时,负数如何在二进制中表达呢?为了讲解的方便,这里使用半个字节(Nibble)即4位为数据长度。

将最高位作为符号位是自然的想法。通常以0表示正、1表示负。去掉符号位后,正数就剩下的3位来表示0~7,0b0000~0b0111等称为原码。对于负数有一种简单但有问题的表示方式:符号加绝对值,如图0-4中间一列所示。


图 0?4 补码

它有两个问题(下面的01串不是正规的二进制表示,因而不加前缀0B):

  •  在整个0000至1111的编码中,出现了两个0,即0000和1000表示+0和-0。想判断一个数是否等于0的时候,会给编程带来麻烦。
  •  更关键的问题是,两个正数的加法与两个正数的减法(也即一个正数加一个负数)没有统一的运算法则。下面是出了问题的例子:

6-3 = 0110 + 1011 = 0001 = 1;
-3-2= 1011 + 1010 = 0101(有溢出) = 5

为了解决这些问题,计算机科学中,以二进制补码(the two’s complement)来编码数值。

负数的补码算法:将对应的正数每位取反,然后最低位加1。

例如求-5的补码如下:

对应的正数: 0b0101

每位取反:   0b1010

最低位加1:   0b1011



要求完成:

  • 练习0-11:有人找程序员借了500元钱,后来又想借500元,程序员说,干脆凑个整数,这是524块。为什么唐纳德·克努特给找出其巨著中任一错误的读者2.56美元?(请熟记2的各次幂)
  • 练习0-12:请严格地定义二进制补码规则。提示:符号位、正数的补码、负数的补码。(我们不给出二进制补码规则,仅介绍负数的补码算法,其他你自己搞定)
  • 练习0-13:数据长度为n位的有符号二进制整数,为什么最大正数为2n-1 -1?能够表示的最大负数为多少?(Java整形的取值范围)
  • 练习0-16:计算下列各题:(1)0x9AB4+0x5C; (2) 0170-023 ;(3) 0b1101*0b101

    练习0-17.:转换进制。(1) 0b1001_1100 = 0____;(2) 0x7F = 0b_______ ;(3) 0107 = 0b_________。


  • 在学习《第12章位运算》时,本节的知识是基础,很重要。
  • 最好的练习项目:整形算术编码。