踏上0.1+0.2不等于0.3的不归路
发布日期:2021-05-14 14:37:38 浏览次数:18 分类:精选文章

本文共 1216 字,大约阅读时间需要 4 分钟。

0.1 + 0.2 = 0.3吗?

1. JS中计算机制的理解

  • 三点要清晰说明
    • JS内部所有的计算都是通过二进制进行计算的
    • 十进制与二进制的换算规则
    • 如何将十进制数转化为二进制浮点数形式

2. 二进制与十进制的换算规则

2.1 二进制转换为十进制

  • 权重概念
    • 某位的权重:2的(该位所在的位数(从右至左)-1)次方
    • 例如:
      • 0的权重为:2^(1-1)=1
      • 1的权重为:2^(2-1)=2
      • 2的权重为:2^(2-1)=2

2.2 十进制转换为二进制

  • 整数位转化法

    • 方法:十进制数除2取余法
    • 例如:
      • 除数为2,依次记录余数
  • 小数位转化法:

    • 方法:乘2取整,顺序排列
    • 例如:
      • 依次乘2并记录整数部分

3. 0.1 + 0.2的计算过程

3.1 将十进制转换为二进制

  • 0.1转换成二进制

    • 0.1 *2=0.2→0
    • 0.2 *2=0.4→0
    • 0.4 *2=0.8→0
    • 0.8 *2=1.6→1
    • 循环,得到二进制为:0.0001100110011001…
  • 0.2转换成二进制

    • 0.2 *2=0.4→0
    • 0.4 *2=0.8→0
    • 0.8 *2=1.6→1
    • 循环,得到二进制为:0.0011001100110011…

4. 将二进制转为浮点数

4.1 浮点数结构

  • 浮点数双精度(64位)
    • 结构:
      • 符号位:1位
      • 指数位:11位
      • 小数位:52位
    • 例如:
      • 0表示正数
      • 指数位为0时,对应的数为最小正数

4.2 加载0.1和0.2的浮点数值

  • 0.1的浮点数表示

    • 指数调整:
      • 小数点移动4位
    • 小数部分:
      • 从无限循环中取1开始的52位
    • 示例:
      • 指数:01111111011
      • 小数位:10011001100110011001100110011001100110011001100110011010
  • 0.2的浮点数表示

    • 指数调整:
      • 增加1位
    • 小数部分:
      • 取其循环节前52位
    • 示例:
      • 指数:01111111100
      • 小数位:10011001100110011001100110011001100110011001100110011010

5. 浮点数相加

5.1 指数位比较

  • 0.1的指数位:1019
  • 0.2的指数位:1020
  • 调整方法:
    • 0.1:减少1位偏移
    • 相加后,调整指数为1021

5.2 小数位相加

  • 最后得到的值:
    • 指数:01111111101
    • 小数位:
      • 第53位为1,舍去,得出结果的小数部分前52位
  • 结果:
    • 0.30000000000000004440…

6. 结论

  • 两次精度丢失

    • 转换为浮点数时,失去小数点后52位中的部分精度
      1. 每次小数位相加时,需要舍去第53位
  • 问题根源

    • 浮点数的精度限制

7. 如何解决(可选)

  • 使用toFixed限制小数位数
  • 自定义高精度计算函数
  • 8. 结论

    0.1 + 0.2 不等于 0.3 是因为浮点数运算过程中多次精度丢失,最终结果为0.3000000000000000444...,与0.3有微小差异。

    上一篇:前端配色
    下一篇:扁平化设计

    发表评论

    最新留言

    表示我来过!
    [***.240.166.169]2025年04月28日 04时53分30秒