JavaScript中 0.1+0.2==0.3 是否正确(附相加的计算过程)

        先上结论:0.1+0.2 == 0.3 在JavaScript中是错误的。

原因

        系统学习过计算机基础理论知识的都应该知道,计算机中的数据是以二进制存储的。相关的,我们想要比较两个数的大小,计算机又是怎样实现的呢,总不可能是直接像人脑一样经过看似简单实则复杂的方式进行对比。计算机的思考方式是非常简单,非0即1(没别的意思 /狗头)。

        首先来看Javascript是如何存储小数的

    JavaScirpt 使用 Number 类型来表示数字(整数或浮点数),遵循 IEEE 754 标准,通过 64 位来表示的一个number类型变量。

IEEE 754 标准定义如何用二进制来存储浮点数,根据公式:
V=(-1)N x M x 2^R(128=(-1)^(0)x1x2^7
其中:

  • N=为符号位,N=1,则为负数;N=0,则为正数
  • M=底数(尾数)
  • R=幂(指数)
    三部分(N、M、R)分开存储组成一个浮点数。
64位分别表示:
        1 符号位, 0 表示正数, 1 表示负数   N
        52 尾数,小数部分(即有效数字)  M      
        11 指数位(e)                                 R
       

   计算过程

        我们试着将0.1+0.2按照计算机的方式进行处理。

1.第一步,计算机首先将0.1和0.2解析成对应的二进制数然后存储。 

附一个链接可根据IEEE754 转换二进制:在线IEEE浮点二进制计算器工具 - ToolTT在线工具箱

0.1换成二进制为:0.0001100110011001100110011001100110011001100110011001101(无限循环)
0.2换成二进制为:0.0011001100110011001100110011001100110011001100110011011(无限循环)
----------------------------------------------------------------------------------
将无限循环的尾数截断至52位
  根据公式可以转换成:0.1=(-1)^0*1.1001100110011001100110011001100110011001100110011010(52)*2^(-4)
  根据公式可以转换成:0.2=(-1)^0*1.1001100110011001100110011001100110011001100110011010(52)*2^(-3)

2.第二步,想要计算0.1+0.2,需要进行对阶,即将指数部分取值相同,然后才能尾数相加。

对阶尾数后:
  0.1=(-1)^0*0.1100110011001100110011001100110011001100110011001101(52)*2^(-3)
  0.2=(-1)^0*1.1001100110011001100110011001100110011001100110011010(52)*2^(-3)

3.第三步尾数相加生成结果。 

 尾数相加之后为:  10.0110011001100110011001100110011001100110011001100111(52)
 转换成标准格式为:1.00110011001100110011001100110011001100110011001100111(53)   
        *****注意这里,现在的尾数是53位,不满足52位尾数的要求
        *****所以需要截断一位,js引擎在这里截断的结果是:
        1.0011001100110011001100110011001100110011001100110100(52)      
相加之后结果表示为:
0.1+0.2=
(-1)^0*1.0011001100110011001100110011001100110011001100110100(52)*2^(-2)
转换成十进制结果是:0.30000000000000004,结果并不等于0.3。

        结果显示为: 0.30000000000000004,与我们在nodejs环境下计算的结果一致。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值