很早很早的时候,我曾经提问过,如何处理精度丢失的问题。过了很久了,经过了不少实践,我分享下自己使用的技巧吧~~希望可以帮助到有遇到和我相同问题的人,大家一起探讨~
问题
精度丢失的情形,大家肯定都遇到过,比如:
- 使用excel的时候,单元格运算会出现精度问题。
- js控制台输入
0.1+0.2
,所得的结果就会出现精度问题。 - 数据库在做汇总计算的时候,得到的结果也会出现精度问题。
那么精度问题是个什么现象呢?如下图:
解决思路
在项目实践中,我们采用的方式是当数据在前端展现时,对数据做一定的处理,使得其结果正确。处理代码如下:
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/
然后原生的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