Javascript 浮点运算精度问题分析与解决


Posted in Javascript onMarch 26, 2014

分析

JavaScript 只有一种数字类型 Number ,而且在Javascript中所有的数字都是以IEEE-754标准格式表示的。 浮点数的精度问题不是JavaScript特有的,因为有些小数以二进制表示位数是无穷的:

十进制           二进制
0.1              0.0001 1001 1001 1001 ...
0.2              0.0011 0011 0011 0011 ...
0.3              0.0100 1100 1100 1100 ...
0.4              0.0110 0110 0110 0110 ...
0.5              0.1
0.6              0.1001 1001 1001 1001 ...

所以比如 1.1 ,其程序实际上无法真正的表示 ‘1.1',而只能做到一定程度上的准确,这是无法避免的精度丢失:

1.09999999999999999

在JavaScript中问题还要复杂些,这里只给一些在Chrome中测试数据:

 输入               输出
1.0-0.9 == 0.1     False
1.0-0.8 == 0.2     False
1.0-0.7 == 0.3     False
1.0-0.6 == 0.4     True
1.0-0.5 == 0.5     True
1.0-0.4 == 0.6     True
1.0-0.3 == 0.7     True
1.0-0.2 == 0.8     True
1.0-0.1 == 0.9     True

解决

那如何来避免这类 1.0-0.9 != 0.1 的非bug型问题发生呢?下面给出一种目前用的比较多的解决方案, 在判断浮点运算结果前对计算结果进行精度缩小,因为在精度缩小的过程总会自动四舍五入:

(1.0-0.9).toFixed(digits)                   // toFixed() 精度参数须在 0 与20 之间
parseFloat((1.0-0.9).toFixed(10)) === 0.1   // 结果为True
parseFloat((1.0-0.8).toFixed(10)) === 0.2   // 结果为True
parseFloat((1.0-0.7).toFixed(10)) === 0.3   // 结果为True
parseFloat((11.0-11.8).toFixed(10)) === -0.8   // 结果为True

方法提炼
// 通过isEqual工具方法判断数值是否相等
function isEqual(number1, number2, digits){
 digits = digits == undefined? 10: digits; // 默认精度为10
 return number1.toFixed(digits) === number2.toFixed(digits);
}
isEqual(1.0-0.7, 0.3);  // return true
// 原生扩展方式,更喜欢面向对象的风格
Number.prototype.isEqual = function(number, digits){
 digits = digits == undefined? 10: digits; // 默认精度为10
 return this.toFixed(digits) === number.toFixed(digits);
}
(1.0-0.7).isEqual(0.3); // return true
Javascript 相关文章推荐
jquery div 居中技巧应用介绍
Nov 24 Javascript
jquery无刷新验证邮箱地址实现实例
Feb 19 Javascript
javascript实现依次输入input自动定焦
Dec 23 Javascript
angularjs 源码解析之scope
Aug 22 Javascript
JS 实现计算器详解及实例代码(一)
Jan 08 Javascript
微信小程序 基础组件与导航组件详细介绍
Feb 21 Javascript
jQuery Plupload上传插件的使用
Apr 19 jQuery
Angular.js组件之input mask对input输入进行格式化详解
Jul 10 Javascript
Webpack实战加载SVG的方法
Dec 26 Javascript
vue better-scroll插件使用详解
Jan 25 Javascript
JavaScript代理模式原理与用法实例详解
Mar 10 Javascript
js利用iframe实现选项卡效果
Aug 09 Javascript
javascript 3d 逐侦产品展示(核心精简)
Mar 26 #Javascript
Node.js模拟浏览器文件上传示例
Mar 26 #Javascript
JavaScript关闭当前页面(窗口)不带任何提示
Mar 26 #Javascript
JavaScript数字和字符串转换示例
Mar 26 #Javascript
jquery实现瀑布流效果分享
Mar 26 #Javascript
jquery实现效果比较好的table选中行颜色
Mar 25 #Javascript
Jquery对数组的操作技巧整理
Mar 25 #Javascript
You might like
超小PHP小马小结(方便查找后门的朋友)
2012/05/05 PHP
浅析PHP程序防止ddos,dns,集群服务器攻击的解决办法
2013/06/18 PHP
php数组使用规则分析
2015/02/27 PHP
PHP的压缩函数实现:gzencode、gzdeflate和gzcompress的区别
2016/01/27 PHP
Composer设置忽略版本匹配的方法
2016/04/27 PHP
PHP面试常用算法(推荐)
2016/07/22 PHP
php组合排序简单实现方法
2016/10/15 PHP
laravel 框架执行流程与原理简单分析
2020/02/01 PHP
jQuery基础知识小结
2014/12/22 Javascript
JavaScript替换当前页面的方法
2015/04/03 Javascript
JQuery悬停控制图片轮播——代码简单
2015/08/05 Javascript
jQuery实现文本框邮箱输入自动补全效果
2015/11/17 Javascript
Bootstrap源码解读表单(2)
2016/12/22 Javascript
input输入密码变黑点密文的实现方法
2017/01/09 Javascript
详解关于JSON.parse()和JSON.stringify()的性能小测试
2019/03/14 Javascript
vue.js中ref和$refs的使用及示例讲解
2019/08/14 Javascript
使用js和canvas实现时钟效果
2020/09/08 Javascript
解决vuex改变了state的值,但是页面没有更新的问题
2020/11/12 Javascript
[00:59]PWL开团时刻DAY7——我在赶
2020/11/06 DOTA
Python编程实现及时获取新邮件的方法示例
2017/08/10 Python
Python使用itertools模块实现排列组合功能示例
2018/07/02 Python
python使用正则表达式来获取文件名的前缀方法
2018/10/21 Python
python 随机打乱 图片和对应的标签方法
2018/12/14 Python
Python如何操作office实现自动化及win32com.client的运用
2020/04/01 Python
通过代码实例了解Python异常本质
2020/09/16 Python
详解基于Facecognition+Opencv快速搭建人脸识别及跟踪应用
2021/01/21 Python
虚拟环境及venv和virtualenv的区别说明
2021/02/05 Python
HTML5通用接口详解
2016/06/12 HTML / CSS
北京-环亚运商测试题.net程序员初步测试题
2013/05/28 面试题
String s = new String(“xyz”);创建了几个String Object?
2015/08/05 面试题
库房保管员岗位职责
2014/04/07 职场文书
企业安全生产月活动总结
2014/07/05 职场文书
2016应届毕业生实习心得体会
2015/10/09 职场文书
漫画「处刑少女的生存之道」第3卷封面公开
2022/03/21 日漫
vue 自定义的组件绑定点击事件
2022/04/21 Vue.js
搭建Yolov5服务器
2022/04/30 Servers