[已注销]对《编码》的笔记(3)

编码
  • 书名: 编码
  • 作者: [美] Charles Petzold
  • 副标题: 隐匿在计算机软硬件背后的语言
  • 页数: 392
  • 出版社: 电子工业出版社
  • 出版年: 2010
  • 第137页
    看到这页,终于明白反码为什么叫1’s complement,而补码叫2's complement了!
    ==反码(1's complement) - 用加法替代减法
    对十进制来说反码其实就是9's complement
    1 -> 8
    7 -> 2
    ...
    它反应了某种形式转换(假设这种转换可以用组合逻辑电路在一瞬间完成,但是考虑到电路一般都是二进制的,所以这种电路并不存在)
    这样如果我们要计算减法的时候就不需要在加法器之外再添加一个额外的减法器了
    253
    -176
    ------
    我们先对176按位做9's complement这种转换:
    176 turns to 823 in a sudden!
    事实上它等价于下面这个减法,但是我们的电路并不懂减法,它只会按位做9's complement
    999
    -176
    --------
    823
    接下去我们就可以用加法器来完成下面这个加法操作:
    823
    +253
    --------
    (1)076
    最高位的1被自动舍弃了,再加上1,于是我们得到253-176的正确答案77!
    对二进制来说,这种转化被变成了1's complement,在电路中我们用一个反向器就能实现。
    1's complement
    0 -> 1 1 - 0 = 1
    1 -> 0 1 - 1 = 0
    所以说,反码的出现是为了解决了减法的问题,但是还有个问题没有解决,那就是怎么在计算机中表示负数。
    ==补码 2's comlement - 表示负数
    -50 -49 -48 -1 0 1 2 3 48 49 (数轴上的整数)
    但是我们机器不能显示“-”这个符号,对于一台十进制的机器,数字之可能显示“0~9”这些数字。
    对于两位十进制来说,可以表示100种不同的状态。如果全部拿来表示正数可以从0表示到99,但是这样就没有办法表示负数。我们想拿出一部分数字来表示负数。
    用补码(10's complement)表示如下(我已经把它对应到了数轴)
    50, 51, 52, ... , 99, 00, 01, 02, 03, ..., 48, 49 (一个负数相当于一个大正数)
    依次代表了
    -50 -49 -48 -1 0 1 2 3 48 49 (数轴上的整数)
    可以看到对于比较小的正数来说,它们代表了自己,对于比较大的正数来说,它们代表了另一个负数。为什么要这样循环对应?下面会讲。
    -1的补码是99 - 1 + 1 = 99
    -2的补码是99 - 2 + 1 = 98
    -50的补码是99 - 50 + 1 = 50
    10's complement相当于用100减去当前的字面值,-32的补码就是100 - 32 = 68(因为我们的机器知道自己的可以表示的最大正数是49,所以当字面值小于49时,它知道这代表了一个正数;当字面值大于等于50时,它知道这其实是一个负数,于是它要经过一个10's complement操作,才能表达出这个字面值真实的含义!)
    但因为我们电路中没有减法器,所以我们要借用9’s comlement和plus one这两个操作来实现10's complement这一个操作。
    这个系统提供了我们了一种不用正负号表示整数的方式,而且可以用加法替代减法!
    下面就来讲这种循环对应的好处。
    如果我们要计算35 - 17。它等价于35 + (100 - 17) - 100。其中100 - 17是一个求10's complement的操作,-17在这个系统就表示成一个较大的字面值:83,而35还是表示成35。35 + 83 = 116,自动舍去最高位,就等于16。
    如果不循环对应可以吗?当然可以,还是00~99这100个字面值,我们可以用字面值中最小的数对应最小的负数,字面值中最大的值来对于最大的正数。
    00, 01, 02, 03, ..., 48, 49, 50, 51, 52, ... , 99
    -50 -49 -48 -2 -1 0 1 2 49 (数轴上的整数)
    这显然不是一个好方法,首先我们牺牲了小正数不用转化的好处。0在计算机内部表示成50就让人感觉怪怪的,我们在做1+1的时候,计算机内部先要把两个51先转换成两个1(便于做加法运算),保存结果的时候还得再转回去……这种方法显然是不可行的,正数还得对应正数。
    那么就试试下面这种排列吧。
    99, 98, 97, ... ,50, 00, 01, 02, 03, ..., 48, 49 (一个负数相当于一个大正数)
    -50 -49 -48 -1 0 1 2 3 48 49 (数轴上的整数)
    直觉告诉我这也不是一种好的方法,因为它缺乏数学上的美感,事实上也是如此,对于负数来说,他的字面值每增加1,它表示的数值反而减少了1。所以说是10's complement这种表示方法还是比较靠谱的。
    而对应到二进制中,补码自然就叫2's complement了。
    2011-11-16 19:58:19 6人喜欢 2回应
  • 第167页
    其实还可以用球员(根据球衣号码)来表示:十六进制的A、B、C、D、E、F
    A=R. Giggs 11
    B=J. Stockton 12
    C=M. Ballack 13
    D=T. Henry 14
    E=C. Anthony 15
    F=R. Keane 16
    :)
    2012-07-13 00:56:07 回应
  • 第242页
    所有计算机本质都相同,即使硬件做不到,也可以通过软件的方法实现。
    而决定两台计算机区别的是它们处理器的*速度*,*速度*也是为什么我要使用计算机的原因。在有限的*时间*内,处理更多的*信息*是人类一直以来追求的东西。
    2012-07-20 07:56:09 回应

[已注销]的其他笔记  · · · · · ·  ( 全部295条 )

The Design of Everyday Things
1
About Face 3
6
Engineering a Compiler
1
人有人的用处
8
Understanding the Linux Kernel
4
计算机程序设计艺术
1
公正
1
The Art of Doing Science and Engineering: Learning to Learn
1
科学革命的结构
7
罗素论教育
3
三十六大
1
娱乐至死
3
Real World Haskell
2
Writing Analytically
1
Is Parallel Programming Hard, And, If So, What Can You Do About It?
1
计算机与人脑
1
组合数学
2
菊与刀
1
Rework
5
翻译新究
4
计算机程序的构造和解释(原书第2版)
5
The Laws of Simplicity
4
计算机组成与设计硬件/软件接口
6
写给无神论者
2
放任自流的时光
3
哥德尔、艾舍尔、巴赫
2
树上的男爵
2
C++语言的设计与演化
1
Land of LISP
7
C陷阱与缺陷
2
CUDA by Example
3
C++沉思录
1
世界尽头与冷酷仙境
4
Head First C
2
刀锋
1
并行编程模式
2
The Ph.D. Grind
2
计算机系统结构
2
禅与摩托车维修艺术
14
流浪的面包树
2
翻译研究
18
An Introduction to Programming in Emacs Lisp
1
GNU Emacs Lisp 编程入门
1
计算机系统概论
1
拖延心理学
1
古今数学思想(一)
1
挪威的森林
9
奇特的一生
7
GPU高性能运算之CUDA
5
那些年,我们一起追的女孩
8
十八岁给我一个姑娘
2
C++编程思想(第1卷)
9
多核计算与程序设计
8
少有人走的路
5
忧伤的情欲
3
Hackers & Painters
7
哲学的慰藉
9
男人来自火星 女人来自金星
8
旅行的艺术
14
活着活着就老了
1
如何阅读一本书
7
Data-intensive Text Processing With Mapreduce
1
学习GNU Emacs
1
给研究生的学术建议
3
C专家编程
2
Spring揭秘
2
Head First Java(第二版·中文版)
1
自私的基因
1
C程序设计语言
2
计算机网络
3
自由在高处
2
大话设计模式
16
计算机网络
12