开发者社区> 问答> 正文

为什么0.1+0.2!=0.3?如何解决这个问题?

展开
收起
前端问答 2019-11-24 20:15:33 1227 0
1 条回答
写回答
取消 提交回答
  • 前端问答小助手

    先说原因,因为 JS 采用 IEEE 754 双精度版本(64位),并且只要采用 IEEE 754 的语言都有该问题。

    我们都知道计算机是通过二进制来存储东西的,那么 0.1 在二进制中会表示为

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

    我们可以发现,0.1 在二进制中是无限循环的一些数字,其实不只是 0.1,其实很多十进制小数用二进制表示都是无限循环的。这样其实没什么问题,但是 JS 采用的浮点数标准却会裁剪掉我们的数字。

    IEEE 754 双精度版本(64位)将 64 位分为了三段

    • 第一位用来表示符号
    • 接下去的 11 位用来表示指数
    • 其他的位数用来表示有效位,也就是用二进制表示 0.1 中的 10011(0011)

    那么这些循环的数字被裁剪了,就会出现精度丢失的问题,也就造成了 0.1 不再是 0.1 了,而是变成了 0.100000000000000002

    0.100000000000000002 === 0.1 // true
    
    

    那么同样的,0.2 在二进制也是无限循环的,被裁剪后也失去了精度变成了 0.200000000000000002

    0.200000000000000002 === 0.2 // true
    
    

    所以这两者相加不等于 0.3 而是 0.300000000000000004

    0.1 + 0.2 === 0.30000000000000004 // true
    
    

    那么可能你又会有一个疑问,既然 0.1 不是 0.1,那为什么 console.log(0.1) 却是正确的呢?

    因为在输入内容的时候,二进制被转换为了十进制,十进制又被转换为了字符串,在这个转换的过程中发生了取近似值的过程,所以打印出来的其实是一个近似值,你也可以通过以下代码来验证

    console.log(0.100000000000000002) // 0.1
    
    

    那么说完了为什么,最后来说说怎么解决这个问题吧。其实解决的办法有很多,这里我们选用原生提供的方式来最简单的解决问题

    parseFloat((0.1 + 0.2).toFixed(10)) === 0.3 // true
    
    2019-12-17 07:48:47
    赞同 1 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
如何做小程序性能优化 立即下载
面向失败设计 立即下载
如何实现应用的持续发布 立即下载