为了账号安全,请及时绑定邮箱和手机立即绑定

JavaScript 如何解决数字计算的精度问题

标签:
JavaScript

我们前端在做计算过程中,特别时小数的计算,都会遇到意想不到的结果,通常我们在价格的计算中遇到很多问题,这是由于 JS 中的 Number 类型是一个浮点类型。

Nubmer 类型

我们先看看 JS 中的 Number 类型。它并不像其它的语言有不同的数字类型,例如:整型、长整型、浮点类型等等,定义不同的数字类型存储的空间也不一样。然而 JS 中的 Number 类型都是浮点类型并且存储空间为 8 数节(byte)(8*8 bit位)。其中Number 类型值的整数最多15位,小数最多17位。

注:1byte=8bit,1kb=1024byte,1mb=1024kb

精度问题

JS 中的 Number 是一个双精度浮点类型,双精度浮点类型在 64 位存储空间中的内容如下:

todo:

1位11位52位
符号位指数位小数位
0表示正,1表示负-1022~+1023任意

由于计算机在计算的过程中,会把十进制数字先转换成二进制,然后做运算,因为浮点类型的小数位的限制而截断了运算完的二进制,这时候再把它转换成了十进制就产生了精度的问题。

举个例子:
0.1 + 0.2 = ?

  • 0.1 转换成二进制:0.000110011001100110....

  • 0.2 转换成二进制:0.001100110011001100....

  • 0.000110011001100110.... + 0.001100110011001100.... = 0.0100110011001100110011001100110011001100110011001100...还很多,如果超过了 52 位就截断了。

  • 然后转换成十进制:0.30000000000000004

如何解决精度问题

简单的四舍五入

通过简单的四舍五入可以解决一些问题。

(0.1 + 0.2).toFixed(1);//0.3

换算成整型计算

当然这种四舍五入的方式明显是经不起考验的。彻底消除运算过程中的精度,需要将所有数字升位转化为整型了再做计算,计算完毕后再将最终结果进行相应的降位处理。

function add(num1, num2) {   var p1 = 0;   var p2 = 0;   if (num1.toString().split('.').length > 1) {
       p1 = num1.toString().split('.')[1].length;
   }   if (num2.toString().split('.').length > 1) {
       p2 = num2.toString().split(".")[1].length;
   }   var p = p1 > p2 ? p1 : p2;   var n1 = num1 * Math.pow(10, p);   var n2 = num2 * Math.pow(10, p);   var result = (n1 + n2) / Math.pow(10, p);   return result;
}

add(0.1, 0.2);//0.3




点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
Web前端工程师
手记
粉丝
12
获赞与收藏
135

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消