反补码运算之 “1 - 1 = - 1 ” ?

news2025/1/12 1:02:08

我们在研究数据的二进制表示时遇到这样一个问题:

由于计算中的CPU只有加法器,没有减法器,所以在计算机采用原码做减法时对于:1 - 1 = 0 相当于1 + (-1),用二进制表示为:0001+1001=1001。而1001是二进制的 -1。这明显是不对的,但是计算机又是出入处理的呢?

        计算机在处理减法的时候,引入了补码这一概念。许多人接触补码,仅是被告知是“正数不变,负数取反加一”,而对于为什么需要这么做,以及补码本身的存在意义并不清楚。而网上关于补码的解释比较散,故在此写一篇文章记录,希望其他人少走弯路。这篇文章的目的,则是从补码被发明的缘由说起,从根源上:

        1)彻底梳理补码形成的过程,说明补码需要解决的问题
        2)归纳补码的实质
        3)解释补码用于数学运算的正确性
        4)解释求补码(负数除符号位以外,按位取反加一)这一操作的可靠性
        5)推导补码加减法的运算公式

一、摈弃错误观念

        如果你对补码有以下误解,请从现在起忘记这些错误观点的存在:
                1)补码是让正数变负数,负数变正数
                2)补码是原码数与模互补的数

        除了上面的错误观点以外,下面还有几点需要提醒,以免先入为主:

                1)不要把补码与“对模求补”的操作直接关联,只需要把补码看成一种全新构造的二进制编码,不需要过度关注补字
                2)补码的最高位是符号位,但它不是无依据地定义的,后面会解释补码最高位可以代表正负的原因


一、补码的形成

        在计算机的硬件结构中,实现加法器比实现减法器简单的多。人们希望的是构造出一套 “用加法代替减法” 的运算逻辑,构造的结果也就是现在我们所使用的“补码”。

最初的探索
        缘起于日常生活的现象,时钟的顺拨与倒拨均可以达到同一钟点。十二小时制中,分针由8点拨到6点,有两种方式:
        1)逆时针拨2小时:8-2=6时
        2)顺时针拨10小时:8+10=6时

        第二种方式本来应该为18时,但由于时钟是十二小时制计时,产生了溢出,显示的是18-12=6时。而这种形式,则是用加法代替了第一种形式的减法,这正是我们想要的,于是对于“以加代减”的逻辑,有了最初的构造:

        时钟超出显示上限,则只显示余下的钟点,这恰好是模数加法运算的体现:在模12的情况下(或者说对12取余),以下式子是等价的:

(8−2)mod12=(8+10)mod12=6

        按照这个思路,我们在模范围内,也许可以将“X-Y”的减法变更为“X+Y的补数”的加法。

注:所谓m的补数就是:(模-m)的值,如2的补数是12-2=10

二、模数加法的局限

        模数加法代替减法是一个很好的思路,但它并不是完美的。上面提及到的情况,事实上只是 “大减小” 的情况,如果出现 “小减大” 情况就出现矛盾了:
举个例子:
        在模100的情况下,套用上面的模数加法公式企图代替减法:

(10−30)mod100=−20
( 10 + ( 100 − 30 ) ) mod100 = 80

        这和说好的不一样啊,80显然不等于-20,而且也没有因为超越模数而引起取余运算。然而先贤们并不打算前功尽弃……


三、负数的表示法

        他们为了继续使用模数加法代替减法,他们做了一个大胆而又粗暴的定义:让80等于-20,即用80代表-20

根据这个规律,推广到一般的情况就是:

负数的表示方式就是它绝对值的补数——规则①

这样做有两个好处:

        1)消除了“小减大”情况下的歧义,使得该情况也可用模数加法代替减法。
        2)此定义同样可以解释“大减小”的情况,因为它同样吻合 将“X-Y”的减法变更为“X+Y的补数” 的说法(视 -Y 作负数,则它的表示为Y的补数)。

        这样做后,无论是“大减小”或是“小减大”,模数加法代替减法都已可适用,可以说已经形成了一套较为通用的以加代减体系。

该负数表示法的结果与缺点
        但是注意到,像80这样的大数,失去了自己的意义,在模100的情况下,无法再表示80了。更一般地,因为我们希望正负数尽量成对出现,而且打算用正数表示负数,这意味着在模100的非负数之间,需要划分一半正数用于表示负数,结合规则①的负数表示方式,最终满足这一系列条件的结果是:
        在模100条件下:0 ~ 49表示正数本身; 50 ~ 99表示各自补数的负值(如98代表-2)

        更一般地:模n情况下,0 ~ n/2 -1表示本身,n/2 ~ n-1表示各自补数的负值——规则②


四、补码的实质

        所谓补码,其实只是:非负数和规则①表示的负数,在二进制形式下的表示
        所以虽然补码叫补码,但事实上它的本质和补字没有直接关联,它只是一种为了实现模数加法代替减法而构造出来的数字映射罢了。

        补码并非在二进制中才有用,根据上面的定义,无论任何进制都不会改变补码体系的准确性。二进制与其它进制,影响只是求补码的简便方式(下面会提及)

补码最高位为符号位的解释
       &nbsp补码在二进制中的最高位为符号位,其实是因为规则②中,把半模以上的数用作表示负数,而恰好半模以上的数,在二进制表示中的最高位就是1,半模以下最高位是0。

在这里插入图片描述

       &nbsp因此,从数字映射来讲,半模以上的正数确实被规则①映射为了负数;但是单论二进制数字而言,最高位的1仅代表它是半模以上的数,脱离了规则①它与正负符号没有任何关系。

       &nbsp总之,尽管在补码中,最高位确实可以简单地看做正负标志,但是需要注意的是,这种做法事实上有迹可循,千万不要想当然地以为这只是一种毫无根据的硬性规定


五、原码到负数补码的转换

按位取反加一
上面基本讲解了补码的意义与本质,现在剩下的问题就是在二进制中:原码负数如何求补码?
我们总不能按规则①,依靠十进制定义来求负数表示,再转换成二进制吧?
我们希望的是找到一种原码直接转换成补码的形式

也就是我们喜闻乐见的“除符号位以外,按位取反加一”

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/153929.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

儿童感染新冠病毒后发高烧如何应对?专家来支招

儿童感染新冠病毒后发热较多,但肺炎发展较少儿童感染新冠病毒后发高烧,是重症吗?徐红梅:从目前的接待情况来看,儿童感染新冠病毒后比成人发烧。超过一半的儿童在感染后有发烧症状,伴有咳嗽、鼻塞、流鼻涕、…

JavaWeb的一些学习总结

Web系统就是:前端负责貌美如花,后端负责坚如磐石 企业在做Web系统时,成本与收益的对比是不可忽视的,企业做项目一定是要盈利的! 企业做项目最求的不是技术的新和潮,追求的是低成本和稳还有好用度&#xff…

函数的设计

一、默认参数 C允许在函数定义或声明时,为形参指定默认值,即默认参数(default argument)。 (1)函数定义与函数声明只能设置一次默认参数。 (2)可以设置多个默认参数,设…

【精华】搞定JVM调优学习

JVM 介绍 1. 什么是 JVM JVM 是 Java Virtual Machine(Java 虚拟机)的缩写。一台执行 Java 程序的机器。 2 .JAVA 语言的执行原理 计算机语言: 计算机能够直接执行的指令。这种指令和系统及硬件有关。 计算机高级语言: 在遵循…

「数据」驱动行业拐点,毫末智行冲刺自动驾驶3.0时代

“毫末预计,到2025年中国高阶辅助驾驶搭载率将达到70%。而在汽车新消费领域,中国汽车市场增换购消费比例将达到60%,智能驾驶功能成为必选因素,并迎来商业化的加速发展。”1月5日,第七届HAOMO AI DAY上,毫末…

黑马学ElasticSearch(五)

目录: (1)DSL查询语法-DSL查询分类和基本语法 (2)DSL查询语法-全文检索查询 (3)DSL查询语法-精确查询 (4)DSL查询语法-地理查询 (5)DSL查询语…

计算机网络(一)

计算机网络1 概述1.1 计算机网络的作用1.2 因特网概述1.2.1 网络的网络1.2.2 Internet和internet的区别1.2.3 因特网发展的三个阶段1.2.4 ISP介绍1.2.5 ISP分类1.2.5.1 主干ISP1.2.5.2 地区ISP1.2.5.3 本地ISP1.2.6 因特网交换点 IXP1.3 因特网的组成1.3.1 因特网的边缘部分1.3…

资产管理4大难点,如何破解?

随着企业业务扩大、人员增多,固定资产的数量和种类也会随着增加。此时,如何高效管理企业资产就成为很多企业亟待解决的一大难题。 传统资产管理4大难点 01.资产管理部门需要联系采购部门、使用部门、财务部门等收集数据,汇总难且工作量大&…

vacuum移除不必要的CLOG文件

迫切模式弥补了惰性模式的缺陷。它会扫描所有页面&#xff0c;检查表中的所有元组&#xff0c;更新相关的系统视图&#xff0c;并在可能时删除不必要的CLOG文件与页面。当满足以下条件时&#xff0c;会执行迫切模式。pg_database.datfrozenxid<(OldestXmin-vacuum_freeze_ta…

【多线程】【C++ 知识点】pthread_join学习

目录pthread_join进程id和线程idpthread_join pthread_join() 主线程会进入阻塞装题&#xff0c;pthread_join()之后的代码&#xff0c;只有等待子进程退出之后才能执行。 代码块A pthread_create(&id, NULL, Fn, NULL);pthread_create(&id_1, NULL, Fn, NULL);pthre…

jdk1.8 更替为 oepnJdk8遇到的坑

背景&#xff1a;客户服务器因为说jdk要收费&#xff0c;所以要求将jdk1.8替换为openJdk&#xff0c;本地测试ok&#xff0c;则将服务器的jdk替换为openJdk8&#xff0c;出现一个登录异常&#xff0c;调查发现是一个sso登录的问题&#xff08;单点登录&#xff09;&#xff0c;…

Rhce第一次作业

chrony服务部署&#xff1a;两台机器a: 第一台机器从阿里云同步时间&#xff0c;第二台机器从第一台机器同步时间1.查看防火墙是否关闭&#xff0c;若未关闭&#xff0c;关闭防火墙2.打开chrony配置文件3.向配置文件中写入阿里云时间服务器&#xff0c;并允许两台机器所在的网段…

从0到1完成一个Vue后台管理项目(十八、基础地图绘制)

往期 从0到1完成一个Vue后台管理项目&#xff08;一、创建项目&#xff09; 从0到1完成一个Vue后台管理项目&#xff08;二、使用element-ui&#xff09; 从0到1完成一个Vue后台管理项目&#xff08;三、使用SCSS/LESS&#xff0c;安装图标库&#xff09; 从0到1完成一个Vu…

spring restTemplate的坑----会对String类型的url中的特殊字符进行转义

&#x1f4e2; &#x1f4e2; &#x1f4e2; &#x1f4e3; &#x1f4e3; &#x1f4e3;哈喽&#xff01;大家好&#xff0c;我是「奇点」&#xff0c;江湖人称 singularity。刚工作几年&#xff0c;想和大家一同进步 &#x1f91d; &#x1f91d;一位上进心十足的【Java ToB端…

基于OpenCV实现两种方法测量圆弧长度(步骤 + 源码)

导 读 本文主要介绍基于OpenCV实现两种方法测量圆弧长度(步骤 + 源码)。 背景介绍 要求:如上所示,分别用OpenCV计算出图1和图2中圆弧的长度。因为OpenCV中没有提供现成计算圆弧的方法,所以需要自己编写,本文将提供2种不同的方法来实现,仅供参考。 实现步骤 首…

mmsegmentation 训练Binary segmentation

1.一天最无聊的事从搭环境开始 1.conda create -n swin python3.7 2.conda activate swin 3.conda install pytorch1.7.0 torchvision0.8.0 torchaudio0.7.0 cudatoolkit11.0 4.pip install mmcv-full -f https://download.openmmlab.com/mmcv/dist/cu110/torch1.7.0/index.h…

Keil + STM32学习嵌入式数据结构-01

视频链接 初识数据结构&#xff0c;十天搞定嵌入式数据结构_哔哩哔哩_bilibili 课程目的 学会嵌入式经常使用的数据结构 具备基础知识 具有C语言基础&#xff08;结构体、指针、内存&#xff08;malloc)&#xff09; 具有数据结构的基础知识&#xff0c;因此提及到的基础…

Android 深入系统完全讲解(8)

2 Smali 调试 Smali 是安卓 Apk 反编译出来的格式&#xff0c;类似于我们 PC 上面的汇编语言。语法可以参考这个文 章&#xff1a;https://blog.csdn.net/yuanguozhengjust/article/details/80493963 PC 上的反编译调试工具用 OD 和 IDA&#xff08;这个也可以调试 Android &…

Java 调用 扫描仪的技术该如何选择?

文章目录Java 调用 扫描仪的技术该如何选择?详细介绍;&#xff08;1&#xff09;TWAIN&#xff08;2&#xff09;Kodakimg&#xff08;3&#xff09;Dynamic TWAIN ActiveX&#xff08;4&#xff09;WIA&#xff08;用于桌面应用程序&#xff09;开发应用程序&#xff0c;您可…

计算机组成原理习题一

计算机组成原理习题一 文章目录计算机组成原理习题一题目答案题目 1.某数的IEEE单精度浮点数存储形式为C1F00000H&#xff0c;则其所表示的十进制数真值是多少&#xff1f;要求写出详细求解过程以及最终结果。 2.求出数据10010100110的海明码&#xff0c;可检/纠错一位错&…