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 相关文章推荐
禁用页面部分JavaScript方法的具体实现
Jul 31 Javascript
JavaScript数值转换的三种方式总结
Jul 31 Javascript
在HTML中插入JavaScript代码的示例
Jun 03 Javascript
DEDECMS如何为文章添加HOT NEW标志图片
Aug 14 Javascript
JavaScript基础篇(3)之Object、Function等引用类型
Nov 30 Javascript
jQuery实现的兼容性浮动层示例
Aug 02 Javascript
JS中Object对象的原型概念基础
Jan 29 Javascript
Angular5中状态管理的实现
Sep 03 Javascript
js实现拾色器插件(ColorPicker)
May 21 Javascript
js实现弹窗效果
Aug 09 Javascript
JS监听Esc 键触发事键
Apr 14 Javascript
react 路由Link配置详解
Nov 11 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动态创建Flash动画
2006/10/09 PHP
php类
2006/11/27 PHP
两级联动select刷新后其值保持不变的实现方法
2014/01/27 PHP
ThinkPHP3.1新特性之Action参数绑定
2014/06/19 PHP
php有效防止同一用户多次登录
2015/11/19 PHP
php实现面包屑导航例子分享
2015/12/19 PHP
php闭包中使用use声明变量的作用域实例分析
2018/08/09 PHP
laravel框架模型和数据库基础操作实例详解
2020/01/25 PHP
jQuery 创建Dom元素
2010/05/07 Javascript
19个很有用的 JavaScript库推荐
2011/06/27 Javascript
bootstrap data与jquery .data
2014/07/07 Javascript
jquery动态分页效果堪比时光网
2014/09/25 Javascript
如何在MVC应用程序中使用Jquery
2014/11/17 Javascript
jQuery中prepend()方法用法实例
2014/12/25 Javascript
使用window.prompt()实现弹出用户输入的对话框
2015/04/13 Javascript
bootstrap布局中input输入框右侧图标点击功能
2016/05/16 Javascript
Jquery修改image的src属性,图片不加载问题的解决方法
2016/05/17 Javascript
浅谈js内置对象Math的属性和方法(推荐)
2016/09/19 Javascript
vue.js表格组件开发的实例详解
2016/10/12 Javascript
JavaScript 有用的代码片段和 trick
2018/02/22 Javascript
Auto.js自动收取自己和好友蚂蚁森林能量脚本
2018/06/28 Javascript
Angular5.0 子组件通过service传递值给父组件的方法
2018/07/13 Javascript
优雅地使用loading(推荐)
2019/04/20 Javascript
mock.js模拟前后台交互
2019/07/25 Javascript
python实现人人网登录示例分享
2014/01/19 Python
Python中的魔法方法深入理解
2014/07/09 Python
将Emacs打造成强大的Python代码编辑工具
2015/11/20 Python
python九九乘法表的实例
2017/09/26 Python
TensorFlow搭建神经网络最佳实践
2018/03/09 Python
Django高级编程之自定义Field实现多语言
2019/07/02 Python
加拿大时尚少女服装品牌:Garage
2016/10/10 全球购物
境外导游求职信
2014/02/27 职场文书
《美丽的黄昏》教学反思
2014/02/28 职场文书
党员评议自我评价
2015/03/03 职场文书
Mysql systemctl start mysqld报错的问题解决
2021/06/03 MySQL
淡雅古典唯美少女娇媚宁静迷人写真
2022/03/21 杂记