二进制的加减运算

二进制

整数

  • 十进制数转二进制数:除二取余倒记法
  • 二进制数转十进制数:按权相加法

比如计算 13 的二进制数:

ini 复制代码
13 / 2 = 6 ... 1
6 / 2 = 3  ... 0
3 / 2 = 1  ... 1
1 / 2 = 0  ... 1

所以得到的结果为 1101

1101 转换为十进制数:

ini 复制代码
1 * 2^3 + 1 * 2^2 + 0 * 2^1 + 1 * 2^0 = 13

小数

小数的二进制数转换也是一样的,只不过是除以 2 变成乘以 2,然后是正记法

比如计算 0.78125 的二进制数:

ini 复制代码
0.78125 * 2 = 1.5625 ... 1
0.5625 * 2 = 1.125   ... 1
0.125 * 2 = 0.25     ... 0
0.25 * 2 = 0.5       ... 0
0.5 * 2 = 1          ... 1

所以得到的结果为 0.11001

0.11001 转换为十进制数:

ini 复制代码
1 * 2^-1 + 1 * 2^-2 + 0 * 2^-3 + 0 * 2^-4 + 1 * 2^-5 = 0.78125

原码

原码是有符号数的一种表示方法,第一位是符号位,0 表示正数,1 表示负数

补码

正数的补码等于原码

负数的补码有两种计算方法:

  • 符号位不变,原码的反码 + 1
    • 比如十进制数 -21
      • 原码:10010101
      • 反码:11101010
      • 补码:11101011
  • 2^(n+1) + x
    • 十进制数 -21
      • 2^8 - 21
      • 2^8 的二进制:10000000
      • 21 的二进制:10010101
      • 得到补码:11101011

小数的补码算法和整数的补码一样:

  • 正数的补码等于原码
  • 负数的补码等于原码的反码 + 1

反码

反码有一个作用就是把减法转换为加法

正数的反码等于原码,负数的反码等于原码的符号位不变,其他位取反

上面计算原码的补码的时 2^(n+1) + x,这种方案 x 是负数的话,就会变成减法运算,而减法运算在计算机中是比较复杂的

所以使用反码就可以消除运算中的减法运算

定点数和浮点数

定点数

小数点固定在某个位置的数称为定点数

小数位在符号位之后,称为定点小数

小数位在数值位之后,称为定点整数

浮点数

如果这个数值比较大,会超过定点数的表示范围,这时候就需要使用浮点数

浮点数的表示方法是科学计数法,分为四部分:

  • 阶码符号位
  • 阶码
  • 尾数符号位
  • 尾数(尾数是补码,必须是纯小数,最高位必须是 1

比如:0.110101 * 2^6,小数点前面是符号位,小数点后面是尾数

2 个字节来表示浮点数

  • 阶码符号位:占用 1
  • 阶码:占用 4
  • 尾数符号位:占用 1
  • 尾数:占用 10

正数

小数 0.1015625 转换成二进制数

ini 复制代码
0.1015625 * 2 = 0.203125 ... 0
0.203125 * 2 = 0.40625   ... 0
0.40625 * 2 = 0.8125     ... 0
0.8125 * 2 = 1.625       ... 1
0.625 * 2 = 1.25         ... 1
0.25 * 2 = 0.5           ... 0
0.5 * 2 = 1              ... 1

得到的结果为 0.0001101

0.0001101 规格化:

0.1101000000 * 2^-3

正数的补码还是原码

阶码符号位 阶码 尾数符号位 尾数
1 0011 0 1101000000

负数

整数 -54 转换成二进制数

ini 复制代码
54 / 2 = 27 ... 0
27 / 2 = 13 ... 1
13 / 2 = 6  ... 1
6 / 2 = 3   ... 0
3 / 2 = 1   ... 1
1 / 2 = 0   ... 1

得到的结果是:-110110,用 1 表示负数 1,110110

1,110110 规格化:

1.1101100000 * 2^6

负数的补码是原码的反码+1

所以 1.1101100000 * 2^6 转换成补码是 1.0010100000 * 2^6

阶码符号位 阶码 尾数符号位 尾数
0 0110 1 0010100000

表示范围

假设阶码有 n 位,尾数有 m

  • 阶码的范围 -(2^n - 1) ~ 2^n - 1
  • 尾数的范围
    • 负数 -(1 - 2^-m) ~ -(2^-m)
    • 正数 2^-m ~ 1 - 2^-m
上溢 负数最小值 负数最大值 下溢 下溢 下溢 正数最小值 正数最大值 上溢
- -(1 - 2^-m) * 2^(2^n - 1) -(2^-m) * 2^-(2^n - 1) - 0 - (2^-m) * 2^-(2^n - 1) (1 - 2^-m) * 2^(2^n - 1) -

定点数加减法运算

定点数加法运算用补码运算,如果符号位发生进位,则丢弃符号位

单符号位如果符号位发生进位了,不知道有没有发生溢出,所以就有了双符号位,如果双符号在计算后不相同,就说明有溢出

整数加法

例如:A 的值为 -110010B 的值为 001101,求 A + B

  • A-110010 补齐符号位 1,110010,它的补码是 1,001110
  • B001101 补齐符号位 0,001101,它的补码是 0,001101

A + B => A 的补码 + B 的补码 1,001110 + 0,001101 => 1,011011

这个 1,011011 是补码,转换成原码就是 1,100101

验证一下 A 的十进制数是 -50B 的十进制数是 13A + B 的结果是 -37

1,100101 转换成十进制数是 -37

所以 A + B = 1,011011

小数加法

例如:A 的值为 -0.1010010B 的值为 0.0110100,求 A + B

  • A-0.1010010 补齐符号位 1,0.1010010,它的补码是 1,1.0101110
  • B0.0110100 补齐符号位 0,0.0110100,它的补码是 0,0.0110100

A + B => A 的补码 + B 的补码 1,1.0101110 + 0,0.0110100 => 1,1.1100010

这个 1,1.1100010 是补码,转换成原码就是 1,0.0011110

验证一下 A 的十进制数是 -0.640625B 的十进制数是 0.40625A + B 的结果是 -0.234375

1,0.0011110 转换成十进制数是 -0.234375

所以 A + B = 1,1.1100010

双符号位有溢出

例如:A 的值为 -10010000B 的值为 -11010000,求 A + B

  • A-10010000 补齐符号位 11,10010000,它的补码是 11,01110000
  • B-11010000 补齐符号位 11,11010000,它的补码是 11,00110000

A + B => A 的补码 + B 的补码 11,01110000 + 11,00110000 => 110,10100000

符号位最高位的 1 舍弃,剩下 10,符号位最高位不同,说明 A + B 发生了溢出

减法运算

减法运算,要转换成加法运算,所以减数的补码**取反(包括符号位)加 1**就能变成加法运算

换句话说,减数的补码 = 减数的原码 + 减数的符号位取反

例如 A 的值为 11001000B 的值为 -00110100,求 A - B

  • A11001000 补齐符号位 00,11001000,它的补码是 00,11001000
  • B-00110100 补齐符号位 11,00110100,它的补码是 11,11001100
    • B 的补码取反(包括符号位)加 1,得到 00,00110100

A - B => A 的补码 + -B 的补码 00,11001000 + 00,00110100 => 00,11111100

这个 00,11111100 是补码,转换成原码就是 00,11111100

验证一下 A 的十进制数是 200B 的十进制数是 -52A - B 的结果是 252

00,11111100 转换成十进制数是 252

浮点数加减法

浮点数加减法要分为 5 个步骤:

  1. 对阶
  2. 尾数求和
  3. 尾数规格化
  4. 舍入
  5. 溢出判断
阶码符号位 阶码 尾数符号位 尾数
A 0.1101 * 2^1 00 01 00 1101
B -0.1010 * 2^3 00 11 11 1010

加码+1,尾数右移,阶码-1,尾数左移

对阶

对阶的目的是使得两个浮点数阶码一致,从而使得尾数可以进行运算

因为浮点数的小数位与阶码有关,如果阶码不整齐,就无法进行运算

对阶操作:小阶对齐大阶

  • A 的阶码是 1,对应的二进制数是 01
  • B 的阶码是 3,对应的二进制数是 11

A 的阶码需要变成 11,所以 A 的尾数需要右移 2 位,变为 0.0011

阶码符号位 阶码 尾数符号位 尾数
A 0.1101 * 2^1 00 11 00 0011(01)
B -0.1010 * 2^3 00 11 11 1010

由于这里只有 4 位,所以 A 的尾数右移后 01 需要被舍弃

尾数求和

尾数求和的方法和定点数的加减法一致

A + B 的结果是 11,1011 记为 S,这里的 S 是补码

阶码符号位 阶码 尾数符号位 尾数
S 00 11 11 1001

尾数规格化

尾数规格化分两种情况

  • 如果 S > 0,需满足 00.1xxxxx
  • 如果 S < 0,需满足 11.0xxxxx

如果不满足条件需要小数部分需要进行左移,同时阶码需要发生变化

阶码符号位 阶码 尾数符号位 尾数
S 00 10 11 (1)0010

S 的的尾数是 11.0010,原码 11.1110,所以 A + B 的值是-0.1110

尾数规格化(右移)

尾数规格化,一般都是左移,只有在双符号位不一致的情况下,才进行右移

右移的话需要进行舍入操作,在二进制中的舍入是 01 入法

例如:

  • 10.10110111 右移一位,符号位补 111.01011011(1),阶码需要 +1
    • 如果是 10,右移符号位补 1,小数位补 0
    • 如果是 01,右移符号位补 0,小数位补 1
  • 由于舍弃的是 1,所以还需要 +1,得到的结果是 11.01011100

01 入可能会有溢出

溢出判断

在浮点数中判断溢出:在规格化后判断阶码的符号位是否一致,如果一致就没有溢出,如果不一致就溢出了

相关推荐
YY_D_S_5 天前
【机组】概述精炼考点(冯诺依曼、层次结构、翻译语言、执行程序的过程、基本工作原理、运算器、控制器、存储器)
计算机组成原理·机组
superiony8 天前
【计算机组成原理】实验二:通用寄存器单元实验
计算机组成原理·通用寄存器
青春pig头少年14 天前
《计算机组成原理》(408大题)
学习笔记·408·计算机组成原理
moonless022214 天前
【GISer精英计划_00】从二进制到协议、到计算机通信、到服务器
网络协议·gis·计算机组成原理
运维小文16 天前
linux的磁盘管理
linux·运维·网络·磁盘·计算机组成原理·硬件
shengjk11 个月前
从零开发操作系统-聊一下GDT 和 IDT
人工智能·后端·计算机组成原理
小新_-1 个月前
第五章:指令系统
计算机组成原理
啊呦.超能力2 个月前
计算机硬件的工作原理
计算机组成原理
旅僧3 个月前
多处理器基本概念(SISD、SIMD、MISD、MIMD)--自用
计算机组成原理
dulu~dulu3 个月前
数据冒险与控制冒险
java·开发语言·计算机组成原理