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 定时器调用传递参数的方法
Nov 12 Javascript
jquery使用$(element).is()来判断获取的tagName
Aug 24 Javascript
JavaScript中操作Mysql数据库实例
Apr 02 Javascript
jQuery检测输入的字符串包含的中英文的数量
Apr 17 Javascript
javascript封装 Cookie 应用接口
Aug 07 Javascript
jQuery获取及设置表单input各种类型值的方法小结
May 24 Javascript
ES6学习之变量的解构赋值
Feb 12 Javascript
vue的style绑定background-image的方式和其他变量数据的区别详解
Sep 03 Javascript
JS实现的自定义map方法示例
May 17 Javascript
js中console在一行内打印字符串和对象的方法
Sep 10 Javascript
Vue实现开关按钮拖拽效果
Sep 22 Javascript
Node 使用express-http-proxy 做api网关的实现
Oct 15 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中var_dump,var_export,print_r三个函数的区别
2013/06/21 PHP
Eclipse的PHP插件PHPEclipse安装和使用
2014/07/20 PHP
php处理单文件、多文件上传代码分享
2016/08/24 PHP
PHP/ThinkPHP实现批量打包下载文件的方法示例
2017/07/31 PHP
随机显示经典句子或诗歌的javascript脚本
2007/08/04 Javascript
myFocus slide3D v1.1.0 使用方法与下载
2011/01/12 Javascript
写自已的js类库需要的核心代码
2012/07/16 Javascript
Javascript页面跳转常见实现方式汇总
2015/11/28 Javascript
详解nodeJS中读写文件方法的区别
2017/03/06 NodeJs
JS实现的倒计时恢复按钮点击功能【可用于协议阅读倒计时】
2018/04/19 Javascript
微信小程序实现刷脸登录
2018/05/25 Javascript
Puppeteer环境搭建的详细步骤
2018/09/21 Javascript
浅谈JavaScript 代码整洁之道
2018/10/23 Javascript
layer.prompt使文本框为空的情况下也能点击确定的方法
2019/09/24 Javascript
element-ui中dialog弹窗关闭按钮失效的解决
2020/09/22 Javascript
python正则表达式中的括号匹配问题
2014/12/14 Python
Python对列表中的各项进行关联详解
2017/08/15 Python
Python搜索引擎实现原理和方法
2017/11/27 Python
pandas数据框,统计某列数据对应的个数方法
2018/04/11 Python
Python爬取qq空间说说的实例代码
2018/08/17 Python
对python 通过ssh访问数据库的实例详解
2019/02/19 Python
使用python实现kNN分类算法
2019/10/16 Python
Python爬取爱奇艺电影信息代码实例
2019/11/26 Python
TensorFlow实现checkpoint文件转换为pb文件
2020/02/10 Python
Python实例教程之检索输出月份日历表
2020/12/16 Python
俄罗斯街头服装品牌:Black Star Wear
2017/03/01 全球购物
FORZIERI福喜利中国官网:奢侈品购物梦工厂
2019/05/03 全球购物
德国高尔夫商店:Par71.de
2020/11/29 全球购物
优秀中专生推荐信
2013/11/17 职场文书
表彰会主持词
2014/03/26 职场文书
教学改革问题查摆整改措施
2014/09/27 职场文书
工作保证书怎么写
2015/02/28 职场文书
2015社区健康教育工作总结
2015/05/20 职场文书
美丽的大脚观后感
2015/06/03 职场文书
公司要求试用期员工提交“述职报告”,该怎么写?
2019/07/17 职场文书
行政后勤人员工作计划应该怎么写?
2019/08/16 职场文书