Javascript 浮点运算问题分析与解决
分析
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 浮点运算问题分析与解决的更多相关文章
- Javascript 浮点计算问题分析与解决
分析 JavaScript 只有一种数字类型 Number ,而且在Javascript中所有的数字都是以IEEE-754标准格式表示的. 浮点数的精度问题不是JavaScript特有的,因为有些小数 ...
- JavaScript中的ParseInt("08")和“09”返回0的原因分析及解决办法
今天在程序中出现一个bugger ,调试了好久,最后才发现,原来是这个问题. 做了一个实验: alert(parseInt("01")),当这个里面的值为01====>07时 ...
- php中session_start()相关问题分析与解决办法
介绍下,在php中使用session时遇到的一些问题,与相关解决方法.1.错误提示Warning: Cannot send session cookie - headers already sentW ...
- firefox下对ajax的onreadystatechange的支持情况分析及解决
一.问题: var xmlHttp; function savecarttodata(){ createXMLHttpRequest(); var rndcode = new Date().getTi ...
- Mybatis关联查询和数据库不一致问题分析与解决
Mybatis关联查询和数据库不一致问题分析与解决 本文的前提是,确定sql语句没有问题,确定在数据库中使用sql和项目中结果不一致. 在使用SpringMVC+Mybatis做多表关联时候,发现也不 ...
- C#中异常:“The type initializer to throw an exception(类型初始值设定项引发异常)”的简单分析与解决方法
对于C#中异常:“The type initializer to throw an exception(类型初始值设定项引发异常)”的简单分析,目前本人分析两种情况,如下: 情况一: 借鉴麒麟.NET ...
- 启动Tomcat一闪而过——分析及解决过程
启动Tomcat一闪而过--分析及解决过程 嗯,昨天将有关JDK的知识稍微整理了一下,现在稍微整理一下有关Tomcat的! 1:Tomcat是什么? Tomcat是当今世界上使用最为广泛的.开源免费的 ...
- SQL Server2005索引碎片分析和解决方法
SQL Server2005索引碎片分析和解决方法 本文作者(郑贤娴),请您在阅读本文时尊重作者版权. 摘要: SQL Server,为了反应数据的更新,需要维护表上的索引,因而这些索引会形成碎片.根 ...
- mybatis异常:Improper inline parameter map format. Should be: #{propName,attr1=val1,attr2=val2}问题分析及解决
转载自:http://blog.csdn.net/jackpk/article/details/44158701 mybatis异常:Improper inline parameter map for ...
随机推荐
- Java-老夫对泛型的理解。。
什么是泛型,在我看来 泛型就是能够限制类,方法,数组-变量的类型 比如说 List<String,int> list = new List<String,int> 就是有尖括 ...
- jTDS Java连接SQL Server 2000数据库
Java连接SQL Server 2000数据库时,有两种方法: (1)通过Microsoft的JDBC驱动连接.此JDBC驱动共有三个文件,分别 是mssqlserver.jar.msutil.ja ...
- Firebug Console 与命令行全集
Console API 当打开 firebug (也包括 Chrome 等浏览器的自带调试工具),window 下面会注册一个叫做 console 的对象,它提供多种方法向控制台输出信息,供开发人员调 ...
- javactript关闭窗体,刷新父窗体
//关闭,父窗口弹出对话框,子窗口直接关闭this.Response.Write("<script language=javascript>window.close();< ...
- JAVA基础--继承中的构造方法
1. 子类的构造方法必须调用父类的构造方法 2. 子类在自己的构造方法中使用super(argument_list)调用父类的构造方法, 使用this(argument_list)调用自己的其他的构造 ...
- Struts2--Dynamic Result动态结果集
${r} : 表示配置文件xml可以读取action的valuestack的内容 1. jsp显示文件: <body> 动态结果 一定不要忘了为动态结果的保存值设置set get方法 &l ...
- oracle与SqlServer连接串服务器地址
SQLSERVER数据库可在连接串中指定服务器: ORACLE在监听中指定服务器地址.
- Eclipse 快捷键使用
ctrl+shift+T //查找当前工程下的某个类 实时提示 ctrl+shift+R//查找当前工程下的某个文件 实时提示 ctrl+/添加注释 Ctrl+1 快速修复(最经典的快捷键,就 ...
- EF 报【序列包含一个以上的元素】解决办法
1.检查模型是否存在重复的字段,eg: public class AggregateRoot { public System.Guid Guid { get; set; } } public part ...
- CodeForces 620A Professor GukiZ's Robot
水题 #include<cstdio> #include<cstring> #include<cmath> #include<stack> #inclu ...