计算机基础三: 二进制减法实现[通俗易懂]

计算机基础三: 二进制减法实现[通俗易懂]在上一章中了解了如何实现二进制加法,加法是始终从两个加数的最右列向左列进位计算的,而在减法中没有进位,只有借位.253-176=77上面的式子我们不难算出来,但习惯性的思维让我们用借位的方式求值.在不借位的情况下如何实现计算?借位是很麻烦的事情,虽然我们能够实现它,但这意味着额外的开销.我们将用一个小技巧,让我们避开借位从而实现减法.为了避免借位,我们先从百位最大值999中减去减数,而非从原来的被减数中减去减数.999-176=823这个方法称为对9求补

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

在上一章中了解了如何实现二进制加法, 加法是始终从两个加数的最右列向左列进位计算的, 而在减法中没有进位, 只有借位.

253 - 176 = 77

上面的式子我们不难算出来, 但习惯性的思维让我们用借位的方式求值. 在不借位的情况下如何实现计算?

借位是很麻烦的事情, 虽然我们能够实现它, 但这意味着额外的开销. 我们将用一个小技巧, 让我们避开借位从而实现减法.

为了避免借位, 我们先从百位最大值999中减去减数, 而非从原来的被减数中减去减数.

999 - 176 = 823

这个方法称为对9求补数. 176对9的补数是823; 反过来说823对9的补数是176. 这样一来, 不管减数是多少, 我们都不需要进行借位操作.

计算出对9的补数后, 将补数与原来的被减数相加:

253 + 823 = 1076

最后将结果加上1, 并减去1000

1076 + 1 - 1000 = 77

用代数思想代入一下, 就能知道为什么这样了, 这里就不再阐述. 我们再看另一个问题.

如果简述大于被减数, 也就是值为负数该怎么计算.

176 - 253 = -77

这与先前有些不同, 我们先用999减去253, 求出9的补数; 然后把9的补数和被减数相加

999 - 253 = 746
746 + 176 = 922

接着我们这里直接减去999, 但会出现借位, 并不符合需求. 将减数和被减数交换, 值取负数即可.

999 - 922 = -77

到此为止, 我们已经解决了十进制不借位做减法运算. 接下来让我们应用到二进制中.

(1111-1101) - (1011-0000) = ?

在十进制减法中, 我们需要用到9的补数, 同理, 二进制中我们需要用到1的补数. 而1的补数并不需要多复杂, 只需要将1取0, 0取1即可; 这也就是我们经常讲的反码.

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.

利用这种机制我们将正负数自由的相加, 而不用用到减法. 但并不是完美, 这里我们约定的范围时一字节, 但两数相加超过一字节所能表示的范围时, 就会产生溢出. 也就是第九位数被舍弃了, 一般而言, 如果两个操作数的符号相同, 而结果与之不同, 这样的加法就发生了溢出, 属于无效.

现在单纯的一串二进制数值就有两种不同的使用方式了: 有符号, 无符号. 所以当你读取一段二进制时, 你得知道它有无符号才能知道对应的十进制数值; 同样的, 在编程的时候也应该使用关键字声明, 虽然很多编译器都自动认为省略就是无符号数, 但这是一个良好的习惯.

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/189943.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • eclipse中配置jdk

    eclipse中配置jdkwindow->preference->java->installjres->add->standardvm->设置好相应的jrehomeeclipse的实验版本:Version:4.3.0.v20130605-20001、点击eclipse菜单栏的window下拉菜单选中preference2、点击…

    2022年6月16日
    26
  • Django(55)GenericAPIView源码分析

    Django(55)GenericAPIView源码分析源码分析GenericAPIView继承自APIView,也就是在APIView基础上再做了一层封装,源码如下:classGenericAPIView(views.APIView):query

    2022年7月30日
    5
  • group by详解

    group by详解一. 概述group_by的意思是根据by对数据按照哪个字段进行分组,或者是哪几个字段进行分组。二. 语法select 字段  from 表名 where  条件  group by    字段或者select 字段  from 表名 group by  字段  having  过滤条件注意:对于过滤条…

    2022年5月26日
    51
  • openEuler安装_Java源代码会被编译成

    openEuler安装_Java源代码会被编译成openEulerLinux源代码编译安装Nginx升级系统和软件yum-yupdate关闭防火墙systemctlstopfirewalldsystemctldisablefirewalld编辑/etc/selinux/config#SELINUX=enforcing修改为SELINUX=disabled#或者执行sed-i’s/SELINUX=enforcing/SELINUX=disabled/g’/etc/selinux/config保

    2022年9月28日
    3
  • linux里chmod_vim命令下一页

    linux里chmod_vim命令下一页linux中chmod命令的使用方法发布时间:2020-06-2417:05:24来源:亿速云阅读:79作者:元一这篇文章运用简单易懂的例子给大家介绍linux中chmod命令的使用方法,代码非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。chmod介绍:linux中可以使用命令chmod来为文件或目录赋予权限。Linux/Unix的档案存取权限分为三级:档案拥有者、群组、其…

    2025年7月24日
    2
  • Opengles2.0入门「建议收藏」

    Opengles2.0入门「建议收藏」一二三四Opengles2.0渲染管线简单画图步骤着色器语言简单介绍镜像技术一OpenGLES2.0渲染管线1.基本处理初始化3D空间中物体的顶点坐标,顶点对应的颜色,顶点的纹

    2022年7月1日
    27

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号