0.1 + 0.2 !== 0.3 就是要说清楚因为个啥?

javascript(简称js)中的数字使用的是国际标准 IEEE 754,因为js是弱类型语言,为了方便省事,所有数字都是以64位浮点数形式储存。也就是说,js语言底层根本没有整数,所有数字都是小数(64位浮点数)!

当我们开心的进行着整数计算的时候,其实js都在算小数(莫名悲伤)。

整数算起来时没有问题的,但当你直接计算小数的时候,就麻烦了:0.1+0.2 不等于0.3

1 + 2 === 3 //true

0.1 + 0.2 === 0.3 //false

0.1 + 0.2 // 0.30000000000000004

这坑咋回事?

原来,0.1是十进制的,转成2进制以后,就是一个无限循环小数了!简单来说,就是2进制里表示1/10的难度跟你在10进制里表示1/3是一样一样的。

十进制的0.1用二进制表示为:0.0 0011 0011 0011 0011…,循环部分是0011

同样的0.2就是1/5

十进制0.2用二进制表示为:0.0011 0011 0011 0011…,循环部分是0011

上边我们也说了,用的这个标准,叫IEEE 754,这个标准里边,最多存52个尾数,也就是转换为科学记数法以后,尾数最多52个,循环小数到这里就被切断了,只留下前边52位。

那这两个浮点数就不准了啊,就有误差了,带着这两个误差进行加法计算,得到的数也就不准了,所以才会出现

0.1 + 0.2 !== 0.3 //true

反过来说,但凡用二进制表示一个浮点数时,出现了无理数的情况,这个浮点数运算都是不准的。

哪些浮点数会变成二进制里的无理数?一个一个记住太麻烦了,只要记住,只要用js算浮点数就会有误差就好了!

那么问题来了,我们如果要用浮点数计算,怎么搞定这个误差呢?

可以设置一个你可以接受的计算精度来完成啦。es6里新增的Number.EPSILON就可以实现啦,这个值就代表了2的负52次方啦

let yourSet = 52 - 10; //精度设置为小数点后10位小数
let yourTolerance = Number.EPSILON * Math.pow(2, yourSet);

只要保证计算结果误差小于你设置的误差就好了,或者你可以直接用Math里的floor,ceil,round等方法来去掉多余的小数位哦。

不知道各位同学搞明白了吗?

posted @ 2018-02-22 23:57  拿饭盒当烟灰缸  阅读(450)  评论(0编辑  收藏  举报