大家好,又见面了,我是你们的朋友全栈君。
在上一章中了解了如何实现二进制加法, 加法是始终从两个加数的最右列向左列进位计算的, 而在减法中没有进位, 只有借位.
代码语言:javascript复制253 - 176 = 77
上面的式子我们不难算出来, 但习惯性的思维让我们用借位的方式求值. 在不借位的情况下如何实现计算?
借位是很麻烦的事情, 虽然我们能够实现它, 但这意味着额外的开销. 我们将用一个小技巧, 让我们避开借位从而实现减法.
为了避免借位, 我们先从百位最大值999中减去减数, 而非从原来的被减数中减去减数.
代码语言:javascript复制999 - 176 = 823
这个方法称为对9求补数. 176对9的补数是823; 反过来说823对9的补数是176. 这样一来, 不管减数是多少, 我们都不需要进行借位操作.
计算出对9的补数后, 将补数与原来的被减数相加:
代码语言:javascript复制253 823 = 1076
最后将结果加上1, 并减去1000
代码语言:javascript复制1076 1 - 1000 = 77
用代数思想代入一下, 就能知道为什么这样了, 这里就不再阐述. 我们再看另一个问题.
如果简述大于被减数, 也就是值为负数该怎么计算.
代码语言:javascript复制176 - 253 = -77
这与先前有些不同, 我们先用999减去253, 求出9的补数; 然后把9的补数和被减数相加
代码语言:javascript复制999 - 253 = 746
746 176 = 922
接着我们这里直接减去999, 但会出现借位, 并不符合需求. 将减数和被减数交换, 值取负数即可.
代码语言:javascript复制999 - 922 = -77
到此为止, 我们已经解决了十进制不借位做减法运算. 接下来让我们应用到二进制中.
代码语言:javascript复制(1111-1101) - (1011-0000) = ?
在十进制减法中, 我们需要用到9的补数, 同理, 二进制中我们需要用到1的补数. 而1的补数并不需要多复杂, 只需要将1取0, 0取1即可; 这也就是我们经常讲的反码.
代码语言:javascript复制1. 用8位二进制最大值1111-1111减去减数
(1111-1111) - (1011-0000) = 0100-1111
2. 将减数的反码与被减数相加
(1111-1101) (0100-1111) = 1-0100-1100
3. 将上式所得结果加1
1-0100-1101
4. 减去1-0000-0000
(1-0100-1101) - (1-0000-0000) = 0100-1101
在这里我们先中断一下, 先了解二进制如何表示负数, 再来了解减数大于被减数的减法运算.
在十进制中, 我们使用 – 号来表示数值的正负, 但二进制中我们不可能加符号, 因为仅有01两个数字.
当然我们可以取一位二进制位当做正负值, 但这带来的后果就是数值表示范围的缩小, 这不符合让它做更多的计算机思维. 在计算机科学中, 抽象的概念非常重要, 贯穿了整个计算机发展史, 现在让我们提升一层抽象.
在数轴上, 所有的数都是以0为中心, 对称无限延长. 但如果我们事先约定好大小, 那所有的整数都是已知的. 现在让我们将这个数轴头尾相连形成一个循环.
上图中内圈为实际数值, 而外圈则是表示数值. 我们可以看到最小的负数-10看起来像是10的衍生, 而最大的负数-1则表示为20.
在二进制中, 一字节所能表示的正整数为(0 ~ 255), 如果想要表示有符号整数, 则一字节取值范围为(-128 ~ 127). 最高有效位表示符号, 1为负0为正. 计算机又能充分利用8位所能表示的所有数值.
例如无符号整数125二进制表示位0111-1101, 为了表示-125, 我们需要先求125的补数1000-0010, 再加1, 得到1000-0011. 这就是有符号整数-125的二进制表示. 同样的步骤, 每位取反再加1, 就可以还原成无符号整型125.
利用这种机制我们将正负数自由的相加, 而不用用到减法. 但并不是完美, 这里我们约定的范围时一字节, 但两数相加超过一字节所能表示的范围时, 就会产生溢出. 也就是第九位数被舍弃了, 一般而言, 如果两个操作数的符号相同, 而结果与之不同, 这样的加法就发生了溢出, 属于无效.
现在单纯的一串二进制数值就有两种不同的使用方式了: 有符号, 无符号. 所以当你读取一段二进制时, 你得知道它有无符号才能知道对应的十进制数值; 同样的, 在编程的时候也应该使用关键字声明, 虽然很多编译器都自动认为省略就是无符号数, 但这是一个良好的习惯.
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。