你知道 0.1+0.2 !==0.3是进制问题,但你讲不出个所以然,是吧?🐶

7,766 阅读2分钟

前言

大家好,我是林三心,用最通俗易懂的话讲最难的知识点是我的座右铭,基础是进阶的前提是我的初心。有一个问题困扰了广大前端工程师,那就是0.1 + 0.2 !== 0.3

截屏2021-12-13 下午10.25.39.png

大家可能都知道,这是因为计算机在存储数字是是通过二进制来存储的,呈现的时候是通过十进制来存储的,所以有误差。但是再继续深问你为啥计算机的二进制存储会造成误差呢,可能你就支支吾吾了。。。

image.png

十进制转二进制

咱们先来讲讲十进制转二进制是怎么转的吧。。情况有三种:

  • 1、整数
  • 2、负整数
  • 3、小数

整数

整数的十进制转二进制,是怎么转的呢?记住一条公式:除二取余,然后倒序排列,高位补零。啥意思呢?别急,我给你讲讲哈,我就拿81这个数字来举例子吧,毕竟曾经有一个男人,单场砍下81分

截屏2021-12-14 下午9.09.21.png

可以得出1010001,可以看出有7位,但是呢,计算机内部表示数是定长的,例如8位、16位、32位,所以7位是不够的,需要高位补0,也就是01010001,规范写法为(81)10 = (01010001)

截屏2021-12-14 下午9.11.07.png

负整数

负整数的话,是这样的规则:

  • 第一步:把正整数转成二进制
  • 第二步:对二进制取反
  • 第三步:对取反后的二进制进行加1

就拿-81举个例子吧:

截屏2021-12-14 下午9.13.02.png

小数

小数转二进制的话是这样的:对小数点以后的数乘以2,得出结果,取结果的整数部分(不是 0 就是 1),然后再对结果的小数点以后的数乘以2,得出结果,再取结果整数部分,再然后然后再对结果的小数点以后的数乘以2。。。。以此类推。。知道小数部分为0或者位数已经到达位数。再把这个过程中取的整数按先后顺序排好就行了。

我举个例子吧,比如0.125

截屏2021-12-13 下午10.07.07.png

我再举个例子,比如121.6

截屏2021-12-14 下午9.15.01.png

0.1 + 0.2

再回到0.1 + 0.2这个问题

截屏2021-12-13 下午10.23.42.png

可以看到,0.1和0.2转成二进制都是无限循环的,超过了最大位数,所以存储时只能通过近似值去存储他们两,那自然的,当0.1 + 0.2时,近似值转十进制肯定也是近似值,所以造成误差,最大位数是根据硬盘内存大小决定的,所以一般硬盘内存越大,精确度越高。

截屏2021-12-13 下午10.25.39.png

结语

我是林三心,一个热心的前端菜鸟程序员。如果你上进,喜欢前端,想学习前端,那咱们可以交朋友,一起摸鱼哈哈,摸鱼群,点这个 --> 摸鱼沸点

image.png