漫话:为什么计算机用补码存储数据?

dfed60952e9d59a2b05def439179f38c.gif

作者 | 漫话编程

来源 | 漫话编程

41c4be0965aa328096e25d6c9eee82fb.png

18e76516b122fb27691651a2da2406c8.png

48fb298b8641d936f16c9f354d005660.png

67e88a6fbc40712f8f19a3bf504a4a6f.png

45fd651cef07cc8963b7eb4427890e97.png

09e4bcdef66b011ea18e9a44b504efab.png

我们知道,计算机只认识0和1,现实世界中的内容,无论是文字、音频、视频等等想要通过计算机存储、计算或者展示,都需要转换二进制。

就像你刚刚唱的旋律,想要存储在计算机中也是要转成二进制的。

那么,最简单的一个数字,想要在计算机中表示出来,就需要通过一定的手段将他转换成二进制。而这种手段我们称之为编码方式。

c1e2c466629709baca6f9b3abbfefa48.png

d63d63ffd46c88fa2f8d39ea7666486a.png

48af530ee958075de3839c172c06b864.png

e24c5714c66400ca55ee4e58b086f812.png

ef5b0e3bb0f3ed18a2a94f0895baf946.png

原码

相信很多人在上初中的时候都学过很多方式把一个十进制数转成二进制数,比如我们可以很快速的知道10的二进制可以表示成 1010 。

但是初中老师没有告诉我们的是:-10 如何表示呢?

为了在计算机中想办法表示负数。于是人们想出来一种办法:

在二进制数值前面增加一位符号位(即最高位为符号位):正数该位为0,负数该位为1,其余位表示数值的大小。

这样,如果我们想要10的话,那么就应该是:0 1010,想要表示-10的话,就应该是1 1010。

这种编码方式被称之为原码,原码的优点比较明显,那就是非常的简单直观,很容易被人理解。

2468c488f2bdb133e7fc9dbf57512497.png

bd652c87b940e2f6547b63f859052bf1.png

使用原码,解决了十进制在计算机中的存储问题,但是计算机中还有一个重要的操作那就是计算。使用原码如何计算呢?

首先,原码对于加法的运算是没什么问题的,如5 + 2

ffae319bd72816d415d936b7b6964d7d.png

对应的二进制运算:0 0101(原) + 0 0010(原) = 0 0111(原) 其对应的十进制是 7。

加法没什么问题,那么我们再试着用原码来计算减法,例如我们想要计算10 - 2:

732cf7a4871fdbc28bab329359c92b6a.png

那么就是 0 1010(原) - 0 0010(原) = 0 1000(原),那么这个二进制对应的十进制刚好是8。可见原码计算减法没有问题的?

但是,以上运算只是我们一厢情愿的算法,其实计算机算术逻辑单元(ALU)并没有直接进行减法运算,对于减法,其实也是用加法器来实现的

也就是说,计算机中的所有的减法运算都需要转换成加法运算,那么10 - 2其实就是10 + (-2)

ab3bb031e1b38c5b3ee29fa0041565d5.png

他们的二进制 0 1010(原) + 1 0010(原) = 1 1100(原) ,得到的结果考虑他的符号位的话,这个值是-12,这明显是错误的!!!

可见,原码虽然对于人类来说是比较简单直观的,但是对于计算机来说却带来了很大的计算难度。

8659a870c8ccb0c9a3d2665f89bd97f3.png

5cceb7f4e5c651279efadb3df1aa8abc.png

反码

因为原码虽然容易被人理解,但是给计算机的计算带来了一定的困难,尤其是减法的运算。所以,人们发明出反码来解决减法运算的问题。

反码是基于原码计算得来的,表示方式是:正数的反码是其本身。负数的反码是在其原码的基础上, 符号位不变,其余各个位取反。

如,10 的 原码为 0 1010 ,那么他的反码同样也是 0 1010 。

如,-2 的原码为 1 0010 ,那么他的反码为 1 1101 。

有了反码之后,二进制的运算就可以带着符号位一起了。并且可以直接将减法转换成加法进行运算。但是使用反码进行运算,需要注意以下几点:

  • 反码运算时,其符号位与数值一起参加运算。

  • 反码的符号位相加后,如果有进位出现,则要把它送回到最低位去相加(循环进位)。

  • 用反码运算,其运算结果亦为反码。在转换为真值时,若符号位为0,数位不变;若符号位为1,应将结果求反才是其真值。

如 10 - 2 的在计算时需要转成 10 + (-2)进行计算:

2a9f1bb5258b88aeab42b447ec63c0d3.png

0 1010(反) + 1 1101(反) = 0 0111(反) + 1(进位) = 0 1000 ,因为符号位是0,表示正数,所以他对应的原码也是0 1000(原),则十进制值为8。

那么,我们再来计算法 2 - 10 ,把2 - 10转换成 2 + (-10)进行计算:

5c50172fa61d3dc139159df6656d9d07.png

0 0010(反) + 1 0101(反) = 1 0111(反),因为符号位是1,表示负数,所以他对应的原码也是1 1000(原),则十进制为-8。

以上,我们通过几个例子展示了反码,我们知道使用反码进行计算的时候,可以带着符号位一起计算,只需要在计算之后再将反码转换成原码,再计算其对应的十进制就可以了。

但是,反码运算还是有一个小问题,我们看一下下面这个例子:

我们尝试计算10 - 10 ,即 10 + (-10):

6f232a34535c173c8a60173cd3cdff3a.png

0 1010(反) + 1 0101(反) = 1 1111(反),因为符号位是1,表示负数,所以他对应的原码也是1 0000(原),则十进制为-0。

虽然很多人够能够理解+0和-0其实是一样的,但是0带符号仍然是没有任何意义的。

如果一台计算机有8位,我们想要用反码表示0的话,就有0000 0000和 1111 1111两种方式,分别表示+0和-0。

db1df68f606459f8b1ce2e615418ef96.png

7b21317b7a59d987f7e3e7d9805c167c.png

081b931b12de629407c139254ed04227.png

3915bc6400ab96ce4eb52f65cd5a866d.png

补码

虽然反码解决了减法的问题,但是对于0的符号问题却没有解决,于是补码出现了。

补码是在原码和反码的基础上衍生出来的,补码的表示方法是:正数的补码就是其本身,负数的补码是在其原码的基础上, 符号位不变, 其余各位取反,最后+1。(即在反码的基础上+1)

补码计算的规则:

  • 补码运算时,其符号位与数值一起参加运算。

  • 补码的符号位相加后,如果有进位出现,则进位被舍弃。

  • 用反码运算,其运算结果亦为补码。在转换成原码时,如果是正数,其补码就是原码;如果是负数,该补码的补码就是其原码。

我们再来用补码的方式,来计算下10 - 10 :

96522cc533d45d65b0c918cca2cbd8ea.png

01010(补) + 10110(补) = 0 0000 (补),因为符号位是0,表示正数,所以他对应的原码也是0 0000(原),则十进制为0。

有了补码,0的表达方式就唯一了,如果是8位的话,那么就是固定的0000 0000。

如果使用原码或者反码,8位的原码或者反码能表示的最小数字是-127,而使用补码,能表示的最小数字是-128。

可见,使用补码, 不仅仅修复了0的符号以及存在两个编码的问题, 而且还能够多表示一个最低数。这就是为什么8位二进制, 使用原码或反码表示的范围为[-127, +127], 而使用补码表示的范围为[-128, 127]。

c71b3b468eb0a12427b1a84689486316.png

974237575256ff957868c7fb1c965b6e.png

b7f7d85ce22660e036afc3258aba6ad2.png

使用补码的原因

通过以上介绍,我们知道了原码、反码和补码的一些知识,我们尝试着总结下为什么计算机中会最终选择补码来进行存储和计算数字。

1、计算机的运算器为了实现简单,倾向于在运算过程中将减法转换成加法,统一使用加法运算器进行计算。想要把减法转化成加法运算,就需要在运算时带着符号一起运算,而反码和补码可以带符号位一起运算,也就方便了将减法转换为加法。

2、采用补码,可以解决编码中有+0和-0两种表示0的方式。

3、补码表示的数字范围要比原码和反码大。如8位2进制,使用原码或反码表示的范围为[-127, +127], 而使用补码表示的范围为[-128, 127]。

5657ce11df9d712f016b95fa0dd6be30.png

f96d31dc0abd6f498ceee9e7727a8221.png

f2929806ae7cfe98dcf931fea7da31e5.png

990dd98432d4172b7e36bdb5e72ed817.png

6098fab4117717b883d485e2f3f7f717.png

b325eff15e9047285129e3765d4bb5d5.png

5b759e1a584fc4f45c87d5483f336540.png

a47feaaca349cd4fdf4188cd594e47f6.gif

58341c6d43cbc8adc67b282c377ab30d.png

往期推荐

做安全操作系统,这位技术老兵很认真

Docker终失C位,开源少年缘何黑化?

关于数据库,你可能最想知道的几件事

张一鸣购得元宇宙入场券,谁将是头号玩家?

d81be7bfdbfda3dfdfbcd03ad746acb0.gif

点分享

d6d4c214e5f510c240da76babb7ce8ba.gif

点收藏

52ba4e5bc31e88be321f284a16a2a91e.gif

点点赞

56762edcb69bb2f15aafd386368c47aa.gif

点在看

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

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

相关文章

cad多个窗口并排显示_你早该这么做!并排查看Excel工作表其实一个小动作就搞定!...

特别福利:私信发送关键词【福利】,年度最全Office办公资源等你免费领哟~很多人都知道,有时在屏幕上并排查看起两个文件的内容,是一项非常顺畅和方便的操作——省去不少在不同窗口间来回切换的时间!当然,对于…

数据仓库如何实现湖仓一体数据分析?

简介: 随着云计算的普及和数据分析需求的扩大,数据湖数据仓库的湖仓一体分析能力成为下一代数据分析系统的核心能力。相对于数据仓库,数据湖在成本、灵活性、多源数据分析等多方面,都有着非常明显的优势。IDC发布的十项2021年中国…

Java应用全链路启动速度提升至15s,阿里云SAE能力再升级

简介: Java 作为一门面向对象编程语言,在性能方面的卓越表现独树一帜。但在高性能的背后,Java 的启动性能差也令人印象深刻,大家印象中的 Java 笨重、缓慢的印象也大多来源于此,高性能和快启动速度似乎有一些相悖。 近…

到底什么是“无源物联网”?

作者 | 小枣君来源 | 鲜枣课堂继Cat.1之后,2021年的物联网行业,又“喜提”了一个新的“风口”。这个“风口”的名字,叫做“无源物联网”。无源物联网,到底是个啥东东?它和现有的物联网技术之间,有什么区别&…

Gartner魔力象限到底有何“魔力”?

简介: Gartner魔力象限到底有何“魔力”?近日,Gartner发布了一系列最新魔力象限报告,在IT圈掀起了阵阵“龙卷风”,谁跻身全球第一阵营,谁跌出“领导者”象限,权威定调,众说纷纭&…

K8s 原生 Serverless 实践:ASK 与 Knative

简介: K8s 处在一个承上启下的位置,云原生用户使用 K8s 的目的是为了交付和管理应用,也包括灰度发布、扩容缩容等。但是对用户来说,实现这些能力,通过直接操作 K8s API 难免有些复杂。另外节省资源成本和弹性对于用户来…

react安装_前端大牛进阶---gt;React必会教程

一、背景介绍01React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设 Instagram 的网站。做出来以后,发现这套东西很好用,就在2013年5月开源…

透过 3.0 Preview 看 Dubbo 的云原生变革

简介: 做过微服务开发的开发者相信对 Dubbo 都不陌生,Dubbo 是一款能帮助我们快速解决微服务开发、通信以及流量治理的框架。相比于之前只限定在 Java 语言范围内,Dubbo 的多语言版本在这两年呈现了良好的发展势头,其中&#xff0…

扩展云存储边界,阿里云推出全球首个云定义存储产品

云计算正带来一场消除线上线下存储边界的革命。 9月22日,阿里云宣布云存储服务全面升级,包括性能大幅提升300%、时延降低70%的ESSD云盘;可兼容HDFS的数据湖存储OSS,同时推出一款全新产品“云定义存储”(Cloud Defined…

Go Mysql Driver 集成 Seata-Golang 解决分布式事务问题

简介: 2020 年 4 月,我们开始尝试实现 go 语言的分布式事务框架 Seata-Golang。众所周知,Seata AT 模式以无业务代码侵入的特点,被广大开发者推崇。Java 版 Seata AT 模式通过对 DataSource 数据源进行代理,在 sql 语句…

安装redis提示[test] error 2_技术干货分享:一次flask+redis的微服务实战

先说一下需求的场景,策划部门想做一个垂直领域的社区产品,类似与知乎那种,但受益人群是金融行业的从业人员。产品中有一个搜索问题的需求,搜索的问题去题库中进行模糊匹配,终端支持H5/APP/小程序,甚至是微信…

实现阿里云容器镜像服务反向访问代理

简介: 本文会先介绍镜像推送/拉取过程的交互逻辑来梳理需要代理的所有服务,再通过搭建一个公网 HTTPS 反向代理来访问容器镜像服务来向您展示多场景代理访问模式原理。 真实业务场景可能很复杂,因安全、合规、访问限制等原因可能需要&#x…

数字基础设施开源操作系统欧拉全新发布

在华为全联接2021上,面向数字基础设施的开源操作系统欧拉(openEuler)全新发布。欧拉操作系统可广泛部署于服务器、云计算、边缘计算、嵌入式等各种形态设备,应用场景覆盖IT(Information Technology)、CT&am…

mysql 聚簇索引和非聚簇索引_MySQL 聚簇索引 二级索引 辅助索引(上两期中奖名单)...

阅读文本大概需要3分钟。MySQL中每个表都有一个聚簇索引( clustered index ),除此之外的表上的每个非聚簇索引都是二级索引,又叫辅助索引( secondary indexes )。以InnoDB来说,每个InnoDB表具有一个特殊的索引称为聚集索引。如果表上定义有主…

共筑计算新生态 共赢数字新时代

[中国,深圳,2021年9月25日] 在华为全联接2021上,华为副总裁、计算产品线总裁邓泰华分享了六大数字生态的最新进展,并携手生态伙伴为计算产业带来一系列重磅内容:欧拉开源操作系统(openEuler)全新…

数据湖,已成为海量数据存储与分析的重要承载方式

简介: 在云计算和大数据时代,基于数据开展生产、运营、决策成为常态,根据Gartner报道,2019年数据基建方面的采购费用飙升到660亿美元,占据基础架构类软件费用的24%。数据的存储及应用体系是企业生态运转的中枢神经&…

Fluid 0.5 版本发布:开启数据集缓存在线弹性扩缩容之路

简介: 为了解决大数据、AI 等数据密集型应用在云原生场景下,面临的异构数据源访问复杂、存算分离 I/O 速度慢、场景感知弱调度低效等痛点问题,南京大学PASALab、阿里巴巴、Alluxio 在 2020 年 6 月份联合发起了开源项目 Fluid。 作者 | 顾荣 …

php生成cookie在哪,php程序中cookie的使用方法

Cookie 可以翻译为“小甜品,小饼干” ,Cookie 在网络系统中几乎无处不在,当我们浏览以前访问过的网站时,网页中可能会出现 :你好 XXX,这会让我们感觉很亲切,就好像吃了一个小甜品一样。这其实是…

c#类属性和实例属性_Visual C#类和对象的创建方式,定义类,实例化对象,实例讲解...

定义类类由class member类成员组成,包含字段、属性、方法和事件。其中字段和属性为类的数据成员,用来存储数据;方法负责数据的传递和运算。使用类之前,要进行声明,声明的语法如下:Class 类名称{访问权限 数…

面对不可避免的故障,我们造了一个“上帝视角”的控制台

简介: 混沌工程随着云原生的发展逐渐进入大家的视野,通过混沌工程可以很好地发现和解决在云原生化过程中的高可用问题。阿里巴巴在 2019 年开源了底层的混沌工程工具 - chaosblade,今年年初再次开源混沌工程控制台 chaosblade-box&#xff0c…