0.1+0.2等于几?

0.1+0.2等于0.3吗?这好像是一个小学生就能解答的问题。

但是在JavaScript中,这个问题的答案可就不一定了。为什么呢?学习一下,写个笔记。

在JavaScript中,数字是Number类型,此类型使用IEEE 754格式表示整数和浮点数。储存整数比较好理解,但储存浮点数值的内存会消耗更多一些,是整数值的两倍内存,所以ECMAScript总是想方设法把用不着小数的浮点数转化成整数。这个特性会让一些小数点后全为0的小数显示为整数,可是这只是一个显示格式的问题,但对于值而言不会出错,但对于有些计算而言,就会出一些要命的错误。

很明显,这不是我们想要的结果。

其实这要从IEEE 754这个标准的浮点数开始说起。 它规定双精度浮点数的长度为64个二进制位,最高1位是符号位,后11位是指数部分,剩下的52位是小数部分。符号位决定了数字的正负,指数部分决定数的大小,小数部分决定了数字的精度。众所周知,在计算机中的存储是二进制的,数值相加到计算机内计算时都是体现成二进制的(这里暂时没补码什么事),那么,先尝试把0.1和0.2转化成二进制小数吧。

然后开始了无尽的计算…

(0.1)2=0.0001100110011001…

(0.2)2=0.0011001100110011…

可以发现,这两个数字的二进制是无限的。由于小数部分最多支持52位,所以在IEEE 754标准下,到了52位之后数字就会被截断,只能拿在它之前的数值进行计算,这样的计算是存在误差的,然后就得到了这个出现错误的结果。

如何解决?方法有很多。

  • 使用toFixed()方法进行保留x位小数,适合于计算有精度要求的情况,但是这种情况并不能满足全部可能。

  • 把需要计算的数字同时倍增放大一个给定的倍数,放大到都是整数,然后在整数下进行计算,计算完毕后再缩回来。

  • 把精确数值计算的任务丢给后端。

  • 采用第三方库Math.jsdecimal.jsbig.js等,完成计算操作。

打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2018-2021 Shawn Zhou
  • Hexo 框架强力驱动 | 主题 - Ayer
  • 访问人数: | 浏览次数:

感谢打赏~

支付宝
微信