一. 浮点数精度丢失的原因

1. 计算机的二进制实现和位数限制有些数无法表示。就像一些无理数不能有限表示,如:圆周率3.1415926...,1.333...等。JS遵循 IEEE 754 规范,采用双精度存储(double precision),占用64bit。如图:

s
eeeeeee  eeee
ffff  ffffffff  ffffffff  ffffffff  ffffffff  ffffffff
1
11
52

说明:

  • 1位用来表示符号位

  • 11位用来表示指数

  • 52位表示尾数

JS中能精准表示的最大整数是Math.pow(2, 53),十进制 9007199254740992,大于 9007199254740992 就可能丢失精度。

详细了解可以看这篇论文:What Every Computer Scientist Should Know About Floating-Point Arithmetic


二. 浮点数的加减乘除

1. 两个浮点数相乘

alert("1024.2 * 1.2 = " + (1024.2 * 0.2));

三. 解决方案

1. 先把浮点数放大倍数到整数,再进行运算,最后将结果缩小倍数。

2. 案例1:解决两个浮点数相乘丢失精度问题

// 解决两个浮点数相乘丢失精度问题
// a: 第一个参数
// b: 第二个参数 
function sum(a, b){
    var weight = 0;
    var aStr = a.toString();
    var bStr = b.toString();
    var regex = /^\d+$/;
    
    if(!regex.test(aStr)){
        weight += aStr.split(".")[1].length; 
        aStr = aStr.replace(".","");
    }
    if(!regex.test(bStr)){
        weight += bStr.split(".")[1].length;
        bStr = bStr.replace(".","");
    }
    return Number(aStr) * Number(bStr) / Math.pow(10, weight);
}

四. 知识点

1.Math.floor()方法执行的是向下取整计算,它返回的是小于或等于函数参数,并且与之最接近的整数。



document.write(Math.floor(0.60) + "")
document.write(Math.floor(0.40) + "")
document.write(Math.floor(5) + "")
document.write(Math.floor(5.1) + "")
document.write(Math.floor(-5.1) + "")
document.write(Math.floor(-5.9))

输出:

0
0
5
5
-6
-6

五. 学习博文

1. http://www.cnblogs.com/snandy/p/4943138.html

2. http://blog.csdn.net/dclove/article/details/43112839