• javascript中的数字都是双精度的浮点数。
  • JavaScript中的整数并不是一个独立的数据类型,而是浮点数的一个子集。

  

浮点数的坑
我们看下面的例子

在浏览器的console 控制台上我们分别进行以下的浮点数运算

通过控制台的运算,我们可以很惊奇的看到答案,有些运算结果竟然和我们想像的不一样,比如0.1+0.2的返回结果不是0.3,而是0.30000000000000004。

这究竟是啥原因?
1,首先要肯定的是这不是浏览器的问题,而是由于浮点数的精度导致的。
2,浮点数的精度问题并不是JavaScript所独有的,例如在java中,我们运行以下代码,同样会输出和JavaScript中一样的结果。

double dd = 0.1+0.2;
System.out.println(dd);//0.30000000000000004?

why?
因为电脑永远都是按照二进制进行运算的,我们输入的十进制数在转化为二进制数时,并不总如人意,意思是说有些十进制并不能用准确的二进制数表示。

十进制小树转二进制表示

我们来看下十进制小树转二进制表示的过程,小数位乘以2,取整,小数部分继续乘以2,再取整,直到小数部分为0为止,然后将取整位按顺序排列。

由此方法我们可以看到以下一些十进制小数的二进制表示。

 十进制     二进制
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.0999999999...无限接近与1.1

解决方案

常用的一种解决方法就是将浮点数转化为整数进行运算,以下是一些封装好的关于浮点运算的方法,而且经过测试,加减乘除运算都会达到自己想要的结果。

 //求和
function add(num1,num2){
var r1,r2,m;
try{
r1 = num1.toString().split('.')[1].length;
}catch(e){
r1 = 0
}
try{
r2 = num2.toString().split('.')[1].length;
}catch(e){
r2 = 0
}
m = Math.pow(10,Math.max(r1,r2));
return Math.round(num1*m + num2*m)/m;
}
//相减
function sub(num1,num2){
var r1,r2,m;
try{
r1 = num1.toString().split('.')[1].length;
}catch(e){
r1 = 0;
}
try{
r2 = num1.toString().split('.')[1].length;
}catch(e){
r2 = 0;
}
m = Math.pow(10,Math.max(r1,r2));
n = (r1 >= r2) ? r1 : r2;
return (Math.round(num1 * m - num2*m) / m).toFixed(n);
}
//相乘
function mul(num1,num2){
var m = 0,r1,r2;
var s1 = num1.toString();
var s2 = num2.toString();
try{
m += s1.split('.')[1].length
}catch(e){ }
try{}catch(e){
m += s2.split('.')[1].length
}catch(e){ }
r1 = Number(num1.toString().replace(".",""));
r2 = Number(num2.toString().replace(".",""));
return r1 * r2 / Math.pow(10,m);
}
 //相除
function accDiv(){
var t1,t2,r1,r2;
try{
t1 = num1.toString().split('.')[1].length;
}catch(e){
t1 = 0;
}
try{}catch(e){
t2 = num2.toString().split('.')[1].length;
}catch(e){
t2 = 0;
}
r1 = Number(num1.toString().replace(".",""));
r2 = Number(num2.toString().replace(".",""));
return (r1 / r2)*Math.pwo(10,t2-t1);
}

js浮点数运算的坑,多少同学有碰到过?的更多相关文章

  1. JS浮点数运算Bug

    JS浮点数运算Bug的解决办法(转) 37.5*5.5=206.08 (JS算出来是这样的一个结果,我四舍五入取两位小数) 我先怀疑是四舍五入的问题,就直接用JS算了一个结果为:206.0849999 ...

  2. JS浮点数运算BUG破法

    JS里,0.3*3 = 0.8999999999999999 破法1:((0.3*10)*3)/10 破法2:(0.3*3).toFixed(2)//保留两位小数 原因:js浮点数用的是IEEE754 ...

  3. js浮点数运算需要注意的问题

    最近在js运算浮点数时发现了一个问题.问题是这样的:js函数中处理两个浮点数的相加,为了防止出现0.1+0.2=0.30000000000000004的问题,两个数都先乘以10000后再相加,得到结果 ...

  4. js浮点数运算封装, 起因财务部分精确计算

    目录 背景 具体代码 背景 项目中用到浮点数,Int 等 js中 Number类型比较多, 加上牵涉到财务软件, 前台js运算等. 有时候会出现精确度的问题 , 公共方法中有好事者写的方法. 此处拿来 ...

  5. 【转】JS浮点数运算Bug的解决办法

    37.5*5.5=206.08 (JS算出来是这样的一个结果,我四舍五入取两位小数) 我先怀疑是四舍五入的问题,就直接用JS算了一个结果为:206.08499999999998 怎么会这样,两个只有一 ...

  6. 记C语言浮点数运算处理 "坑" 一则

    看一小段C语言程序: int main() { float x = 1.3; x = x - (int)x; ); ; } 在你心目中, 变量 I 是怎样的结果? 如果你理所当然地认为是3的话, 那么 ...

  7. JS浮点数运算Bug的解决办法

    方法一:重写浮点运算的函数 //除法函数,用来得到精确的除法结果 //说明:javascript的除法结果会有误差,在两个浮点数相除的时候会比较明显.这个函数返回较为精确的除法结果. //调用:acc ...

  8. JS浮点数运算

    //乘法函数,用来得到精确的乘法结果 //说明:javascript的乘法结果会有误差,在两个浮点数相乘的时候会比较明显.这个函数返回较为精确的乘法结果. //调用:accMul(arg1,arg2) ...

  9. js浮点数运算出现误差解决方案

    1.数据展示类(使用 toPrecision 凑整并 parseFloat 转成数字后再显示) parseFloat(1.4000000000000001.toPrecision(12)) === 1 ...

随机推荐

  1. Linux显示2015年日历表

    Linux显示2015年日历表 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ cal 2015 2015 一月 二月 三月 日 一 二 三 四 五 六 日 一 ...

  2. 芝麻HTTP:TensorFlow LSTM MNIST分类

    本节来介绍一下使用 RNN 的 LSTM 来做 MNIST 分类的方法,RNN 相比 CNN 来说,速度可能会慢,但可以节省更多的内存空间. 初始化 首先我们可以先初始化一些变量,如学习率.节点单元数 ...

  3. Excle巧取汉字打头的字串内容

    处理表格数据时遇到问题:从网页表格中复制来的数据,地址一列中出现类似于“4AWZCX万载老林业局2”的无用字符前缀.现在希望提取第一个汉字及其之后的所有内容(图1),寻求高效分离中英文及数字的实操方法 ...

  4. freemark标签从后台接过来数据Boolean在前台还是Boolean输出(四)

    FREEMARK标签中输出BOOLEAN值 private boolean showHeader=true; public boolean getShowHeader(){ return this.s ...

  5. eclipse - The superclass "javax.servlet.http.HttpServlet" was not found on the Java

  6. Poj2723:Get Luffy Out

    题意 给出 n 对钥匙,每对只能挑一把使用,每把只能用一次,当一对钥匙中的一把被使用后,另一把也就不能再用了:然后给出 m 道门,每个门都有两把钥匙可以打开,问最多能开几道门(按给出的顺序开). So ...

  7. Docker 基础技术之 Linux namespace 详解

    Docker 是"新瓶装旧酒"的产物,依赖于 Linux 内核技术 chroot .namespace 和 cgroup.本篇先来看 namespace 技术. Docker 和虚 ...

  8. sql server 2008 sql prompt 自动提示

    sql server 2008 在编写SQL脚本的时候,总是希望能提示一些信息,或者自动提示需要查询的表的名字,或者表的基本信息,sql server默认会有一些提示的,如果没有可以设置工具--> ...

  9. Oracle数据库中in()参数超过一千报错代码报错

    转载请注明出处:http://www.cnblogs.com/xunzhaorendaxia/p/8570604.html 解决方案将select * from tablename where fie ...

  10. STM32F10x的启动汇编分析

    ;******************** (C) COPYRIGHT 2009 STMicroelectronics ********************;* File Name         ...