本篇文章主要是对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. Idea 实时编译 和 热部署

    实时编译 idea自动保存编写好的文件,但是不会编译,想要编译需要按ctrl+F9(编译整个项目)ctrl+shift+f9(单个文件),不仅麻烦而且和平常习惯也不相复合.怎么令idea的ctrl+s ...

  2. iOS 链式编程探索(Masonry)

    看了几篇关于链式编程的文章,还是理解的不透彻,我想这可能是因为我自己对block掌握的不熟练. 我已经明白了,所以,和大家分享一下我的理解!如有问题,麻烦大家指出! 直接看代码吧!关键的注释都有. 我 ...

  3. 如何创建独立的UE4服务端

    原文作者:@玄冬Wong 转载请注明原文出处:http://aigo.iteye.com/blog/2268777 这是论坛上对UE服务端功能的回答,意思是UE4提供了主流MMO网游服务端所具备的特性 ...

  4. java-并发-不可变对象

    浏览以下内容前,请点击并阅读 声明 当一个对象创建后的状态不可改变时就认为其为不可变对象,尽可能地利用不可变对象被公认为是构建简单可靠代码的有效方法.不可变对象在并发程序中比较有用,由于其状态无法改变 ...

  5. Java 语句循环

    编写程序,显示Welcome to Java 五次. public class Welcome{ public static void main(String[] args){ int i;(定义变量 ...

  6. 【Java】JDK类 CountDownLatch

    一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. 用给定的计数 初始化 CountDownLatch.由于调用了 countDown() 方法,所以在当前计数到达 ...

  7. appium过程中的问题

    1.在eclipse中点击Genymotion Virtual Device Manager ,选择虚拟设备,点击start后,无反应.    解决方法:Help/Install New Softwa ...

  8. 二、JSP、servlet、SQL三者之间的数据传递(前台与后台数据交互)

    2.收信息来到表单提交时URL所指向的servlet文件,获取传递过来的参数值

  9. C++哈夫曼树编码和译码的实现

    一.背景介绍: 给定n个权值作为n个叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree).哈夫曼树是带权路径长度最短的树,权值较大的 ...

  10. 一鼓作气 博客--第四篇 note4

    1.元祖允许重复数据.只读元组,列表,元祖没有增删改查,比如身份证列表,不允许修改,就存成 元祖. 2. 字典 key-value对 特性: 无顺序 去重 查询速度快,比列表快多了 比list占用内存 ...