乐趣区

关于前端:二进制下为什么能用补码来计算减法

二进制下为什么能用补码来计算减法?

学习指标

  1. 计算机中是怎么去形容一个 ” 数 ” 的?(本文有答案)
  2. 补码到底是什么?为什么要创造它?为什么用补码就能够计算减法?取得一个原码的补码的原理是什么?(本文有答案,重点
  3. 怎么晓得一个占 n 比特位的数,它所能示意的整数范畴是多少?(本文没细讲)
  4. 什么是浮点数?怎么用二进制示意浮点数?什么是浮点数的精度?(下一讲)

比照一个时钟,来看二进制补码

数据应该怎么在计算机内存储?

  • 在计算机的世界里,不管任何数据模式,只能用二进制示意和计算,因为作为开关的电信号仅有两种状态。

    二进制,简略来说我认为是一种计数规定,相比于咱们从小学到大的十进制,二进制就是逢二进一。

    举例,5(10) = 101(2),5 在十进制数当中算作一位,因为他只有一个 ” 个位 ”,而 101(2) 这个数字在二进制中算作三位,每一位都以电信号的形式存储在计算机的某个半导体内。

    咱们这里的 ” 位 ”,就叫做 1 一个比特位(bit),这很重要,它间接影响了数的示意范畴。

  • 存储信息的半导体的个数是无限的,所以用来示意数的比特位也是无限的,咱们不能得心应手的有限扩张它,咱们要尽可能的增大示意范畴,又要控制数据的存储空间。

    举例,在 Java 中,一个 int 类型占据了 4 个字节(Byte),再加上我偷偷通知你 1 个字节等于 8 个比特,所以 Java 里 int 占 32 位:

    在脑海里的样子:
    0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000

    什么?不看虚的?那你瞧一瞧上面这张图!????

    这,就是题目外面 问题 1 的答案 — 数据以一个个的电容信号存储在计算机硬件外面的某些半导体中,你仅能够设想它的样子(如下面的 32 个 0)。

  • 我在这里不想形容进制间是怎么转换的,这不是咱们明天探讨的重点,感兴趣的话能够自行搜寻。

整数的二进制示意和补码

  • 整数又分为正整数,负整数,零。如果想要简略的来示意 无符号整数,定义一个正整数占 4 个比特位的话,那么

    6(10) = 0 23 + 1 22 + 1 21 + 0 20 = 0110(2)

    在这种状况下,咱们无奈示意出正数,那么用这样的办法示意多少个非负整数?

    也就是 0000(2) \~ 1111(2) 也就是 [0 \~ 23+22+21+20] = [0 \~ 15] 也就是 24个。

    可我就是想要示意 - 6 怎么办呢?????

    咱们只能 sacrifice 掉一位男 … 额不对,是就义掉 1 个比特位。

    也就是说咱们要拿出 1 个比特位来做符号位,0 示意正,1 示意负

    那么,同样一个 +6:

    6(10) = 1 22 + 1 21 + 0 * 20 = 0110(2)

    肯定要留神这次的计算形式和上一次的区别,少了一次对 2 3的计算!是因为这次存储数值的总共就三位,还有一位用作了符号位:

    符号位    数值位
      
      0       110
    

    自然而然,咱们会想到用 1110(2) 来示意 - 6 的二进制(我肯定要先申明,这是一种 谬误????‍♂️的做法,请往下看完)

    这里呈现了一个问题,如果我想让你计算 1-6=?

    /** 计算机没方法做减法,只能通过 1+(-6) 来实现 1 -6 **/
       0 0 0 1
     + 1 1 1 0
       1 1 1 1
    

你会发现后果是 -7,这显然不对。(起因是第一位是用来示意正或负号,不能参加计算)

  • 为了解决这个问题,人们想出了补码的概念。

    当正数用二进制补码示意后,符号位能与有效值局部一起加入运算,减法运算能够转换为加法运算并且后果正确。

    原理呢?别急,看看上面这个家伙

    这是一个时钟,12 进制。咱们使用生存中的教训来答复以下几个问题:

    Q1. 当初是 8 点,问 5 小时后是几点?8 + 5 = 13 
    然而时钟上没有 13 点,所以你看到的是 1 点
    
    Q2. 当初是 8 点,问 5 小时前是几点?8 - 5 = 3
    3 点!可是请问用加法怎么解决这个问题呢?

    这里咱们能够用 8 + 7 来失去 3 点

    把 8 - 5 看作是时针从 8 点向前拨动了 5 个小时,回到了 3 的地位,然而他也等同于把时针从 8 点向后拨动 7 个小时,达到了 3 的地位上。

    而后你心里面肯定会有疑难????️

    小学数学通知咱们 8 -5=3,可是你来给我解释解释 8 + 7 为什么等于 3!

    $$\begin{cases} \text{-5 + 0 = -5}\\ \text{0 = 12} \ \ \text{在时钟只有一个的状况下(只有 1 个比特位时)0 = 12(能够看下时钟,0 点也是 12 点,对吧?)} \end{cases}$$

    所以 -5 + 12 = 7 = -5

    能够看到,这里的 - 5 等于了 7,咱们把 12 进制中的 7 和 - 5 就称作是一组 互补数,用这样办法,能够做到加法代替减法,让计算机把符号位带入还能够失常运算

    如果你没看懂,那你听听我的另一种解释:8+7=15,然而时钟是一个 12 进制的工具,所以十进制的 15(10) 的理论表白是 12 进制的 13(12),然而因为咱们只有一个时钟,就相当于咱们只有一个比特位来存储 13(12)这个数据,那么第二位 ”1″ 就溢出了,这个 ”1″ 相当于是被一个黑洞给吞掉了,咱们基本没有方法去找回来,所以最初只剩下一个 12 进制的 3 (12),所以最初 8 +7=3!

  • 那么,在二进制中,该怎么计算出 补码 呢?

    负数和 0 的补码就是该二进制自身,也就是 原码 。正数的补码则是将其对应负数的原码按位取反失去 反码 再加 1。

    原理呢!

    咱们假设当初用 2 个比特位来示意 1 个数,依葫芦画瓢,列出上面的不等式组:

    $$\begin{cases} \text{原码 + 补码 = 00}\\ \text{00 = 100} \ \ \text{只有 2 个比特位时} \end{cases}$$

    补码 = 100(2) – 原码 =(11(2) + 01(2))- 原码 = 11(2) – 原码 + 01(2)

    而 11(2) – 原码是什么?认真想一下,这不就是相当于是原码取反后的后果吗!

    写到这里,我想你终于能够弄懂 问题 2 了吧?

小数的二进制示意

  • 小数能够拆成整数局部和小数局部,整数局部的示意办法在下面,小数局部应该怎么做呢?

    举例,十进制 123.45 示意成二进制如下图:

    具体的转换形式是:

    • 整数局部采纳十进制转二进制办法进行
    • 小数局部乘以 2,而后取整数局部。一直反复该操作直到 小数局部为 0,或达到指定的精度
  • 你想要的只是岁月静好。然而呢,不是所有的小数都能转换无限位数的二进制小数。例如 10 进制 0.2 的二进制:

    0.2 x 2 = 0.4 0
    0.4 x 2 = 0.8 0
    0.8 x 2 = 1.6 1
    0.6 x 2 = 1.2 1
    0.2 x 2 = 0.4 0
    0.4 x 2 = 0.8 0
    0.8 x 2 = 1.6 1
    0.6 x 2 = 1.2 1
    ……不光岁月静好,我还送你天荒地老

    这是为什么呢?

    抛开数学概念,十进制中 1 的一半是 0.5,二进制中 1 的一半是 0.1;十进制中天然能够十等分造成小数,所有不能十等分的都是有限循环,同理二进制中只能二等分,所有不能二等分的天然都是有限循环。正如切蛋糕,二进制就像一把一次只能切一半的刀。

  • 讲了这么久,该示意示意了吧?

    所以,实践 上,咱们能够这样存储小数(以 123.5 为例):

    符号位       整数位        小数位
      
      0        0111,1011    1000,0000

    然而,这种办法是不被采纳的,本质上,被用来示意小数的货色叫做 浮点数

浮点数的二进制示意

  • 敬请期待

本文援用了

  • 为什么十进制小数转换成二进制有可能有限循环?卫知 的答复
  • 浮点数在计算机中是如何存储的?

  • V(base): 下标 base 代表进制数,V 则代表了在该进制下的值示意。
退出移动版