开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第8天,点击查看活动详情
前言
在面试的时候经常会被问道0.1+0.2等于多少,自己心里第一反应等于0.3,但是又清楚面试官肯定不会问这么简单的问题而不敢说出来,最后面试失败回去查结果发现答案是0.30000000000000004,即使面试中没遇到,在实际工作中也非常可能会遇到
小数精度问题
要解决这个问题就先抛开1+1=2的观念,在计算机的角度,输入一个数字是如何存储起来的?其实计算机是二进制的方式存储的,也就是用0和1存储,没有其他数字的了
还有一个就是考虑二进制的存储容量,javascript采用了IEEE754标准来规定数字,IEEE754标准有几种表示方式:
- 单精度
- 双精度(64位)
- 延伸单精度
- 延伸双精度
javascript采用的就是双精度(64位),意思就是由0或1组成的64位,而IEEE754标准将64位分成了三个部分:
了解指数位和有效数之前先了解科学计数法,例如十进制的24在二进制表示11000,而二进制数11000表示为11E4,E后面的数字是指数,然后使用科学计数法二进制11000就是1.1 * 2的四次方,数字越大用科学计数法就越节省空间
64位的指数位存储科学计数法的指数也就是2的四次方,有效数存储1.1这个数,但是十进制数字和在计算机里的二进制数字是有差别的,小数转二进制是无限长度的,有效数就无法存储这个无线长度,计算机就取一个近似的数字,所以0.1和0.2转为十进制就不是纯正的0.3了
解决方法
1.使用toFixed()方法保留指定小数位,然后使用parseFloat()转为小数
2.使用第三方的math库
//统一配置math.js
math.config({
number: 'BigNumber',
// 'number' (default),
precision: 20
});
// 转换数字类型
var temp = math.bignumber(a) * math.bignumber(b)
// 提取数字类型,不然会是一个math对象
var result = math.number(temp)