• 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. dojo中获取表格中某一行的某个值

    dojo中经常出现对表格中的某行进行操作,如单击某行修改.删除等.那怎样获取某行的唯一标示呢? 如查询表格中的某列有个userId,并且这个是唯一的,那么可以通过它来访问这一列 具体操作代码如下: v ...

  2. class-k近邻算法kNN

    1 k近邻算法2 模型2.1 距离测量2.2 k值选择2.3 分类决策规则3 kNN的实现--kd树3.1 构造kd树3.2 kd树搜索 1 k近邻算法 k nearest neighbor,k-NN ...

  3. C# 获取一个独一无二的字符串 GUID

    在保存文件,创建目录时,为了保证名称不重复,经常使用Random产生一个随机数,有更简单且不会重复的办法是: Guid.NewGuid().ToString() 就会生成一个类似 37c1acec-4 ...

  4. AndroidStudio 集成litepal 报错

    E/AndroidRuntime(24972): org.litepal.c.b: can not find a class named org.litepal.model.Table_Schema ...

  5. BZOJ 1926: [Sdoi2010]粟粟的书架(主席树,二分答案)

    BZOJ 1926: [Sdoi2010]粟粟的书架(主席树,二分答案) 题意 : 给你一个长为\(R\)宽为\(C\)的矩阵,第\(i\)行\(j\)列的数为\(P_{i,j}\). 有\(m\)次 ...

  6. POJ 2187 Beauty Contest(凸包,旋转卡壳)

    题面 Bessie, Farmer John's prize cow, has just won first place in a bovine beauty contest, earning the ...

  7. Java集合中迭代器的常用用法

    该例子展示了一个Java集合中迭代器的常用用法public class LinkedListTest { public static void main(String[] args) { List&l ...

  8. angular 按下回车键触发事件

    angularJs  按下回车键触发事件这个功能很简单,但是今天的却让我掉坑很久.... 由于我的页面上有两个不同方法都传$event事件,如search($event)和create($event) ...

  9. win10怎么安装JDK8,配置JDK8的环境变量

    win10怎么安装JDK8,配置JDK8的环境变量 本文详细说明怎么在win10上安装JDK8,方便小伙伴们快速学会安装与配置JDK. 工具/原料 windows10 jdk-8u51-windows ...

  10. MongoDB存储引擎(中)——WiredTiger

    上一篇博文介绍了MongoDB的MMAPv1存储引擎,本文接着介绍MongoDB另一个存储引擎--WiredTiger,WiredTiger是在MongoDB3.0版本引入的,并且在MongoDB3. ...