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中end()方法用法实例
Jan 08 Javascript
浅谈Javascript数组(推荐)
May 17 Javascript
微信小程序 location API实例详解
Oct 02 Javascript
微信小程序 scroll-view实现上拉加载与下拉刷新的实例
Jan 21 Javascript
深入浅析JS中的严格模式
Jun 04 Javascript
Vue Router去掉url中默认的锚点#
Aug 01 Javascript
layer.confirm点击第一个按钮关闭弹出框的方法
Sep 09 Javascript
微信小程序返回上一页传参并刷新过程解析
Dec 13 Javascript
原生JavaScript创建不可变对象的方法简单示例
May 07 Javascript
javascript实现前端分页功能
Nov 26 Javascript
typescript编写微信小程序创建项目的方法
Jan 29 Javascript
vue实力踩坑之push当前页无效
Apr 10 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
Zend Framework教程之资源(Resources)用法实例详解
2016/03/14 PHP
php自定义函数转换html标签示例
2016/09/29 PHP
Yii2中datetime类的使用
2016/12/17 PHP
php 数组元素快速去重
2017/05/05 PHP
Laravel 前端资源配置教程
2019/10/18 PHP
PHP终止脚本运行三种实现方法详解
2020/09/01 PHP
Nigma vs Liquid BO3 第二场2.14
2021/03/10 DOTA
js 异步处理进度条
2010/04/01 Javascript
jQuery 通过事件委派一次绑定多种事件,以减少事件冗余
2010/06/30 Javascript
在jQuery中 常用的选择器介绍
2013/04/16 Javascript
浅谈页面装载js及性能分析方法
2014/12/09 Javascript
node.js中的events.emitter.removeAllListeners方法使用说明
2014/12/10 Javascript
谷歌showModalDialog()方法不兼容出现对话窗口的解决办法
2016/02/15 Javascript
Omi v1.0.2发布正式支持传递javascript表达式
2017/03/21 Javascript
JS解决position:sticky的兼容性问题的方法
2017/10/17 Javascript
对vue.js中this.$emit的深入理解
2018/02/23 Javascript
create-react-app安装出错问题解决方法
2018/09/04 Javascript
webpack4.x CommonJS模块化浅析
2018/11/09 Javascript
你应该了解的JavaScript Array.map()五种用途小结
2018/11/14 Javascript
JS浮点数运算结果不精确的Bug解决
2019/08/01 Javascript
深入了解Vue.js 混入(mixins)
2020/07/23 Javascript
[01:02:03]2014 DOTA2华西杯精英邀请赛 5 24 NewBee VS VG
2014/05/26 DOTA
[03:07]2015国际邀请赛选手档案EHOME.rOtK 是什么让他落泪?
2015/07/31 DOTA
Python实现对百度云的文件上传(实例讲解)
2017/10/21 Python
Windows下的Python 3.6.1的下载与安装图文详解(适合32位和64位)
2018/02/21 Python
python pandas库的安装和创建
2019/01/10 Python
在Python IDLE 下调用anaconda中的库教程
2020/03/09 Python
Python函数必须先定义,后调用说明(函数调用函数例外)
2020/06/02 Python
Python 微信公众号文章爬取的示例代码
2020/11/30 Python
美国最便宜的旅游网站:CheapTickets
2017/07/09 全球购物
美国最大婚纱连锁店运营商:David’s Bridal
2019/03/12 全球购物
《那片绿绿的爬山虎》教学反思
2014/02/27 职场文书
英文自荐信常用句子
2014/03/26 职场文书
《大自然的语言》教学反思
2014/04/08 职场文书
教师党员岗位承诺书
2014/05/29 职场文书
《游戏公平》教学反思
2016/02/20 职场文书