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 相关文章推荐
jQuery获取地址栏参数插件(模仿C#)
Oct 26 Javascript
jQuery 淡出一个图像到另一个图像的实现代码
Jun 12 Javascript
写出高效jquery代码的19条指南
Mar 19 Javascript
js监听input输入框值的实时变化实例
Jan 26 Javascript
使用Xcache缓存器加速PHP网站的配置方法
Apr 22 Javascript
如何使node也支持从url加载一个module详解
Jun 05 Javascript
深入理解JS中Number(),parseInt(),parseFloat()三者比较
Aug 24 Javascript
深入理解Angularjs 脏值检测
Oct 12 Javascript
详解ES6系列之私有变量的实现
Nov 21 Javascript
vue router 组件的高级应用实例代码
Apr 08 Javascript
微信小程序如何利用getCurrentPages进行页面传值
Jul 01 Javascript
vue浏览器返回监听的具体步骤
Feb 03 Vue.js
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
php上传文件并存储到mysql数据库的方法
2015/03/16 PHP
PHP中in_array函数使用的问题与解决办法
2016/09/11 PHP
php读取XML的常见方法实例总结
2017/04/25 PHP
PHP文件管理之实现网盘及压缩包的功能操作
2017/09/20 PHP
ExtJS判断IE浏览器类型的方法
2014/02/10 Javascript
JQuery遍历json数组的3种方法
2014/11/08 Javascript
JavaScript中函数(Function)的apply与call理解
2015/07/08 Javascript
JavaScript Math.round() 方法
2015/12/18 Javascript
JavaScript表单验证完美代码
2017/03/02 Javascript
node.js中EJS 模板快速入门教程
2017/05/08 Javascript
实例解析ES6 Proxy使用场景介绍
2018/01/08 Javascript
简单的Vue SSR的示例代码
2018/01/12 Javascript
ng-zorro-antd 入门初体验
2018/12/03 Javascript
微信小程序实现的自定义分享功能示例
2019/02/12 Javascript
vue-cli3+typescript初体验小结
2019/02/28 Javascript
vue插槽slot的理解和使用方法
2019/04/03 Javascript
JavaScript实现五子棋游戏的方法详解
2019/07/08 Javascript
vue-cli单页面预渲染seo-prerender-spa-plugin操作
2020/08/10 Javascript
Python基础教程之正则表达式基本语法以及re模块
2016/03/25 Python
Python标准库之collections包的使用教程
2017/04/27 Python
python函数式编程学习之yield表达式形式详解
2018/03/25 Python
美国波西米亚风格服装品牌:Show Me Your Mumu
2018/01/05 全球购物
西班牙床垫网上商店:Colchones.es
2018/05/06 全球购物
德国在线订购鲜花:Fleurop
2018/08/25 全球购物
违反校纪校规检讨书
2014/02/15 职场文书
新年抽奖获奖感言
2014/03/02 职场文书
10的分与合教学反思
2014/04/30 职场文书
创先争优个人承诺书
2014/08/30 职场文书
授权委托书
2014/09/17 职场文书
2014年助理工程师工作总结
2014/11/14 职场文书
离职感谢信
2015/01/21 职场文书
Python读取文件夹下的所有文件实例代码
2021/04/02 Python
利用前端HTML+CSS+JS开发简单的TODOLIST功能(记事本)
2021/04/13 Javascript
分析MySQL抛出异常的几种常见解决方式
2021/05/18 MySQL
聊聊Python中关于a=[[]]*3的反思
2021/06/02 Python
Pytorch中使用ImageFolder读取数据集时忽略特定文件
2022/03/23 Python