计算机中的数值表示,二进制,原码反码补码
- 在cpu 底层中,用高低电平表示1和0,通过逻辑门的组合可以 存储修改读取 该组合 电平状态即1和0,此为存储单元。
- 如何用1和0表示更多的数据信息,这就是二进制,引入位数表示更大的数字。
- 但是位数是有限的,而且不能尽量不能随意浪费。
- 计算机可以可以利用 异或门 和 与门 进行一位加法运算(半加器,全加器)
- 通过级联全加器实现多位加法,但延迟较高 行波进位加法器
- (延迟较高应该是电路更长,虽然逻辑简单,但是没有优化。通电进行一次)
- 因为电流也需要时间,完成一次加法,必须等电流通过所有电路, 这个时间应该就是时钟
- 通过并行计算进位优化性能,但硬件更复杂 超前进位加法器
- (硬件复杂应该是指逻辑复杂,需要更过不同的逻辑,及相应不同的硬件实现)
- 通过级联全加器实现多位加法,但延迟较高 行波进位加法器
- 如何实现减法
- 原码、补码、反码
- 计算机中用到减法,会用一位最高位表示正负号,其他位表示数值。
- 但是要透过概念看本质,首先原码、反码、补码的概念顺序要反过来,我们不是根据原码、反码进行运算,计算机中运算只用到补码!这个顺序很重要。
- 本质的运算是模运算和溢出的概念
-
一个4位二进制,它的模数是2^4 = 16, 但是我们用它表示的数字是-7~7。这是我们定的概念。
-
补码的设计基于模运算。对于一个 n 位的二进制系统,模数是 2^(n)。补码的本质是:
-
一个负数 −B的补码实际上是 2^n - B。
-
因此,A−B可以表示为 A + 2^n - B = 2^n + (A - B)
由于计算机的位数是固定的,超出 n 位的部分会被丢弃(溢出),所以结果就是 A−B,如果结果没有超出,结果也是正确的。
- 因为没有超出的话,说明结果A-B的结果为负数, 这个时候结果仍然是补码,也是正确的(计算机运算中不存在反码原码!反码原码只是为了容易理解)。
-
-
例子
4位 = 2^4 = 16 3位数值表示(-8^8) + 1位符号位 6-2 = 4 6+(-2) 原码:0110(6) 1010(10) 反码:0110(6) 1101(13) 补码:0110(6) 1110(14) 10100(20) 20 -16=4 6-7 = -1 6+(-7) 原码:0110(6) 1111(15) 反码:0110(6) 1000(8) 补码:0110(6) 1001(9) 1111(15) =4 6-7+2 1111 + 0010(2) = 10001 = 1 其实计算机中只有补码,用补码进行运算! 这里可以看到,我们其实是用14 表示 -2, 用9 表示-7, 用15表示-1
-
- 计算中小数的表示,进制问题
-
不同进制的真值其实是每一位的数值剩余该位权重 累加,记住10进制 也只是一种进制表示方法而已,明白数量的真实含义
二进制 1 111 1*2^3 + 1*2^2 + 1*2^1 + 1*2^0 = 15 为什么要1*2^3 因为在这个数之前已经有1*2^3 - 1 个数 即从000-111(0-7) 这个位置的权重就为2^3(8) 十进制 1 111 1*10^3 + 1*10^2 + 1*10^1 + 1*10^0 十六进制 1 111 1*16^3 + 1*16^2 + 1*16^1 + 1*16^0
-
整数十进制转二进制
- 模二除法
1111(10) 1111/2=555 余 1 555/2 =277 余 1 277/2 =138 余 1 138/2 =69 余 0 69/2 =34 余 1 34/2 =17 余 0 17/2 =8 余 1 8/2 =4 余 0 4/2 =2 余 0 2/2 =1 余 0 1/2 =0 余 1 直到商为0 结果为余数倒数排列100 0101 0111 为什么? 按除以2 的次数,得到每位上的结果 验证 1*2^10 + 1*2^6 + 1*2^4 + 1*2^2 + 1*2^1 + 1*2^0 = 1024 + 64 + 16 + 4 + 2 + 1 = 1111
- 小数使用 乘二取整
小数点每一位的权重是2^(-n) 0.1(2) = 0.5(10) 0.01(2) = 0.25(10) 0.001(2) = 0.125(10) 0.001(2) = 0.0625(10) 0.611(10) 0.611*2 = 1.222 取 1 0.222*2 = 0.444 取 0 0.444*2 = 0.888 取 0 0.888*2 = 1.776 取 1 0.776*2 = 1.552 取 1 0.552*2 = 1.104 取 1 0.104*2 = 0.208 取 0 0.208*2 = 0.416 取 0 ... 结果:0.10011100... 因为二进制小数每位的权重可以预料到会有精度问题,而且很多数对于二进制来说就是无理数或者无限循环小数(十进制特殊处?为何十进制为主流) 并且n 位十进制 转成二进制 通常位数有 5^n 位以上(除非正好是2的-n 相加的结果),结果才较准确 验算结果 1*2^(-1) + 1*2^(-4) + 1*2^(-5) + 1*2^(-6) = 0.5 + 0.0625 + 0.03125 + 0.015625 = 0.609375 其他例子 0.1(10) = 0.000110011 (第二位开始 0011 循环) 乘2 也可以看成是 除以0.5 它其实是为了确定每一位二进制位上的系数是1 还是 0(这是一种方法去确定每位的系数,你也可以用更复杂的基准,不为1,甚至是从右特定位往左计算) 为什么不和整数一样除以2,是因为我们要转的数是小数,所有的小数都没有2,小数乘二取整基准是第一位小数位2^-1, 我们确定的方向是从左到右,通过是否大于1判断系数,而整数位我们基准是2,从右往左,通过余数确定 每位系数。 而且说到底,这只是一种方法,我们能用这种方法简便的去确定每位的系数。
- 模二除法
-
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix