《编程导论(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章位运算》时,本节的知识是基础,非常重要。
- 最好的练习项目:整形算术编码。