首页
社区
课程
招聘
[原创]关于第二章的原码和补码的一些小整理....
发表于: 2011-10-17 08:55 5755

[原创]关于第二章的原码和补码的一些小整理....

2011-10-17 08:55
5755
整数原码:
在源码中最高位用来表示符号位,例如:
0,0001 = 1;
1,0001 = -1;
整数原码的计算:加权展开
比如0, 1111
1*23+ 1*22+ 1*21+ 1*20= 15
对于整数原码的定义:
[X]source |    0, x (2n > x ≥ 0)
                |    2^n – x ( 0 ≥ x > -2n)

小数原码:
同理用最高位表示符号:
0.1000 = 0.5
1.1000 = -0.5
小数原码计算:
一样是加权展开:
0.1000 = 1-1(-1) + 0*2-2............
对于小数原码的定义:
[X]source|    x (1 > x ≥ 0)
            |    1 – x (0 ≥ x > -1)
以上是补码的定义以及计算..但是当计算机真正计算的时候如果原码去计算那么就会存在需要比较大小等等一系列操作....所以引进了原码..
关于原码的解释..我们计算机组成原理的老师最喜欢用书上那个经典的时钟例子..比如说现在时钟指向6点钟..那么当你想走到3点中的时候应该怎么办呢?
有两种方法...一种是逆时针走3小时...第二种是顺时针走9小时...即
6 – 3 = 3;
6 + 9 = 3 + 12 = 3;(mod 12)因为他们是以12为模..那么就可以去掉12...在数学上称12为模...写作mod12...而称9和-3是以12为模的补数...
例如:
-4 ≡ 8(mod12)
-5 ≡ 7(mod12)
如果一个负数和一个正数的绝对值相加等于模..那么就说这两个数互为补数...这样就找到了一个正数来代替负数进行运算...
比如:A = 9, B = 5, 求A –B       (mod12)
方法一:9 – 5 = 4
方法二: 9 + 7(5的补数) = 16 = 4 + 12 = 4
这样就避免了减法运算...而在计算机中一般对于2n的二进制数...通常模为2n+1

接下来是整数补码的定义:
          [X]原 = |    0, x ( 2n > x ≥0)
               |2n – x (0 ≥ x  > -2n)
在这里可以看到正整数的补码就是他本身[x]原 = [x]补
因为比如:
-7的补码(以12为模): -7 + 12 = 5...那么-7以12为模对应的补数是5
4的补码 4 + 12 = 4..所以正数的补码就是他本身
  
接下来看负数的补码:
假设x = - 1101
[X]补 = 100000 – 1101 = 1, 0011

下面再到小数部分:
小数补码的定义:
[X]补 = |    x (1 > x ≥ 0)
           |    2 + x (0 > x ≥ -1)     (mod 2)
同理小数正数的补码也等于他自己...
对于负数...假如x = -0.0100
[X]补 = 2 – 0.0100

10.0000
-0.0100
= 1.1100

那么还有一个问题就是为什么在负数的时候0是取不到的?
我们知道在原码的时候0有两种表示方式:
0, 0000
1, 0000
那么我们试下在补码的定义下来看下0的表示方式(假设为5位):
[+0.0000] = 0.0000
[-0.0000] =  10.0000 – 0.0000 = 0.0000(最高位舍弃)其实他这里的最高位我也有点搞不懂....只知道可以双符号判断...并且双符号判断在溢出判断中经常用到...

但是到这里又出现了一个问题,本身我们用补码的目的就是为了消除减法, 但是在定义中我们却又引入了减法..
[补码] = 2n – |x|...那么我们可以转换一下
[补码] = 1011....1n-1 + 0001....0n-1  -  x1x2x3....xn-1 (这里的X表示的是x用二进制表示的个个位上的值...非0即1,并且这里的x是正数)
下面的粗体表示取反:
[补码] = 1*X0X1X2Xn-1 - 0001....0n-1
也就是[补码] = 原码取反 + 1;
[原码] = 补码取反 + 1;

下面是浮点表示:
先提下定点机:
定点机就是看小数点位置是位于数符和数值之间(纯小数)还是位于数值之后(纯整数)他的范围可以通过上面给的定义求出来:
[原码]:
整数:(2n – 1)到-(2n – 1)
小数:2-n到1 – 2-n
[补码]:
整数:2n到-2n
小数:2-n到-1

浮点数的表示:
N = S * Rj
S是位数,j是阶码, R是基数..基数可以取2, 4, 8, 16......
假设以2为基数..那么数N可以写成好多种形式
N = 11.0101
  = 0.110101 * 210(此时小数点向左移动两位, 你把阶码加权展开算出来就是移的位数)
= 1101.01 * 2-10(同理, 这里向右移动了两位)

比如在书上21页:
12.25转化为浮点表示
先化成二进制的原码:
[12.25] = 1*23 + 1*22 + 0*21 + 0*20 + 0*2-1   + 1*2-2= 1100.01
再用科学记数法化简(向左移动三位):
1.11001 * 2j
J = 3 + 127(规定大于127的为正数,小于127的为负数)

[课程]Linux pwn 探索篇!

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//