关于二进制世界的秘密

我们都知道,计算机的底层都是使用二进制数据进行数据流传输的,那么为什么会使用二进制表示计算机呢?或者说,什么是二进制数呢?在拓展一步,如何使用二进制进行加减乘除?二进制数如何表示负数呢?本文将一一为你揭晓。

为什么用二进制表示

我们大家知道,计算机内部是由IC电子元件组成的,其中 CPU 和 内存 也是 IC 电子元件的一种,CPU和内存图如下

CPU

内存

CPU 和 内存使用IC电子元件作为基本单元,IC电子元件有不同种形状,但是其内部的组成单元称为一个个的引脚。有人说CPU 和 内存内部都是超大规模集成电路,其实IC 就是集成电路(Integrated Circuit)。

IC元件切面图

IC元件两侧排列的四方形块就是引脚,IC的所有引脚,只有两种电压: 0V 和 5V,IC的这种特性,也就决定了计算机的信息处理只能用 0 和 1 表示,也就是二进制来处理。一个引脚可以表示一个 0 或 1 ,所以二进制的表示方式就变成 0、1、10、11、100、101等,虽然二进制数并不是专门为 引脚 来设计的,但是和 IC引脚的特性非常吻合。

计算机的最小集成单位为 ,也就是 比特(bit),二进制数的位数一般为 8位、16位、32位、64位,也就是 8 的倍数,为什么要跟 8 扯上关系呢?因为在计算机中,把 8 位二进制数称为 一个字节, 一个字节有 8 位,也就是由 8个bit构成。

为什么1个字节等于8位呢?因为 8 位能够涵盖所有的字符编码,这个记住就可以了。

字节是最基本的计量单位,位是最小单位。

用字节处理数据时,如果数字小于存储数据的字节数 ( = 二进制的位数),那么高位就用 0 填补,高位和数学的数字表示是一样的,左侧表示高位,右侧表示低位。比如 这个六位数用二进制数来表示就是 100111,只有6位,高位需要用 0 填充,填充完后是 00100111,占一个字节,如果用 16 位表示 就是 0000 0000 0010 0111占用两个字节。

我们一般口述的 32 位和 64位的计算机一般就指的是处理位数,32 位一次可以表示 4个字节,64位一次可以表示8个字节的二进制数。

我们一般在软件开发中用十进制数表示的逻辑运算等,也会被计算机转换为二进制数处理。对于二进制数,计算机不会区分他是 图片、音频文件还是数字,这些都是一些数据的结合体。

什么是二进制数

那么什么是二进制数呢?为了说明这个问题,我们先把 00100111 这个数转换为十进制数看一下,二进制数转换为十进制数,直接将各位置上的值 * 位权即可,那么我们将上面的数值进行转换

二进制转十进制表示图

也就是说,二进制数代表的 00100111 转换成十进制就是 39,这个 39 并不是 3 和 9 两个数字连着写,而是 3 * 10 + 9 * 1,这里面的 10 , 1 就是位权,以此类推,上述例子中的位权从高位到低位依次就是 7 6 5 4 3 2 1 0。这个位权也叫做次幂,那么最高位就是2的7次幂,2的6次幂 等等。二进制数的运算每次都会以2为底,这个2 指得就是基数,那么十进制数的基数也就是 10 。在任何情况下位权的值都是 数的位数 – 1,那么第一位的位权就是 1 – 1 = 0, 第二位的位权就睡 2 – 1 = 1,以此类推。

那么我们所说的二进制数其实就是 用0和1两个数字来表示的数,它的基数为2,它的数值就是每个数的位数 * 位权再求和得到的结果,我们一般来说数值指的就是十进制数,那么它的数值就是 3 * 10 + 9 * 1 = 39。

移位运算和乘除的关系

在了解过二进制之后,下面我们来看一下二进制的运算,和十进制数一样,加减乘除也适用于二进制数,只要注意逢 2 进位即可。二进制数的运算,也是计算机程序所特有的运算,因此了解二进制的运算是必须要掌握的。

首先我们来介绍移位 运算,移位运算是指将二进制的数值的各个位置上的元素坐左移和右移操作,见下图

移位过程

上述例子中还是以 39 为例,我们先把十进制的39 转换为二进制的 0010 0111,然后向左移位 <<一个字节,也就变成了 0100 1110,那么再把此二进制数转换为十进制数就是上面的78, 十进制的78 竟然是 十进制39 的2倍关系。我们在让 0010 0111 左移两位,也就是 1001 1100,得出来的值是 156,相当于扩大了四倍!

因此你可以得出来此结论,左移相当于是数值扩大的操作,那么右移 >>呢?按理说右移应该是缩小 1/2,1/4 倍,但是39 缩小二倍和四倍不就变成小数了吗?这个怎么表示呢?请看下一节

便于计算机处理的补数

刚才我们没有介绍右移的情况,是因为右移之后空出来的高位数值,有 0 和 1 两种形式。要想区分什么时候补0什么时候补1,首先就需要掌握二进制数表示负数的方法。

二进制数中表示负数值时,一般会把最高位作为符号来使用,因此我们把这个最高位当作符号位。 符号位是 0 时表示正数,是 1 时表示 负数。那么 -1 用二进制数该如何表示呢?可能很多人会这么认为:因为 1 的二进制数是 0000 0001,最高位是符号位,所以正确的表示 -1 应该是 1000 0001,但是这个答案真的对吗?

计算机世界中是没有减法的,计算机在做减法的时候其实就是在做加法,也就是用加法来实现的减法运算。比如 100 – 50 ,其实计算机来看的时候应该是 100 + (-50),为此,在表示负数的时候就要用到二进制补数,补数就是用正数来表示的负数。

为了获得补数,我们需要将二进制的各数位的数值全部取反,然后再将结果 + 1 即可,先记住这个结论,下面我们来演示一下。

-1 取反过程

具体来说,就是需要先获取某个数值的二进制数,然后对二进制数的每一位做取反操作(0 —> 1 , 1 —> 0),最后再对取反后的数 +1 ,这样就完成了补数的获取。

补数的获取,虽然直观上不易理解,但是逻辑上却非常严谨,比如我们来看一下 1 – 1 的这个过程,我们先用上面的这个 1000 0001(它是1的补数,不知道的请看上文,正确性先不管,只是用来做一下计算)来表示一下

1 – 1 分析图

奇怪,1 – 1 会变成 130 ,而不是0,所以可以得出结论 1000 0001 表示 -1 是完全错误的。

那么正确的该如何表示呢?其实我们上面已经给出结果了,那就是 1111 1111,来论证一下它的正确性

1 – 1 正确的分析图

我们可以看到 1 – 1 其实实际上就是 1 + (-1),对 -1 进行上面的取反 + 1 后变为 1111 1111, 然后与 1 进行加法运算,得到的结果是九位的 1 0000 0000,结果发生了溢出,计算机会直接忽略掉溢出位,也就是直接抛掉 最高位 1 ,变为 0000 0000。也就是 0,结果正确,所以 1111 1111 表示的就是 -1 。

所以负数的二进制表示就是先求其补数,补数的求解过程就是对原始数值的二进制数各位取反,然后将结果 + 1

当然,结果不为 0 的运算同样也可以通过补数求得正确的结果。不过,有一点需要注意,当运算结果为负的时候,计算结果的值也是以补数的形式出现的,比如 3 – 5 这个运算,来看一下解析过程

3 – 5 的解析过程

3 – 5 的运算,我们按着上面的思路来过一遍,计算出来的结果是 1111 1110,我们知道,这个数值肯定表示负数,但是负数无法直接用十进制表示,需要对其取反+ 1,算出来的结果是 2,因为 1111 1110的高位是 1,所以最终的结果是 -2。

编程语言的数据类型中,有的可以处理负数,有的不可以。比如 C语言中不能处理负数的 unsigned short类型,也有能处理负数的short类型 ,都是两个字节的变量,它们都有 2 的十六次幂种值,但是取值范围不一样,short 类型的取值范围是 -32768 – 32767 , unsigned short 的取值范围是 0 – 65536。

仔细思考一下补数的机制,就能明白 -32768 比 32767 多一个数的原因了,最高位是 0 的正数有 0 ~ 32767 共 32768 个,其中包括0。最高位是 1 的负数,有 -1 ~ -32768 共 32768 个,其中不包含0。0 虽然既不是正数也不是负数,但是考虑到其符号位,就将其归为了正数。

算数右移和逻辑右移的区别

在了解完补数后,我们重新考虑一下右移这个议题,右移在移位后空出来的最高位有两种情况 0 和 1。当二进制数的值表示图形模式而非数值时,移位后需要在最高位补0,类似于霓虹灯向右平移的效果,这就被称为逻辑右移

逻辑右移示意图

将二进制数作为带符号的数值进行右移运算时,移位后需要在最高位填充移位前符号位的值( 0 或 1)。这就被称为算数右移。如果数值使用补数表示的负数值,那么右移后在空出来的最高位补 1,就可以正确的表示 1/2,1/4,1/8等的数值运算。如果是正数,那么直接在空出来的位置补 0 即可。

下面来看一个右移的例子。将 -4 右移两位,来各自看一下移位示意图

逻辑右移和算数右移示意图

如上图所示,在逻辑右移的情况下, -4 右移两位会变成 63, 显然不是它的 1/4,所以不能使用逻辑右移,那么算数右移的情况下,右移两位会变为 -1,显然是它的 1/4,故而采用算数右移。

那么我们可以得出来一个结论:左移时,无论是图形还是数值,移位后,只需要将低位补 0 即可;右移时,需要根据情况判断是逻辑右移还是算数右移。

下面介绍一下符号扩展:将数据进行符号扩展是为了产生一个位数加倍、但数值大小不变的结果,以满足有些指令对操作数位数的要求,例如倍长于除数的被除数,再如将数据位数加长以减少计算过程中的误差。

以8位二进制为例,符号扩展就是指在保持值不变的前提下将其转换成为16位和32位的二进制数。将0111 1111这个正的 8位二进制数转换成为 16位二进制数时,很容易就能够得出0000 0000 0111 1111这个正确的结果,但是像 1111 1111这样的补数来表示的数值,该如何处理?直接将其表示成为1111 1111 1111 1111就可以了。也就是说,不管正数还是补数表示的负数,只需要将 0 和 1 填充高位即可。

逻辑运算的窍门

掌握逻辑和运算的区别是:将二进制数表示的信息作为四则运算的数值来处理就是算数,像图形那样,将数值处理为单纯的 0 和 1 的罗列就是逻辑

计算机能够处理的运算,大体可分为逻辑运算和算数运算,算数运算指的是加减乘除四则运算;逻辑运算指的是对二进制各个数位的 0 和 1分别进行处理的运算,包括逻辑非(NOT运算)、逻辑与(AND运算)、逻辑或(OR运算)和逻辑异或(XOR运算)四种。

逻辑非 指的是将 0 变成 1,1 变成 0 的取反操作•逻辑与 指的是”两个都是 1 时,运算结果才是 1,其他情况下是 0″•逻辑或 指的是”至少有一方是 1 时,运算结果为 1,其他情况下运算结果都是 0″•逻辑异或 指的是 “其中一方是 1,另一方是 0时运算结果才是 1,其他情况下是 0”

与或非异或真值表

掌握逻辑运算的窍门,就是要摒弃二进制数表示数值这一个想法。大家不要把二进制数表示的值当作数值,应该把它看成是 开关上的 ON/OFF

文章参考:

《程序是怎样跑起来的》让我们努力向前奔跑吧!

Image placeholder
杨博
未设置
  42人点赞

没有讨论,发表一下自己的看法吧

推荐文章
时序数据库的秘密 —— 快速检索

Elasticsearch是通过Lucene的倒排索引技术实现比关系型数据库更快的过滤。特别是它对多条件的过滤支持非常好,比如年龄在18和30之间,性别为女性这样的组合查询。倒排索引很多地方都有介绍,

腾讯财报背后的小秘密:转型路上的未知

8月14日,腾讯发布第二季度财报,不凑巧的是,当日欧市盘中,美国2年期与10年期国债利率发生2007年来首次倒挂,引起市场对经济衰退的恐慌,美股三大指数均暴跌3%。8月15日,中国香港恒生指数低开1.

初探英特尔存储“秘密基地”:傲腾小白 学成归来

可以把这篇文章当成故事听、你也可以把它看成游记、你还可以认为它是一篇技术贴,whatever,如何包装不重要,接下来的干货才是重点:忆往事英特尔傲腾数据中心技术,是英特尔“以数据为中心”战略的具体体现

2019年世界5G大会热点

  2019年世界5G大会热点,5G时代的开局元年,在北京举行5G大会吸引了众多行业领导者参与其中。5G融合大数据、人工智能、区块链等通用技术,将全面构建我国数字经济的关键基础设施。5G与人工智能之间

专访领英工程副总裁张仁辉:如何驯服算法,打造世界级的职位推荐系统?

大数据文摘出品作者:魏子敏、宋欣仪作为全球最大的职业社交网络,创建于2003年的LinkedIn在过去6年间,从一个7000万左右年营收的企业,增长至30亿美元营业额的企业。五年间LinkedIn业务

AI赌神升级!无惧bluff,6人局德扑完胜世界冠军,训练只用了8天

大数据文摘出品作者:曹培信、宁静2017年年初,BrainvsAI的德州扑克人机大战在卡耐基梅隆大学(CMU)落幕,由4名人类职业玩家组成的人类大脑不敌人工智能程序Libratus。获胜后人类还遭到了

一文告诉你全世界最顶级的开发者都在使用什么数据库

作为一名IT行业从业者,其实从去年已经隐隐约约感觉到数据库的有变化,只是没有想到变得这么快。今年的一些事情实实在在地给了某些数据库重击,如果以前去某数据库还是喊喊,然后该用还用,今年从传统领域刮起的去

解码GaussDB:如何成为世界级数据库?

1、开源GaussDB单机版OLTP;2、成立鲲鹏智能数据产业联盟数据库产业推进组;3、1.5亿元启动基金,发起GaussDB高校金种子发展计划;4、成立十大GaussDB高校联合创新实验室;5、现场

Git教程_1.1 起步 - 关于版本控制

本章关于开始学习Git。我们从介绍有关版本控制工具的一些背景知识开始,然后讲解如何在你的系统运行Git,最后是关于如何设置Git开始你的工作。通过本章的学习,你应该了解为什么Git这么流行,为什么你应

Laravel shop 5.8 关于面包屑 category 为空,前端页面报错问题。

进入本章的:3.体验优化现在商品列表页还比较简陋,接下来我们就要针对类目做一些前端方面的体验优化。类目面包屑前面测试还正常,地址栏输入 还能正常获取到商品信息,自从前端的商品index模板中加入了

关于 Deref, 使&&T 变成&T 的疑问

分享链接:https://rust.cc/article?id=9d04e55e-7523-4... 这个知识点,非常值得掌握,特地补充了例子:fnmain(){ letx=5; lety=&&&&&

有个关于『热更新』的问题请教

热更新问题问题背景日志分析支撑平台 游戏服务器将日志推送到平台服务器 protobuf作为序列化方案,双方约定好proto文件,一方进行序列化发送,另一方反序列化接收 问题描述当proto变更之后,平

关于工业物联网,你应该了解的3件事

世界各地的基础设施日益紧密。我们应该感谢工业物联网(IIoT)带来的这种连通性,它将交通、制造业、医疗保健等行业的机器和设备连接起来,并远远超出了预期范围。IIoT的潜力仍然很高,但风险也是如此。你需

《关于MySQL的一些骚操作》

概要回顾以前写的项目,发现在规范的时候,还是可以做点骚操作的。假使以后还有新的项目用到了MySQL,那么肯定是要实践一番的。为了准备,创建测试数据表(建表语句中默认使用utf8mb4以及utf8mb4

关于SD-WAN的三大误区

传统的广域网已经跟不上时代的发展速度。在宽带时代,网络专业人员在管理和配置分支机构时困难重重。员工注意到他们的关键业务应用程序的速度变慢了,而其他应用程序(如流媒体体育赛事)则会覆盖网络。拥有许多分支

关于网络安全防御,每个中小企业应该知道的5件事

根据美国商业促进局(BBB)的数据显示,你可能会惊讶地发现,小型企业占北美所有企业的97%以上。根据这个统计数字,我认为好消息是,在所有网络攻击中,针对小企业的攻击不到一半。坏消息是,当中小企业受到攻

看完秒变5G专家!关于5G,你必须知道的事儿……

本文转自|鲜枣课堂   什么是5G    5G,就是5thGenerationMobileNetworks(第五代移动通信网络),也可以称为5thGenerationWirelessSystems(第

关于强化学习你应该知道的三件事

如果您有在关注科技相关的新闻,可能读过有关人工智能(AI)应用程序如何通过强化学习训练,在围棋、国际象棋等棋类游戏以及电子游戏中击败人类玩家的报道。作为一名工程师、科学家或研究人员,您可能会希望利用这

IBM 思想之夜:⼀场关于 AI 辩论,⼀名“AI 辩⼿”

5⽉20⽇,在2019IBM中国论坛隆重举⾏前夜,⼀场围绕关于“⼈⼯智能(AI)是否会改写商业规则”的思想对话辩论在北京盘古七星酒店激烈展开。由《哈佛商业评论》与IBM携⼿主办的“HBRC年度对话暨I

关于企业数字化转型和AI应用的5个建议

波士顿咨询公司(BostonConsultingGroup)表示,企业对数字化转型和人工智能抱有很高的期望,但也面临着一些挑战。许多企业正在迎来第一波数字化转型浪潮,在扩大覆盖面和定制化、改进流程、提

Spring Boot 中关于自定义异常处理的套路!

在SpringBoot项目中,异常统一处理,可以使用Spring中@ControllerAdvice来统一处理,也可以自己来定义异常处理方案。SpringBoot中,对异常的处理有一些默认的策略,我们

关于分析IT系统宕机对业务影响的10个提示

在制定灾难恢复计划时,一个非常重要的任务就是,要确定并想方设法避免潜在的威胁,同时为最坏的情况做准备。业务影响分析(BIA)提供了解决突发事件所需的信息,前提是您要事先做好万全准备。遵循详尽的业务影响

一份关于机器学习“模型再训练”的终极指南

机器学习模型的训练,通常是通过学习某一组输入特征与输出目标之间的映射来进行的。一般来说,对于映射的学习是通过优化某些成本函数,来使预测的误差最小化。在训练出最佳模型之后,将其正式发布上线,再根据未来生

科普 | 关于联盟区块链你不知道的事

在分布账本技术发明十年后的今天,我们仍然处于大规模应用落地的早期。目前多数流行的公有区块链仍然无法落地,因此近年来越来越多的技术团队将目光集中在那类有使用场景的方向--联盟区块链。第1部分:行业分类从