资讯专栏INFORMATION COLUMN

0.1 + 0.2 != 0.3背后的原理

阿罗 / 320人阅读

摘要:标准是浮点数算术标准的标准编号,等同于国际标准。标准规定了计算机程序设计环境中的二进制和十进制的浮点数之间的交换算术格式以及方法。

初学JavaScript,在进行小数(浮点数)运算时,经常会碰到这样的情况:0.1 + 0.2=0.30000000000000004,记得当时,教程告诉我们说,0.1 + 0.2在JavaScript运算中,它的值是不固定的,可以在后面学习和试验中,渐渐发现,这个值似乎每次都是0.30000000000000004,于是渐渐怀疑当时学习过程中关于它的和值是不固定的说法。

其实有一定编程基础的同学们应该都知道,计算机是采用二进制来表示十进制的,规则是:整数除以2,商继续除以2,得到0为止,将余数逆序排列;小数乘以2,取整,小数部分继续乘以2,取整,得到小数部分0为止,将整数顺序排列。例如:

其实不管是十进制转二进制还是八进制、十六进制,原理都是一样的,即,基数连连除(整数)或者连乘(小数)

再回到我们最初的问题, JS 采用 IEEE 754 双精度版本(64位),并且只要采用 IEEE 754 的语言都有前面的问题。

IEEE 754 标准是IEEE浮点数算术标准(IEEE Standard for Floating-Point Arithmetic)的标准编号 ,等同于国际标准ISO/IEC/IEEE 60559 。IEEE 754 标准规定了计算机程序设计环境中的二进制和十进制的浮点数之间的交换、算术格式以及方法 。

根据前面介绍的知识,0.1 的二进制表示为:

0.1 = 2^-4 * 1.10011(0011)// (0011) 表示循环

0.2 的二进制表示为:

0.2 = 2^-3 * 1.10011(0011)// (0011) 表示循环

前面说了,JS 采用 IEEE 754 双精度版本(64位),六十四位中符号位占一位,整数位占十一位,其余五十二位都为小数位。因为 0.1 和 0.2 都是无限循环的二进制,所以在小数位末尾处需要判断是否进位(规则和十进制里的四舍五入一样)。
所以 0.1的二进制表示(0.1 = 2^-4 * 1.10011(0011)) 进位后就变成了 2^-4 * 1.10011(0011 * 12次)010,同理可得0.2的二进制表示 。把这两个二进制加起来得到 2^-2 * 1.0011(0011 * 11次)0100 , 这个值再换算成十进制就是 0.30000000000000004

所以说,0.1 + 0.2=0.30000000000000004,在JavaScript中,它的结果并非不固定的。

那么,如果需要比较0.1 + 0.20.3的关系,我们又该如何进行呢?
其实对于在大学学过数学分析、数值逼近或者高中课程代数方面证明知识的同学来说,自然可以想到让0.1 + 0.2的和减去0.3小于一个任意小的数,比如说我们可以通过他们差值是否小于0.0000000001来判断他们是否相等。JavaScript也提供了一些原生的方法,比如toFixed() 方法可把 Number 四舍五入为指定小数位数的数字,语法:NumberObject.toFixed(num)

参数描述:num,必需。规定小数的位数,是 0 ~ 20 之间的值,包括 0 和 20,有些实现可以支持更大的数值范围。如果省略了该参数,将用 0 代替。

参考内容:JavaScript toFixed() 方法
几道高级前端面试题解析

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/95315.html

相关文章

  • 为什么0.1+0.2不等于0.3

    摘要:又如,对于,结果其实并不是,但是最接近真实结果的数,比其它任何浮点数都更接近。许多语言也就直接显示结果为了,而不展示一个浮点数的真实结果了。小结本文主要介绍了浮点数计算问题,简单回答了为什么以及怎么办两个问题为什么不等于。 原文地址:为什么0.1+0.2不等于0.3 先看两个简单但诡异的代码: 0.1 + 0.2 > 0.3 // true 0.1 * 0.1 = 0.01000000...

    Profeel 评论0 收藏0
  • javascript中0.1 + 0.2 != 0.3?

    摘要:按照的数字格式,整数有的范围是,而且只能表示有限个浮点数,能表示的个数为个。 0.1+0.2 等于0.3吗?相信拿着这条题目随便问一个高年级的小学生,他们都会毫不犹豫都回答:相等。是的,相等是正常的,这是常识。但是都说实践是检验真理的唯一标准,拿这道简单的算术题用javascript在chrome控制台试验一下: 结果令人大跌眼镜,在控制台输入0.1+0.2 == 0.3返回的结果竟然...

    ivydom 评论0 收藏0
  • 利用babel(AST)优雅地解决0.1+0.2!=0.3问题

    摘要:因此利用以及语法树在代码构建过程中重写等符号,开发时直接以这样的形式编写代码,在构建过程中编译成,从而在开发人员无感知的情况下解决计算失精的问题,提升代码的可读性。 前言 你了解过0.1+0.2到底等于多少吗?那0.1+0.7,0.8-0.2呢? 类似于这种问题现在已经有了很多的解决方案,无论引入外部库或者是自己定义计算函数最终的目的都是利用函数去代替计算。例如一个涨跌幅百分比的一个...

    张巨伟 评论0 收藏0
  • JS魔法堂:彻底理解0.1 + 0.2 === 0.30000000000000004背后

    摘要:也就是说不仅是会产生这种问题,只要是采用的浮点数编码方式来表示浮点数时,则会产生这类问题。到这里我们都理解只要采取的浮点数编码的语言均会出现上述问题,只是它们的标准类库已经为我们提供了解决方案而已。 Brief 一天有个朋友问我JS中计算0.7 * 180怎么会等于125.99999999998,坑也太多了吧!那时我猜测是二进制表示数值时发生round-off error所导致,但并不...

    JerryWangSAP 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<