关于js精度计算
2010-11-24 18:33
671 查看
问题这样的:
37.5*5.5=206.08 (JS算出来是这样的一个结果,我四舍五入取两位小数)
我先怀疑是四舍五入的问题,就直接用JS算了一个结果为:206.08499999999998
怎么会这样,两个只有一位小数的数字相乘,怎么可能多出这么小数点出来。
我Google了一下,发现原来这是JavaScript浮点运算的一个bug。
比如:7*0.8 JavaScript算出来就是:5.6000000000000005
网上找到了一些解决办法,就是重新写了一些浮点运算的函数。
下面就把这些方法摘录下来,以供遇到同样问题的朋友参考:
程序代码
//除法函数,用来得到精确的除法结果
//说明:javascript的除法结果会有误差,在两个浮点数相除的时候会比较明显。这个函数返回较为精确的除法结果。
//调用:accDiv(arg1,arg2)
//返回值:arg1除以arg2的精确结果
function accDiv(arg1,arg2){
var t1=0,t2=0,r1,r2;
try{t1=arg1.toString().split(".")[1].length}catch(e){}
try{t2=arg2.toString().split(".")[1].length}catch(e){}
with(Math){
r1=Number(arg1.toString().replace(".",""))
r2=Number(arg2.toString().replace(".",""))
return (r1/r2)*pow(10,t2-t1);
}
}
//乘法函数,用来得到精确的乘法结果
//说明:javascript的乘法结果会有误差,在两个浮点数相乘的时候会比较明显。这个函数返回较为精确的乘法结果。
//调用:accMul(arg1,arg2)
//返回值:arg1乘以arg2的精确结果
function accMul(arg1,arg2)
{
var m=0,s1=arg1.toString(),s2=arg2.toString();
try{m+=s1.split(".")[1].length}catch(e){}
try{m+=s2.split(".")[1].length}catch(e){}
return Number(s1.replace(".",""))*Number(s2.replace(".",""))/Math.pow(10,m)
}
//加法函数,用来得到精确的加法结果
//说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。
//调用:accAdd(arg1,arg2)
//返回值:arg1加上arg2的精确结果
function accAdd(arg1,arg2){
var r1,r2,m;
try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0}
try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0}
m=Math.pow(10,Math.max(r1,r2))
return (arg1*m+arg2*m)/m
}
帖出减法的代码:
function Subtr(arg1,arg2){
var r1,r2,m,n;
try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0}
try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0}
m=Math.pow(10,Math.max(r1,r2));
//last modify by deeka
//动态控制精度长度
n=(r1>=r2)?r1:r2;
return ((arg1*m-arg2*m)/m).toFixed(n);
}
附js方法解释
必选项。表达式底的值。
exponent
必选项。表达式的指数值。
当使用 with 语句时,代码变得更短且更易读:
[/code]
37.5*5.5=206.08 (JS算出来是这样的一个结果,我四舍五入取两位小数)
我先怀疑是四舍五入的问题,就直接用JS算了一个结果为:206.08499999999998
怎么会这样,两个只有一位小数的数字相乘,怎么可能多出这么小数点出来。
我Google了一下,发现原来这是JavaScript浮点运算的一个bug。
比如:7*0.8 JavaScript算出来就是:5.6000000000000005
网上找到了一些解决办法,就是重新写了一些浮点运算的函数。
下面就把这些方法摘录下来,以供遇到同样问题的朋友参考:
程序代码
//除法函数,用来得到精确的除法结果
//说明:javascript的除法结果会有误差,在两个浮点数相除的时候会比较明显。这个函数返回较为精确的除法结果。
//调用:accDiv(arg1,arg2)
//返回值:arg1除以arg2的精确结果
function accDiv(arg1,arg2){
var t1=0,t2=0,r1,r2;
try{t1=arg1.toString().split(".")[1].length}catch(e){}
try{t2=arg2.toString().split(".")[1].length}catch(e){}
with(Math){
r1=Number(arg1.toString().replace(".",""))
r2=Number(arg2.toString().replace(".",""))
return (r1/r2)*pow(10,t2-t1);
}
}
//乘法函数,用来得到精确的乘法结果
//说明:javascript的乘法结果会有误差,在两个浮点数相乘的时候会比较明显。这个函数返回较为精确的乘法结果。
//调用:accMul(arg1,arg2)
//返回值:arg1乘以arg2的精确结果
function accMul(arg1,arg2)
{
var m=0,s1=arg1.toString(),s2=arg2.toString();
try{m+=s1.split(".")[1].length}catch(e){}
try{m+=s2.split(".")[1].length}catch(e){}
return Number(s1.replace(".",""))*Number(s2.replace(".",""))/Math.pow(10,m)
}
//加法函数,用来得到精确的加法结果
//说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。
//调用:accAdd(arg1,arg2)
//返回值:arg1加上arg2的精确结果
function accAdd(arg1,arg2){
var r1,r2,m;
try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0}
try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0}
m=Math.pow(10,Math.max(r1,r2))
return (arg1*m+arg2*m)/m
}
帖出减法的代码:
function Subtr(arg1,arg2){
var r1,r2,m,n;
try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0}
try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0}
m=Math.pow(10,Math.max(r1,r2));
//last modify by deeka
//动态控制精度长度
n=(r1>=r2)?r1:r2;
return ((arg1*m-arg2*m)/m).toFixed(n);
}
附js方法解释
pow 方法
返回底表达式的指定次幂。Math.pow(base, exponent)
参数
base必选项。表达式底的值。
exponent
必选项。表达式的指数值。
示例
在下面的例子中,等同于 baseexponent 的数值表达式,返回值为 1000。Math.pow(10,3);
toFixed 方法
返回一个字符串,代表一个以定点表示法表示的数字。numObj.toFixed([fractionDigits])参数
numObj必选项。一个 Number 对象。fractionDigits可选项。小数点后的数字位数。其值必须在 0 – 20 之间,包括 0 和 20。说明
toFixed 方法返回一个以定点表示法表示的数字的字符串形式。该字符串中小数点之前有一位有效数字,而且其后必须包含 fractionDigits 数字。
如果没有 fractionDigits 参数,或者该参数为 undefined,toFixed 方法假定该值为 0。with 语句
为语句设定默认对象。
[code]with (object)
statements
参数
object新的默认对象。statements一个或多个语句,object 是该语句的默认对象。说明
with 语句通常用来缩短特定情形下必须写的代码量。在下面的例子中,请注意 Math 的重复使用:x = Math.cos(3 * Math.PI) + Math.sin(Math.LN10) y = Math.tan(14 * Math.E)
当使用 with 语句时,代码变得更短且更易读:
with (Math){ x = cos(3 * PI) + sin (LN10) y = tan(14 * E) }
[/code]
相关文章推荐
- 关于js浮点精度计算不准确的问题及解决方法
- 关于js浮点数计算精度不准确问题
- 关于js中计算精度的问题解决办法
- 关于计算订单价格,转换后差一分钱的解决方法(浮点数精度问题)
- js中数字计算精度
- JS浮点计算时精度解决办法
- js金额计算精度缺失解决方案(只此一家,错过后悔)
- 关于k3中自定义字段的数据计算精度的问题
- js数值计算的处理,防止精度误差
- 关于JavaScript中计算精度丢失的问题
- js中数字计算精度
- 关于JavaScript中计算精度丢失的问题(一)
- JS精度计算 (转帖,补充减法)
- 关于精度计算的问题
- JS的浮点数计算精度丢失问题解决方案
- js中的小数计算精度问题,修正计算精度
- 黄聪:JS数学计算精度修正
- Js计算,精度丢失处理
- 关于js小数计算的问题
- js计算精度问题