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 相关文章推荐
父子窗体间传递JSON格式的数据的代码
Dec 25 Javascript
JQuery在页面中添加和除移DOM示例代码
Jun 24 Javascript
关闭页面window.location事件未执行的原因及解决方法
Sep 01 Javascript
前端js实现文件的断点续传 后端PHP文件接收
Oct 14 Javascript
利用jquery获取select下拉框的值
Nov 23 Javascript
Vue添加请求拦截器及vue-resource 拦截器使用
Nov 23 Javascript
js 公式编辑器 - 自定义匹配规则 - 带提示下拉框 - 动态获取光标像素坐标
Jan 04 Javascript
Element-UI Table组件上添加列拖拽效果实现方法
Apr 14 Javascript
JavaScript模板引擎原理与用法详解
Dec 24 Javascript
Angular中使用ng-zorro图标库部分图标不能正常显示问题
Apr 22 Javascript
解决Vue打包上线之后部分CSS不生效的问题
Nov 12 Javascript
Node使用koa2实现一个简单JWT鉴权的方法
Jan 26 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 strtotime函数详解
2009/12/18 PHP
PHP实现的简单mock json脚本分享
2015/02/10 PHP
php结合安卓客户端实现查询交互实例
2015/05/05 PHP
js实现瀑布流的一种简单方法实例分享
2013/11/04 Javascript
jQuery使用ajaxSubmit()提交表单示例
2014/04/04 Javascript
js不能获取隐藏的div的宽度只能先显示后获取
2014/09/04 Javascript
JavaScript判断IE版本型号
2015/07/27 Javascript
Angular 应用技巧总结
2016/09/14 Javascript
轻松搞定js表单验证
2016/10/13 Javascript
javascript遍历json对象的key和任意js对象属性实例
2017/03/09 Javascript
JavaScript注册时密码强度校验代码
2017/06/30 Javascript
vue中获取滚动table的可视页面宽度调整表头与列对齐(每列宽度不都相同)
2019/08/17 Javascript
Vue 实现分页与输入框关键字筛选功能
2020/01/02 Javascript
详解python基础之while循环及if判断
2017/08/24 Python
深入学习Python中的上下文管理器与else块
2017/08/27 Python
Python实现的求解最大公约数算法示例
2018/05/03 Python
python中验证码连通域分割的方法详解
2018/06/04 Python
Selenium(Python web测试工具)基本用法详解
2018/08/10 Python
python变量赋值方法(可变与不可变)
2019/01/12 Python
python常用数据重复项处理方法
2019/11/22 Python
Python线程协作threading.Condition实现过程解析
2020/03/12 Python
PyQt5实现画布小程序
2020/05/30 Python
python实现图片转字符画的完整代码
2021/02/21 Python
中东奢侈品购物网站:Ounass
2020/09/02 全球购物
Python面试题集
2012/03/08 面试题
毕业生自荐书
2013/12/18 职场文书
《凡卡》教学反思
2014/04/09 职场文书
纠纷协议书
2014/04/16 职场文书
软件售后服务方案
2014/05/29 职场文书
第二批党的群众路线教育实践活动总结报告
2014/10/30 职场文书
2014年宣传思想工作总结
2014/12/10 职场文书
二年级学生期末评语
2014/12/26 职场文书
天坛导游词
2015/02/02 职场文书
2015年秋季小学开学标语
2015/07/16 职场文书
助学金申请书该怎么写?
2019/07/16 职场文书
python 如何用terminal输入参数
2021/05/25 Python