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的Repeater实现代码
Jul 17 Javascript
新发现一个骗链接的方法(js读取cookies)
Jan 11 Javascript
js中parseFloat(参数1,参数2)定义和用法及注意事项
Jan 27 Javascript
js中继承的几种用法总结(apply,call,prototype)
Dec 26 Javascript
JavaScript实现存储HTML字符串示例
Apr 21 Javascript
使用JQuery实现Ctrl+Enter提交表单的方法
Oct 22 Javascript
bootstrap Validator 模态框、jsp、表单验证 Ajax提交功能
Feb 17 Javascript
解决jquery appaend元素中id绑定事件失效的问题
Sep 12 jQuery
Vue.js实现分页查询功能
Nov 15 Javascript
vue.js实现备忘录demo
Jun 26 Javascript
vue分页插件的使用方法
Dec 25 Javascript
vue首次渲染全过程
Apr 21 Vue.js
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生成带有雪花背景的验证码
2008/09/28 PHP
php 字符过滤类,用于过滤各类用户输入的数据
2009/05/27 PHP
PHP setTime 设置当前时间的代码
2012/08/27 PHP
php preg_replace替换实例讲解
2013/11/04 PHP
PHP在线书签系统分享
2016/01/04 PHP
解析PHP的Yii框架中cookie和session功能的相关操作
2016/03/17 PHP
PHP中ltrim()函数的用法与实例讲解
2019/03/28 PHP
javascript 得到变量类型的函数
2010/05/19 Javascript
理解Javascript_06_理解对象的创建过程
2010/10/15 Javascript
7个JS基础知识总结
2014/03/05 Javascript
JS实现先显示大图后自动收起显示小图的广告代码
2015/09/04 Javascript
javascript实现简单加载随机色方块
2015/12/25 Javascript
原生javascript实现匀速运动动画效果
2016/02/26 Javascript
JavaScript数组的栈方法与队列方法详解
2016/05/26 Javascript
一种Javascript解释ajax返回的json的好方法(推荐)
2016/06/02 Javascript
JavaScript蒙板(model)功能的简单实现代码
2016/08/04 Javascript
让bootstrap的carousel支持滑动滚屏的实现代码
2017/11/27 Javascript
vue移动端实现下拉刷新
2018/04/22 Javascript
vue弹窗插件实战代码
2018/09/08 Javascript
详解微信小程序缓存--缓存时效性
2019/05/02 Javascript
微信公众号服务器验证Token步骤图解
2019/12/30 Javascript
JS删除数组指定值常用方法详解
2020/06/04 Javascript
vue3.0生命周期的示例代码
2020/09/24 Javascript
python实现爬虫统计学校BBS男女比例之数据处理(三)
2015/12/31 Python
OpenCV实现人脸识别
2017/04/07 Python
python中property属性的介绍及其应用详解
2019/08/29 Python
pycharm 2020.2.4 pip install Flask 报错 Error:Non-zero exit code的问题
2020/12/04 Python
服装设计专业毕业生推荐信
2013/11/09 职场文书
幼儿园教师工作制度
2014/01/22 职场文书
领导欢迎词范文
2015/01/26 职场文书
2015年国际护士节演讲稿
2015/03/18 职场文书
防卫过当辩护词
2015/05/21 职场文书
背起爸爸上学观后感
2015/06/08 职场文书
《比尾巴》教学反思
2016/02/24 职场文书
教你用Python写一个植物大战僵尸小游戏
2021/04/25 Python
python 算法题——快乐数的多种解法
2021/05/27 Python