本篇文章主要是对javascript避免数字计算精度误差的方法进行了介绍,需要的朋友可以过来参考下,希望对大家有所帮助。

如果我问你 0.1 + 0.2 等于几?你可能会送我一个白眼,0.1 + 0.2 = 0.3 啊,那还用问吗?连幼儿园的小朋友都会回答这么小儿科的问题了。但是你知道吗,同样的问题放在编程语言中,或许就不是想象中那么简单的事儿了。

不信?我们可以做个试验。

先来看一段 JS。

var num1 = 0.1;
var num2 = 0.2;
alert(num1+num2 === '0.3');

执行结果是 false。没错,当我第一次看到这段代码时,我也理所当然地以为它是 true,但是执行结果让我大跌眼镜,是我的打开方式不对吗?非也非也。我们再执行以下代码试试就知道结果为什么是 false 了。

var num1 = 0.1;
var num2 = 0.2;
alert( num1+numB );

原来,0.1 + 0.2 = 0.30000000000000004。是不是很奇葩?其实对于浮点数的四则运算,几乎所有的编程语言都会有类似精度误差的问题,只不过在 C++/C#/Java 这些语言中已经封装好了方法来避免精度的问题,

而 JavaScript 是一门弱类型的语言,从设计思想上就没有对浮点数有个严格的数据类型,所以精度误差的问题就显得格外突出。下面就分析下为什么会有这个精度误差,以及怎样修复这个误差。

首先,我们要站在计算机的角度思考 0.1 + 0.2 这个看似小儿科的问题。我们知道,能被计算机读懂的是二进制,而不是十进制,所以我们先把 0.1 和 0.2 转换成二进制看看:

0.1==》0.1.toString(2)==》0.0001100110011(无限循环..)

0.2==》0.2.toString(2)==》0.001100110011(无限循环..)

双精度浮点数的小数部分最多支持 52 位,所以两者相加之后得到这么一串 0.0100110011001100110011001100110011001100110011001100 因浮点数小数位的限制而截断的二进制数字,这时候,我们再把它转换为十进制,就成了 0.30000000000000004。

原来如此,那怎么解决这个问题呢?我想要的结果就是 0.1 + 0.2 === 0.3 啊!!!

有种最简单的解决方案,就是给出明确的精度要求,在返回值的过程中,计算机会自动四舍五入,

比如:

var num1 = 0.1;
var num2 = 0.2;
alert( parseFloat((num1 + num2).toFixed(2)) === 0.30 );

但是四舍五入明显不是一劳永逸的办法。

如果有一个方法能帮我们解决这些浮点数的精度问题,那该多好!所以,我们就自己写一个方法。

我们来试试下面这个方法:

formatNum = function(f, digit) {
var m = Math.pow(10, digit);
return parseInt(f * m, 10) / m;
}

 var num1 = 0.1; 
 var num2 = 0.2;

 alert(formatNum(num1 + num2, 1) === 0.3);

这个方法是什么意思呢?

为了避免产生精度差异,我们要把需要计算的数字乘以 10 的 n 次幂,换算成计算机能够精确识别的整数,然后再除以 10 的 n 次幂,大部分编程语言都是这样处理精度差异的,我们就借用过来处理一下 JS 中的浮点数精度误差。

所以如果下次再有人问你 0.1 + 0.2 等于几,你可要小心回答咯!!

JS数字计算精度误差的解决方法的更多相关文章

  1. JS数字计算精度问题解决

    add(a, b) {//相加 var c, d, e; try { c = a.toString().split(".")[1].length; } catch (f) { c ...

  2. 关于js浮点数计算精度不准确问题的解决办法

    今天在计算商品价格的时候再次遇到js浮点数计算出现误差的问题,以前就一直碰到这个问题,都是简单的使用tofixed方法进行处理一下,这对于一个程序员来说是及其不严谨的.因此在网上收集了一些处理浮点数精 ...

  3. js中style.display=""无效的解决方法

    本文实例讲述了js中style.display=""无效的解决方法.分享给大家供大家参考.具体解决方法如下: 一.问题描述: 在js中我们有时想动态的控制一个div显示或隐藏或更多 ...

  4. ADF控件ID变化引发JS无法定位控件的解决方法

    原文地址:ADF控件ID变化引发JS无法定位控件的解决方法作者:Nicholas JSFF定义的控件ID到了客户端时往往会改变.例如在JSFF中的一个的ID为"ot1",但是当这个 ...

  5. 学以致用:手把手教你撸一个工具库并打包发布,顺便解决JS浮点数计算精度问题

    本文讲解的是怎么实现一个工具库并打包发布到npm给大家使用.本文实现的工具是一个分数计算器,大家考虑如下情况: \[ \sqrt{(((\frac{1}{3}+3.5)*\frac{2}{9}-\fr ...

  6. JS中浮点数精度误差解决

    问题出现 0.1 + 0.2 = 0.30000000000000004 问题分析 对于浮点数的四则运算,几乎所有的编程语言都会有类似精度误差的问题,只不过在 C++/C#/Java 这些语言中已经封 ...

  7. js中toFixed精度问题的解决办法

    toFixed() 方法可把 Number 四舍五入为指定小数位数的数字.例如将数据Num保留2位小数,则表示为:toFixed(Num):但是其四舍五入的规则与数学中的规则不同,使用的是银行家舍入规 ...

  8. js 浮点数计算精度不准确问题

    或许很多人都遇到过,js 对小数的加.减.乘.除时经常得到一些奇怪的结果! 比如 :0.1 + 0.2 = 0.3  ? 这么一个简单的计算,当你用js 计算时会发现结果是:0.30000000000 ...

  9. JavaScript数字计算精度丢失的问题和解决方案

    一.JS数字精度丢失的一些典型问题 1. 两个简单的浮点数相加:0.1 + 0.2 != 0.3 // true,下图是firebug的控制台截图: 看看java的计算结果:是不是让你很不能接受 再来 ...

随机推荐

  1. [转]iOS Safari 中click点击事件失效的解决办法

    iOS Safari 中click点击事件失效的解决办法 问题起因: 在微信公众号开发(微站)过程中用jquery的live方法绑定的click事件点击无效(不能执行) 问题描述 当使用委托给一个元素 ...

  2. zabbix身份验证流程解析&绕过身份验证的方法

    由于实验室产品的监控模块的需求,需要绕过zabbix的验证模块,实现从二级平台到zabbix的无缝接入. 测试发现,zabbix的身份验证并不是想象的那么简单,为了实现功能,遂进行源码分析. zabb ...

  3. 工厂模式模拟Spring的bean加载过程

    一.前言    在日常的开发过程,经常使用或碰到的设计模式有代理.工厂.单例.反射模式等等.下面就对工厂模式模拟spring的bean加载过程进行解析,如果对工厂模式不熟悉的,具体可以先去学习一下工厂 ...

  4. c、c++ 常用函数记录

    1.void*  memcpy(char*dest, char*src, size_tnum) 将第二个参数拷贝到第一个参数,最后一个是长度. 2.void *memset(void *s, int ...

  5. .net core Jwt 添加

    Jwt 已经成为跨平台身份验证通用方案,如不了解请关注:https://jwt.io/. 为了和微软其他验证模块有个比较好的衔接,项目中采用了微软开发的jwt组件: System.IdentityMo ...

  6. Salesforce练习Case

    以下几个SFDC的Case基本覆盖了Force.com平台的一些基本操作流程,大家可以自己动手练习一下 Case 1: 在某公司的业务流程中,有零售店和销售人员两类信息,销售人员是指在零售店中工作的人 ...

  7. 《JavaScript Dom编程艺术》(第二版)

    第一章<JavaScript简史> 1.JavaScript是一种脚本语言,通常只能通过Web浏览器去完成一些操作而不能像普通意义上的程序那样独立运行,它需要由Web浏览器进行解释和执行. ...

  8. div 添加滚动条

    <div id="dic" style="overflow:auto">

  9. WEB前端工程师(实践)制作天气预报难度:简单

    需要准备:jQuery Bootstrap 天气预报API(本文中使用API可能会失效请灵活运用) CSS样式可以你自己去写这里只提出jQuery 请求数据和解析JSON数据 { "resu ...

  10. SQL Server CONVERT() 截取日期

    SELECT CONVERT(varchar(100), GETDATE(), 0): 05 16 2006 10:57AMSELECT CONVERT(varchar(100), GETDATE() ...