Javascript 浮点运算的问题分析与解决方法


Posted in Javascript onAugust 27, 2013

十进制           二进制
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函数
Aug 01 Javascript
什么是JavaScript
Aug 13 Javascript
javascipt:filter过滤介绍及使用
Sep 10 Javascript
JS+CSS实现分类动态选择及移动功能效果代码
Oct 19 Javascript
基于JavaScript实现拖动滑块效果
Feb 16 Javascript
js实现移动端编辑添加地址【模仿京东】
Apr 28 Javascript
JS解决position:sticky的兼容性问题的方法
Oct 17 Javascript
IE9 elementUI文件上传的问题解决
Oct 17 Javascript
vue自动路由-单页面项目(非build时构建)
Apr 30 Javascript
JavaScript定时器设置、使用与倒计时案例详解
Jul 08 Javascript
jQuery实现消息弹出框效果
Dec 10 jQuery
Javascript执行流程细节原理解析
May 14 Javascript
js中点击空白区域时文本框与隐藏层的显示与影藏问题
Aug 26 #Javascript
关于IE中getElementsByClassName不能用的问题解决方法
Aug 26 #Javascript
关于Jquery操作Cookie取值错误的解决方法
Aug 26 #Javascript
jquery弹出框的用法示例(2)
Aug 26 #Javascript
jquery弹出框的用法示例(一)
Aug 26 #Javascript
jQuery快速上手:写jQuery与直接写JS的区别详细解析
Aug 26 #Javascript
使用js实现雪花飘落效果
Aug 26 #Javascript
You might like
为什么《星际争霸》是测试人工智能的理想战场
2019/12/03 星际争霸
php zlib压缩和解压缩swf文件的代码
2008/12/30 PHP
PHPMYADMIN 简明安装教程 推荐
2010/03/07 PHP
jQuery 源码分析笔记
2011/05/25 PHP
使图片旋转的3种解决方案
2013/11/21 Javascript
Google (Local) Search API的简单使用介绍
2013/11/28 Javascript
jQuery 获取屏幕高度、宽度的简单实现案例
2016/05/17 Javascript
JS使用正则表达式过滤多个词语并替换为相同长度星号的方法
2016/08/03 Javascript
javascript中this用法实例详解
2017/04/06 Javascript
JavaScript通过mouseover()实现图片变大效果的示例
2017/12/20 Javascript
vue实现2048小游戏功能思路详解
2018/05/09 Javascript
Vue axios全局拦截 get请求、post请求、配置请求的实例代码
2018/11/28 Javascript
详解Vue2 添加对scss的支持
2019/01/02 Javascript
Node.js学习教程之Module模块
2019/09/03 Javascript
微信内置开发 iOS修改键盘换行为搜索的解决方案
2019/11/06 Javascript
Python 中pandas.read_excel详细介绍
2017/06/23 Python
python线程池threadpool实现篇
2018/04/27 Python
Python爬取qq空间说说的实例代码
2018/08/17 Python
Python基础学习之函数方法实例详解
2019/06/18 Python
python利用蒙版抠图(使用PIL.Image和cv2)输出透明背景图
2020/08/04 Python
美国在线购物频道:Shop LC
2019/04/21 全球购物
Linux的文件类型
2012/03/07 面试题
怎样声明一个匿名的内部类
2016/06/01 面试题
实习生个人的自我评价
2013/12/08 职场文书
大学班长的职责
2014/01/27 职场文书
初中生自我鉴定
2014/02/04 职场文书
《口技》教学反思
2014/02/21 职场文书
个人投资计划书
2014/05/01 职场文书
最美护士演讲稿
2014/08/27 职场文书
学期个人自我总结
2015/02/13 职场文书
会议主持词结束语
2015/07/03 职场文书
婚宴祝酒词大全
2015/08/10 职场文书
在酒桌上的敬酒词
2015/08/12 职场文书
深入理解go缓存库freecache的使用
2022/02/15 Golang
vue实现列表垂直无缝滚动
2022/04/08 Vue.js
《火纹风花雪月无双》预告“神秘雇佣兵” 紫发剑客
2022/04/13 其他游戏