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 相关文章推荐
Opacity.js
Jan 22 Javascript
Javascript的时间戳和php的时间戳转换注意事项
Apr 12 Javascript
浅谈javascript中自定义模版
Jan 29 Javascript
简介AngularJS的HTML DOM支持情况
Jun 17 Javascript
jQuery加载及解析XML文件的方法实例分析
Jan 22 Javascript
jQuery、zepto、js常用小技巧
Feb 12 Javascript
node.js调用Chrome浏览器打开链接地址的方法
May 17 Javascript
vue-loader教程介绍
Jun 14 Javascript
vue2.0实现移动端的输入框实时检索更新列表功能
May 08 Javascript
如何在js代码中消灭for循环实例详解
Jul 29 Javascript
Vue实现远程获取路由与页面刷新导致404错误的解决
Jan 31 Javascript
JavaScript前端面试扁平数据转tree与tree数据扁平化
Jun 14 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短网址的生成代码(仿微博短网址)
2014/05/07 PHP
destoon二次开发常用数据库操作
2014/06/21 PHP
浅谈php使用curl模拟多线程发送请求
2019/03/08 PHP
JavaScript 未结束的字符串常量常见解决方法
2010/01/24 Javascript
关于图片的预加载过程中隐藏未知的
2012/12/19 Javascript
重构Javascript代码示例(重构前后对比)
2013/01/23 Javascript
jQuery中parents()方法用法实例
2015/01/07 Javascript
动态加载jQuery的两种方法实例分析
2015/07/17 Javascript
Javascript的无new构建实例详解
2016/05/15 Javascript
仅9张思维导图帮你轻松学习Javascript 就这么简单
2016/06/01 Javascript
jquery实用技巧之输入框提示语句
2016/07/28 Javascript
浅谈Angular.js中使用$watch监听模型变化
2017/01/10 Javascript
AngularJS Toaster使用详解
2017/02/24 Javascript
json字符串传到前台input的方法
2018/08/06 Javascript
ios中视频的最后一桢问题解决
2019/05/14 Javascript
在vue中动态修改css其中一个属性值操作
2020/12/07 Vue.js
[49:02]KG vs Infamous 2019国际邀请赛淘汰赛 败者组BO1 8.20.mp4
2020/07/19 DOTA
Python中列表(list)操作方法汇总
2014/08/18 Python
windows 下python+numpy安装实用教程
2017/12/23 Python
用Python下载一个网页保存为本地的HTML文件实例
2018/05/21 Python
78行Python代码实现现微信撤回消息功能
2018/07/26 Python
Python3简单实现串口通信的方法
2019/06/12 Python
Python 3.6 -win64环境安装PIL模块的教程
2019/06/20 Python
python跳出双层for循环的解决方法
2019/06/24 Python
TFRecord文件查看包含的所有Features代码
2020/02/17 Python
Python 实现微信自动回复的方法
2020/09/11 Python
联想哥伦比亚网上商城:Lenovo Colombia
2017/01/10 全球购物
澳大利亚吉他在线:Artist Guitars
2017/03/30 全球购物
贝佳斯官方网站:Borghese
2020/05/08 全球购物
成都思必达公司C#程序员招聘面试题
2013/06/26 面试题
Python面试题:Python是如何进行内存管理的
2014/08/04 面试题
咨询公司各岗位职责
2013/12/02 职场文书
营销总监岗位职责范本
2014/02/26 职场文书
2015年青年志愿者工作总结
2015/05/20 职场文书
2019广播稿怎么写
2019/04/17 职场文书
redis 存储对象的方法对比分析
2021/08/02 Redis