其他分享
首页 > 其他分享> > 【组成原理-数据】定点数的编码与运算

【组成原理-数据】定点数的编码与运算

作者:互联网

目录

1 定点数的编码

1.1 编码的种类

定点数编码有四种:

【注 1】设原码字长为 n(即有 n 位),则原码整数的表示范围为-(2n-1-1) ≤ x ≤ +(2n-1-1)

【注 2】设原码字长为 n(即有 n 位),则原码小数的表示范围为-(1-2-(n-1)) ≤ x ≤ +(1-2-(n-1))

【注 3】原码全 0,对应真值的最小值-(2n-1);原码全 1,对应真值的最大值+(2n-1-1)

【注 4】0 的表示不唯一,分正负零(0,000,0000 和 1,000,0000)

【注 1】设反码字长为 n(即有 n 位),则反码整数的表示范围为-(2n-1-1) ≤ x ≤ +(2n-1-1)

【注 2】设反码字长为 n(即有 n 位),则反码小数的表示范围为-(1-2-(n-1)) ≤ x ≤ +(1-2-(n-1))

【注 3】反码全 0,对应真值的最小值-(2n-1);反码全 1,对应真值的最大值+(2n-1-1)

【注 4】0 的表示不唯一,分正负零(0,000,0000 和 1,111,1111)

【注 1】设补码字长为 n(即有 n 位),则补码整数的表示范围为-(2n-1) ≤ x ≤ +(2n-1-1)

【注 2】设补码字长为 n(即有 n 位),则补码小数的表示范围为-1 ≤ x ≤ +(1-2-n)

【注 3】补码全 0,对应真值的最小值-(2n-1);补码全 1,对应真值的最大值+(2n-1-1)

【注 4】0 的表示唯一(0,000,0000)

【注 5】若补码的符号位相同,则数值位越大码值越大

【注 1】设移码字长为 n(即有 n 位),则移码整数的表示范围为-(2n-1) ≤ x ≤ +(2n-1-1)

【注 2】移码全 0,对应真值的最小值-2n;移码全 1,对应真值的最大值+(2n-1)

【注 3】0 的表示唯一(1,000,0000)

【注 4】移码保持了数据原有的大小顺序,移码大真值就大,移码小真值就小

真值 补码 移码
-128 1000,0000 0000,0000
-127 1000,0001 0000,0001
-126 1000,0010 0000,0010
... ... ...
-2 1111,1110 0111,1110
-1 1111,1111 0111,1111
0 0000,0000 1000,0000
1 0000,0001 1000,0001
2 0000,0010 1000,0010
... ... ...
125 0111,1101 1111,1101
126 0111,1110 1111,1110
127 0111,1111 1111,1111

1.2 编码的转换

【例 1】(-100)10 的编码转换(默认 8 位字长)

先化为十六进制,再转换为二进制:(100)10 = (64)16 = (0110,0100)2

(1)原码:1,110,0100

(2)反码:1,001,1011

(3)补码:1,001,1100

(4)移码:0,001,1100

【例 2】(1,000,1101)2(默认 8 位字长),若为(1)原码;(2)反码;(3)补码;(4)移码,求对应真值?

(1)原码:1,000,1101 --> 转换为十六进制:1(-),000(0),1101(13) --> 转换为十进制:(-13)10

(2)反码:1,000,1101 --> 原码:1,111,0010 --> 转换为十六进制:1(-),111(7),0010(2) --> 转换为十进制:-(16*7+2)10 = (-114)10

(3)补码:1,000,1101 --> 原码:1,111,0011 --> 转换为十六进制:1(-),111(7),0011(3) --> 转换为十进制:-(16*7+3)10 = (-115)10

(4)移码:1,000,1101 --> 补码:0,000,1101 --> 转换为十六进制:0(+),000(0),1101(13) --> 转换为十进制:(+13)10

1.3 C 语言的强制转换

【例】16 位补码 0x8FA0 扩展为 32 位是 0xFFFF 8FA0。

【补充】C 语言数据类型:

【注】8 bit = 1 Byte

2 定点数的运算

2.1 定点数的移位

移位有三种:算术移位、逻辑移位、循环移位。

2.1.1 算术移位(有符号数)

【规则】

负数的原码数值部分与真值相同,因此移位时符号位不变,其余空位添 0

负数的反码数值部分与负数的原码相反,因此移位时其余空位添相反的数,即为 1

负数的原码转补码,从右往左(从低到高)找到第一个“1”,这个“1”的左边(符号位除外)与原码相反,故空位添相反的数,即为 1;右边与原码相同,故空位仍添 0

【例】负数补码的算术移位

算术右移 1 位:1,110,0110 >> 1 = 1,111,0011

算术右移 2 位:1,110,0110 >> 2 = 1,111,1001

算术左移 1 位:1,110,0110 << 1 = 1,100,1100

算术左移 2 位:1,110,0110 << 1 = 1,001,1000

2.1.2 逻辑移位(无符号数)

【规则】

2.1.3 循环移位

【规则】

【例】一个 8 位寄存器内的数值为 0100,1011,进位标志位 CF=1,若(1)带进位循环左移一位;(2)带进位循环右移一位;(3)不带进位循环左移一位;(4)不带进位循环右移一位,结果是多少?

【注】括号内的英文表示该数值位是从 CF、数值的高位(HIGH)还是数值的低位(LOW)移进来的。

(1)带进位循环左移一位:100,1011,1 (CF);CF = 0 (HIGH)

(2)带进位循环右移一位:1 (CF),0100,101;CF = 1 (LOW)

(3)不带进位循环左移一位:100,1011,0 (HIGH);CF = 0 (HIGH)

(4)不带进位循环右移一位:1 (LOW),0100,101;CF = 1 (LOW)

2.2 定点数的加减法

2.2.1 补码的加减法

【例】A = 15,B = 28,计算 [A+B],[A-B]

转换为二进制:A = (15)10 = (000,1111)2, B = (28)10 = (001,1100)2

[A]= 0,000,1111, [B]= 0,001,1100

[A]= 0,000,1111, [B]= 0,001,1100, [-B]= 1,110,0100

[A+B] = 0,000,1111 + 0,001,1100 = 0,010,1011 = (+43)10

[A-B] = 0,000,1111 + 1,110,0100 = 1,111,0011 = (-13)10

2.2.2 溢出的判别

发生溢出的情况:

【模 2 补码】有一个符号位的补码,即正常的补码。

【模 4 补码(变形补码)】有两个符号位 S1S2 的补码,“00”表示正数,“11”表示负数,如:

  • -3:补码:1,101;变形补码:11,101
  • +3:补码:0,011;变形补码:00,011

若两个符号位不同,“01”表示正溢出,“10”表示负溢出,最高位符号位表示真正的符号。

实际情况下,存储每个变形补码仅需一个符号位,因为无论正数还是负数,两个符号位都是一样的,只有在运算时才会出现不一样的情况。

2.3 定点数的乘除法

2.3.1 原码的乘法

设[X]=xs.x1x2...xn,[Y]=ys.y1y2...yn原码一位乘法 X*Y 的规则如下:

【例】x = -0.1101,y = 0.1011,进行原码一位乘法 x * y:

操作 通用寄存器(被乘数) ACC(高位部分积) MQ(低位部分积/乘数) MQ 丢失
初始状态,乘数 y=00.1011 00.1101 00.0000 1011
step1. 乘数最低位为 1,ACC 加 |X| 00.1101 00.1101 1011
step1. 部分积(和乘数)逻辑右移一位 00.1101 00.0110 1101 1
step2. 乘数最低位为 1,ACC 加 |X| 00.1101 01.0011 1101 1
step2. 部分积(和乘数)逻辑右移一位 00.1101 00.1001 1110 11
step3. 乘数最低位为 0,ACC 加 0 00.1101 00.1001 1110 11
step3. 部分积(和乘数)逻辑右移一位 00.1101 00.0100 1111 011
step4. 乘数最低位为 1,ACC 加 |X| 00.1101 01.0001 1111 011
step4. 部分积(和乘数)逻辑右移一位 00.1101 00.1000 1111 1011

符号位 = 1 ⊕ 0 = 1

x * y = -0.10001111

2.3.2 补码的乘法

设[X]=xs.x1x2...xn,[Y]=ys.y1y2...yn补码一位乘法 X*Y 的规则如下:

【例】x = -0.1101,y = 0.1011,进行补码一位乘法 x * y:

[x] = 11.0011,[-x] = 00.1101,[y] = 0.1011

操作 通用寄存器(被乘数) ACC(高位部分积) MQ(低位部分积/乘数) MQ(辅助位) MQ 丢失
初始状态,乘数 y=00.1011 11.0011 [负数: 00.1101] 00.0000 01011 0
step1. 乘数最低位和辅助位为 10,ACC 加 [-X] 11.0011 [负数: 00.1101] 00.1101 01011 0
step1. 部分积(和乘数)算术右移一位 11.0011 [负数: 00.1101] 00.0110 10101 1 0
step2. 乘数最低位和辅助位为 11,ACC 加 0 11.0011 [负数: 00.1101] 00.0110 10101 1 0
step2. 部分积(和乘数)算术右移一位 11.0011 [负数: 00.1101] 00.0011 01010 1 10
step3. 乘数最低位和辅助位为 01,ACC 加 [+X] 11.0011 [负数: 00.1101] 11.0110 01010 1 10
step3. 部分积(和乘数)算术右移一位 11.0011 [负数: 00.1101] 11.1011 00101 0 110
step4. 乘数最低位和辅助位为 10,ACC 加 [-X] 11.0011 [负数: 00.1101] 00.1000 00101 0 110
step4. 部分积(和乘数)算术右移一位 11.0011 [负数: 00.1101] 00.0100 00010 1 0110
step5. 乘数最低位和辅助位为 01,ACC 加 [+X] 11.0011 [负数: 00.1101] 11.0111 00010 1 0110

注:最后的 MQ = 00010 的最低位为原符号位,不用

[x * y] = 11.01110001,x * y = -0.10001111

2.3.3 原码的除法

设[X]=xs.x1x2...xn,[Y]=ys.y1y2...yn加减交替法(不恢复余数法)求 X/Y 的规则如下:

【例】x = 0.1011,y = 0.1101,利用加减交替法求 x / y:

|x| = 0.1011,|y| = 0.1101,[|y|] = 0.1101,[-|y|] = 1.0011

操作 通用寄存器(除数) MQ(被除数/部分余数) MQ(商)
初始状态:|x|=0.1011,|y|=0.1101 0.1101 [负数: 1.0011] 0.1011 0.0000
step0. |x|-|y| 0.1101 [负数: 1.0011] 1.1110 0.0000
step1. 部分余数为负,商 0 0.1101 [负数: 1.0011] 1.1110 0.0000
step1. 部分余数和商左移一位 0.1101 [负数: 1.0011] 1.1100 0.0000
step1. +|y| 0.1101 [负数: 1.0011] 0.1001 0.0000
step2. 部分余数为正,商 1 0.1101 [负数: 1.0011] 0.1001 0.0001
step2. 部分余数和商左移一位 0.1101 [负数: 1.0011] 1.0010 0.0010
step2. -|y| 0.1101 [负数: 1.0011] 0.0101 0.0010
step3. 部分余数为正,商 1 0.1101 [负数: 1.0011] 0.0101 0.0011
step3. 部分余数和商左移一位 0.1101 [负数: 1.0011] 0.1010 0.0110
step3. -|y| 0.1101 [负数: 1.0011] 1.1101 0.0110
step4. 部分余数为负,商 0 0.1101 [负数: 1.0011] 1.1101 0.0110
step4. 部分余数和商左移一位 0.1101 [负数: 1.0011] 1.1010 0.1100
step4. +|y| 0.1101 [负数: 1.0011] 0.0111 0.1100
step5. 部分余数为正,商 1 0.1101 [负数: 1.0011] 0.0111 0.1101
step6. 部分余数为正,不需要+|y| 0.1101 [负数: 1.0011] 0.0111 0.1101

x / y = +0.1101,余数 = 0.0111 * 2-4

2.3.4 补码的除法

设[X]=xs.x1x2...xn,[Y]=ys.y1y2...yn加减交替法求 X/Y 的规则如下:

【例】x = 0.1000,y = -0.1011,利用加减交替法求 x / y:

[x] = 00.1000,[x] = 00.1000

[y] = 11.1011,[y] = 11.0101,[-y] = 00.1011

操作 通用寄存器(除数) MQ(被除数/部分余数) MQ(商)
初始状态:x=00.1000,y=11.0101 11.0101 [负数: 00.1011] 00.1000 0.0000
step0. x、y 异号,+y 11.0101 [负数: 00.1011] 11.1101 0.0000
step1. 部分余数与 y 同号,商 1 11.0101 [负数: 00.1011] 11.1101 0.0001
step1. 部分余数和商左移一位 11.0101 [负数: 00.1011] 11.1010 0.0010
step1. 部分余数-y 11.0101 [负数: 00.1011] 00.0101 0.0010
step2. 部分余数与 y 异号,商 0 11.0101 [负数: 00.1011] 00.0101 0.0010
step2. 部分余数和商左移一位 11.0101 [负数: 00.1011] 00.1010 0.0100
step2. 部分余数+y 11.0101 [负数: 00.1011] 11.1111 0.0100
step3. 部分余数与 y 同号,商 1 11.0101 [负数: 00.1011] 11.1111 0.0101
step3. 部分余数和商左移一位 11.0101 [负数: 00.1011] 11.1110 0.1010
step3. 部分余数-y 11.0101 [负数: 00.1011] 00.1001 0.1010
step4. 部分余数与 y 异号,商 0 11.0101 [负数: 00.1011] 00.1001 0.1010
step4. 部分余数和商左移一位 11.0101 [负数: 00.1011] 01.0010 1.0100
step4. 部分余数+y(商末位恒置 1) 11.0101 [负数: 00.1011] 00.0111 1.0101

[x/y] = 1.0101,余数 = 0.0111 * 2-4

---EOF---

标签:编码,运算,--,补码,负数,定点数,0.1101,余数,原码
来源: https://www.cnblogs.com/Mount256/p/16582736.html