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 相关文章推荐
js的闭包的一个示例说明
Nov 18 Javascript
JavaScript入门教程(5) js Screen屏幕对象
Jan 31 Javascript
javascript开发技术大全-第1章javascript概述
Jul 03 Javascript
javascript中解析四则运算表达式的算法和示例
Aug 11 Javascript
JavaScript数据类型之基本类型和引用类型的值
Apr 01 Javascript
Javascript中With语句用法实例
May 14 Javascript
jQuery实现ToolTip元素定位显示功能示例
Nov 23 Javascript
JavaScript 实现 Tab 点击切换实例代码
Mar 25 Javascript
JavaScript仿微信打飞机游戏
Jul 05 Javascript
基于JavaScript实现简单的音频播放功能
Jan 07 Javascript
vue watch自动检测数据变化实时渲染的方法
Jan 16 Javascript
javascript实现抢购倒计时程序
Aug 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
SONY SRF-22W(33W)的电路分析和维修案例
2021/03/02 无线电
允许phpmyadmin空密码登录的配置方法
2011/05/29 PHP
js将iframe中控件的值传到主页面控件中的实现方法
2013/03/11 Javascript
用json方式实现在 js 中建立一个map
2014/05/02 Javascript
浅谈jQuery异步对象(XMLHttpRequest)
2014/11/17 Javascript
jquery结婚电子请柬特效源码分享
2015/08/21 Javascript
jquery通过扩展select控件实现支持enter或focus选择的方法
2015/11/19 Javascript
学习JavaScript设计模式(单例模式)
2015/11/26 Javascript
js实现跨域访问的三种方法
2015/12/09 Javascript
完美解决jQuery fancybox ie 无法显示关闭按钮的问题
2016/11/29 Javascript
微信小程序 二维码canvas绘制实例详解
2017/01/06 Javascript
AngularJS ng-repeat指令中使用track by子语句解决重复数据遍历错误问题
2017/01/21 Javascript
通过命令行创建vue项目的方法
2017/07/20 Javascript
js实现图片放大展示效果
2017/08/30 Javascript
Angular CLI 安装和使用教程
2017/09/13 Javascript
JS浮点数运算结果不精确的Bug解决
2019/08/01 Javascript
基于javascript处理二进制图片流过程详解
2020/06/08 Javascript
[54:19]完美世界DOTA2联赛PWL S2 Magma vs PXG 第二场 11.28
2020/12/01 DOTA
Python的Bottle框架的一些使用技巧介绍
2015/04/08 Python
Python判断字符串与大小写转换
2015/06/08 Python
Django之choices选项和富文本编辑器的使用详解
2020/04/01 Python
python selenium xpath定位操作
2020/09/01 Python
CSS3的常见transformation图形变化用法小结
2016/05/13 HTML / CSS
HTML5中5个简单实用的API
2014/04/28 HTML / CSS
公司新员工的演讲稿注意事项
2014/01/01 职场文书
中秋节礼品促销方案
2014/02/02 职场文书
我与祖国共奋进演讲稿
2014/09/13 职场文书
2014年政教处工作总结
2014/12/20 职场文书
三潭印月的导游词
2015/02/12 职场文书
2016年会开场白台词
2015/06/01 职场文书
酒店温馨提示语
2015/07/14 职场文书
2016年班主任新年寄语
2015/08/18 职场文书
关于感恩的素材句子(38句)
2019/11/11 职场文书
Python中else的三种使用场景
2021/06/16 Python
使用CSS实现小三角边框原理解析
2021/11/07 HTML / CSS
WINDOWS 64位 下安装配置mysql8.0.25最详细的教程
2022/03/22 MySQL