对于 javascript 浮点运算 BUG 大家都应该有所耳闻,在网上也会收到很多解决办法,在这里我引用两篇博文。
Javascript优化后的加减乘除(解决js浮点数计算bug)
首先,用 2.1 / 0.335 举例说明我的观点。在计算器上计算会得到两组数值 6.26865671641791 和 6.2686567164179104477611940298507。
把 6.2686567164179104477611940298507 用 document.write(6.2686567164179104477611940298507+"<br>"); 在页面上输出会得到 6.268656716417911 数值更接近 6.26865671641791 数值。
所以我认为 javascript 浮点运算把精度控制在 14 位以内应该没什么问题,那么 toFixed 方法就可以满足要求。但是,你要是完全相信 toFixed 方法,你会发现并不是你想要的结果,四舍五入也有有问题。比如说,9.555.toFixed(2) 你会得到 9.55 。
综合网上的解决方案我的解决方案代码如下,希望有兴趣的朋友和我交流一下。看看有什么问题!
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<style type="text/css">
html, body { height: 100%; margin: 0px; padding: 10px; font: 12px/1.5 tahoma,arial, 'Hiragino Sans GB' ,\5b8b\4f53,sans-serif !important; vertical-align:baseline; }
</style>
</head>
<body>
<script type="text/javascript">
//<![CDATA[
Number.prototype.add=function(arg2) {
var r1=0,r2=0,m,s1=this.toString(),s2=arg2.toString();
if(s1.indexOf('.')!= -1)
r1=s1.split('.')[1].length;
if(s2.indexOf('.')!= -1)
r2=s2.split('.')[1].length;
m=Math.pow(10,Math.max(r1,r2));
return ((this.mul(m))+(arg2.mul(m)))/m;
};
Number.prototype.sub=function(arg2) {
var r1,r2,m,n,s1=this.toString(),s2=arg2.toString();
if(s1.indexOf('.')!= -1)
r1=s1.split('.')[1].length;
if(s2.indexOf('.')!= -1)
r2=s2.split('.')[1].length;
m=Math.pow(10,Math.max(r1,r2));
n=(r1>=r2)?r1:r2;
return ((this.mul(m)-arg2.mul(m))/m).toFixed(n);
};
Number.prototype.mul=function(arg2) {
var m=0,s1=this.toString(),s2=arg2.toString();
if(s1.indexOf('.')!= -1)
m+=s1.split('.')[1].length;
if(s2.indexOf('.')!= -1)
m+=s2.split('.')[1].length;
return Number(s1.replace('.',''))*Number(s2.replace('.','')).div(Math.pow(10,m));
};
Number.prototype.div=function(arg2) {
var t1=0,t2=0,r1,r2,s1=this.toString(),s2=arg2.toString();
if(s1.indexOf('.')!= -1)
t1=s1.split('.')[1].length;
if(s2.indexOf('.')!= -1)
t2=s2.split('.')[1].length;
r1=Number(s1.replace('.',''));
r2=Number(s2.replace('.',''));
return (r1/r2)/Math.pow(10,t1-t2);
};
Number.prototype.toFixed=function(n) {
var power=Math.pow(10,n)
,valuePower=this.mul(power)
,dotIndex=valuePower.toString().indexOf('.')
,afterFrist;
if(-1!=dotIndex)
afterFrist=parseInt(valuePower.toString().substring(dotIndex+1,dotIndex+2));
if(!isNaN(afterFrist)&&5<=afterFrist)
valuePower+=0<this?1:-1;
var fixed=parseInt(valuePower).div(power).toString();
if(n==0)
return fixed;
if(fixed.indexOf('.')<0)
fixed+='.';
var padding=n+1-(fixed.length-fixed.indexOf('.'));
for(var i=0;i<padding;i++)
fixed+='0';
return Number(fixed);
};
document.write(" 2.2 + 2.1 = "+(2.2+2.1).toFixed(14)+"<br>");
document.write(" 2.2 - 1.9 = "+(2.2-1.9).toFixed(14)+"<br>");
document.write(" 2.2 * 2.2 = "+(2.2*2.2).toFixed(14)+"<br>");
document.write(" -2.1 / 0.335 = "+(-2.1/0.335).toFixed(8)+"<br>");
document.write(" 2.1 / 0.335 = "+(2.1/0.335).toFixed(8)+"<br>");
document.write(" 0.1 / 0.3 = "+(0.1/0.3).toFixed(14)+"<br>");
document.write("0.0999999999999999 * 0.05 = "+(0.0999999999999999*0.05).toFixed(14)+"<br>");
document.write(6.2686567164179104477611940298507+"<br>");
document.write(6.2686567164179104477611940298507.toFixed(14)+"<br>");
document.write(9.555.toFixed(2)+"<br>");
//]]>
</script>
</body>
</html>