浮点型精度丢失问题的解决方法
发布于 9 年前 作者 CN-Sean 7057 次浏览 最后一次编辑是 8 年前 来自 分享

很早很早的时候,我曾经提问过,如何处理精度丢失的问题。过了很久了,经过了不少实践,我分享下自己使用的技巧吧~~希望可以帮助到有遇到和我相同问题的人,大家一起探讨~

问题

精度丢失的情形,大家肯定都遇到过,比如:

  1. 使用excel的时候,单元格运算会出现精度问题。
  2. js控制台输入0.1+0.2,所得的结果就会出现精度问题。
  3. 数据库在做汇总计算的时候,得到的结果也会出现精度问题。

那么精度问题是个什么现象呢?如下图:

解决思路

在项目实践中,我们采用的方式是当数据在前端展现时,对数据做一定的处理,使得其结果正确。处理代码如下:

function(value, precision) {
    var result = '';
    if (!precision) {
        precision = 8;
    }
    if(!this.isEmpty(value)){
        var number = parseFloat(value);
        if(!isNaN(number)){
            var floatByte = (number + '').split('.')[1];
            if(floatByte && floatByte.length > precision){
                result = parseFloat(number.toFixed(precision));
            }else{
                result = value;
            }
        }
    }
    return result;
}

整体逻辑很简单,就是当小数位数达到8位甚至超过时,做一下舍入。8这个位数是在各种实践中得到的可以保证数据准确性的一个位数。但是,很明显的可以看到缺点,就是如果真的有数字的小数超过了这个问题,而且一定要这么多位的精度的时候,会出现问题,然而这种情况非常罕见。如果有什么更好的方法,欢迎分享~

本文来自:http://www.shaowenwu.cn/fu-dian-xing-jing-du-diu-shi-wen-ti-de-jie-jue-fang-fa/

2 回复

然后原生的toFixed也是有问题的

我们使用了这个解决方案

Number.prototype._toFixed = Number.prototype._toFixed || Number.prototype.toFixed;
Number.prototype.toFixed = function(precision) {
    return (+(Math.round(+(this + 'e' + precision)) + 'e' + -precision))._toFixed(precision);
}

http://stackoverflow.com/questions/20701029/rounding-issue-in-math-round-tofixed http://stackoverflow.com/questions/5490687/broken-tofixed-implementation http://stackoverflow.com/questions/21091727/javascript-tofixed-function http://stackoverflow.com/questions/10015027/javascript-tofixed-not-rounding

也被类似的问题困扰着,mark

回到顶部