前端面试题——0.1+0.2为什么不等于0.3?

本文解释了为什么在计算机中0.1+0.2不等于0.3,涉及到JavaScript中的浮点数表示、IEEE754标准和二进制表示的局限性。通过toFixed方法可以解决这种精度问题。
摘要由CSDN通过智能技术生成

前言

0.1+0.2=0.3在我们的日常生活中是简单到不用动脑子就能得出的等式。但是在计算机的世界中恐怕并非如此,你或许在编写代码时见过0.1+0.2=0.30000000000000004,是计算机算错了吗?让我们来探究其背后的原理。

原理

首先我们要知道:Javascript的数字型数据并不区分整数还是小数,而只有number,即1===1.00,同时采用的是IEEE754的64位双精度版本,由三部分组成:

  • 1位数符(sign bit,记为S):标记正负,0为正,1为负
  • 11位阶码(exponent,记为E):数字的整数部分
  • 52位尾数(mantissa,记为M):数字的小数部分的期望

计算机是以二进制的方式存储数据的,而0.1的二进制表达为:

0.1 = 0.0(0011)(0011)(0011)(0011)....

是一个无限循环小数,在 IEEE 754 中,循环位就不能在无限循环下去了,在双精确度 64 位下最多存储的有效整数位数为 52 位,会采用 就近舍入(round to nearest)模式(进一舍零) 进行存储

11001100110011001100110011001100110011001100110011001 // M 舍去首位的 1,得到如下
1001100110011001100110011001100110011001100110011001 // 0 舍 1 入,得到如下
1001100110011001100110011001100110011001100110011010 // 最终存储

结论

因为浮点数自身小数位数的限制而截断的二进制在转化为十进制,就变0.30000000000000004,所以在计算时会产生误差。

运算过程

算法:
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.6*2=1.2 ----------- 取出整数部分1

0.2*2=0.4 ----------- 取出整数部分0
0.4*2=0.8 ----------- 取出整数部分0
0.8*2=1.6 ----------- 取出整数部分1
0.6*2=1.2 ----------- 取出整数部分1

我们可以发现在无限循环
0.1的二进制结果 0.0 0011 0011 0011 .....  "0011的无限循环"
0.2的二进制结果 0.0011 0011 0011 0011 .... "0011的无限循环"

取52位进行计算
0.1  =  0.0001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001
0.2 =   0.0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011

计算的结果是: 0.0100 1100 1100 1100 1100 1100 1100 1100 1100 1100 1100 1100 ...也是无限循环

将二进制转换为十进制:
浮点型数据存储转换为十进制的话 只会取前17位
0.300000000000000044408920958 .... = 0.30000000000000004(四舍五入)
所以0.1+0.2的结果是等于0.30000000000000004

解决办法

使用toFixed方法,toFixed方法可以指定运算结果的小数点后的指定位数的数字,使保留一位小数就是toFixed(1)

let x=parseFloat((0.1+0.2).toFixed(1));
//使用toFixed方法将number转换成了string,再使用parseFloat转回number
console.log(x===0.3);
//打印结果:true

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值