博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JS数字计算精度误差的解决方法
阅读量:4353 次
发布时间:2019-06-07

本文共 1610 字,大约阅读时间需要 5 分钟。

本篇文章主要是对javascript避免数字计算精度误差的方法进行了介绍,需要的朋友可以过来参考下,希望对大家有所帮助。

 

如果我问你 0.1 + 0.2 等于几?你可能会送我一个白眼,0.1 + 0.2 = 0.3 啊,那还用问吗?连幼儿园的小朋友都会回答这么小儿科的问题了。但是你知道吗,同样的问题放在编程语言中,或许就不是想象中那么简单的事儿了。

不信?我们可以做个试验。

先来看一段 JS。

var num1 = 0.1;var num2 = 0.2;alert(num1+num2 === '0.3');

执行结果是 false。没错,当我第一次看到这段代码时,我也理所当然地以为它是 true,但是执行结果让我大跌眼镜,是我的打开方式不对吗?非也非也。我们再执行以下代码试试就知道结果为什么是 false 了。

var num1 = 0.1; var num2 = 0.2; alert( num1+numB );

原来,0.1 + 0.2 = 0.30000000000000004。是不是很奇葩?其实对于浮点数的四则运算,几乎所有的编程语言都会有类似精度误差的问题,只不过在 C++/C#/Java 这些语言中已经封装好了方法来避免精度的问题,

而 JavaScript 是一门弱类型的语言,从设计思想上就没有对浮点数有个严格的数据类型,所以精度误差的问题就显得格外突出。下面就分析下为什么会有这个精度误差,以及怎样修复这个误差。

 

首先,我们要站在计算机的角度思考 0.1 + 0.2 这个看似小儿科的问题。我们知道,能被计算机读懂的是二进制,而不是十进制,所以我们先把 0.1 和 0.2 转换成二进制看看:

0.1==》0.1.toString(2)==》0.0001100110011(无限循环..)

0.2==》0.2.toString(2)==》0.001100110011(无限循环..)

双精度浮点数的小数部分最多支持 52 位,所以两者相加之后得到这么一串 0.0100110011001100110011001100110011001100110011001100 因浮点数小数位的限制而截断的二进制数字,这时候,我们再把它转换为十进制,就成了 0.30000000000000004。

原来如此,那怎么解决这个问题呢?我想要的结果就是 0.1 + 0.2 === 0.3 啊!!!

有种最简单的解决方案,就是给出明确的精度要求,在返回值的过程中,计算机会自动四舍五入,

比如:

var num1 = 0.1; var num2 = 0.2; alert( parseFloat((num1 + num2).toFixed(2)) === 0.30 );

但是四舍五入明显不是一劳永逸的办法。

如果有一个方法能帮我们解决这些浮点数的精度问题,那该多好!所以,我们就自己写一个方法。

我们来试试下面这个方法:

formatNum = function(f, digit) {     var m = Math.pow(10, digit);     return parseInt(f * m, 10) / m; }

 var num1 = 0.1; 

 var num2 = 0.2;

 alert(formatNum(num1 + num2, 1) === 0.3);

这个方法是什么意思呢?

为了避免产生精度差异,我们要把需要计算的数字乘以 10 的 n 次幂,换算成计算机能够精确识别的整数,然后再除以 10 的 n 次幂,大部分编程语言都是这样处理精度差异的,我们就借用过来处理一下 JS 中的浮点数精度误差。

所以如果下次再有人问你 0.1 + 0.2 等于几,你可要小心回答咯!!

 

转载于:https://www.cnblogs.com/wymbk/p/6031442.html

你可能感兴趣的文章
JDBC原生态代码
查看>>
韩版可爱小碎花创意家居收纳挂袋
查看>>
计算机基础之硬件
查看>>
python操作mysql ------- SqlAchemy正传
查看>>
如何使用 JSP JSTL 显示/制作树(tree) 菜单
查看>>
12.5号
查看>>
lintcode-medium-Binary Tree Zigzag Level Order Traversal
查看>>
logrotate日志切割
查看>>
POJ-3253 Fence Repair 贪心
查看>>
Arraylist集合遍历输出
查看>>
java中的选择结构与循环结构
查看>>
无法将类型“ASP.login_aspx”转换为“System.Web.UI.WebControls.Login”
查看>>
[cocos2dx] lua注册回调到c++
查看>>
(treap)[bzoj3224][洛谷3369][cogs1829]Tyvj 1728 普通平衡树
查看>>
Linux下常用的shell命令记录
查看>>
HTTP 常用 Header 讲解
查看>>
linux分割字符串操作
查看>>
PHP学习2
查看>>
多实例Mysql配置
查看>>
linux下安装Mongodb
查看>>