`
flex_莫冲
  • 浏览: 1074915 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

javascript浮点运算偏差的成因及解决方法

 
阅读更多
原文地址:http://eatpockyboy.blog.163.com/blog/static/116734640201231414154243/
最近做javascript算价格总和的时候遇到乘法也有乘不尽的情况。。。= =! 设想是js的运算算法里面包含了除法 没想到是这样的的  = =! js解释器的作者们真心强啊。。。 除了下文提及的解决方法之外 还有一个就是如果浮点的小数位确定时 比如价格是小数点后两位的 那么我们可以把价格乘以100 运算完之后再作相应的处理 这样会涉及一个位数过大(比如我这个价格要算个n次方的话就......)而转字符串处理的问题 这样效率本来就不高的算法而变得更加笨重 呃 但是下文的通过字符串切割分成小数部分和整数部分运算再算结果的这个方法效率貌似也不怎的 因此如何取舍就看诸君的需求了

转自:http://topic.csdn.net/u/20120329/17/6cc27133-a13f-4b9d-b253-fc8a04fd2f5c.html

-----------------正文-----------------

最近做js是对浮点类型计算时总是有偏差比如
3*0.8输出2.4000000000000003
在网上查了一下原因:

用解析字符串的方式移动小数点,转化为整数,完毕后,在把小数点复位。  
  浮点数运算的时候,先转化为二进制,用二进制来算,结果再转回十进制  
  例如 :求1038.1-1000  
  1038.1=10000001110.0001100110011001100110011001100110011001100.....  
  1000= 1111101000  
  1038.1转化为二进制是个无限循环小数,1100是循环节,只能取近似值,误差就是这里产生的 
如果浏览器版本高,可以用toFixed() 方法可把 Number 四舍五入为指定小数位数的数字.
后有固定的 num 位数字。如果必要,该数字会被舍入,也可以用 0 补足,以便它达到指定的长度。如果 num 大于 le+21,则该方法只调用 NumberObject.toString(),返回采用指数计数法表示的字符串。
语法
NumberObject.toFixed(num)
返回值
返回 NumberObject 的字符串表示,不采用指数计数法,小数点后有固定的 num 位数字。如果必要,该数字会被舍入,也可以用 0 补足,以便它达到指定的长度。如果 num 大于 le+21,则该方法只调用 NumberObject.toString(),返回采用指数计数法表示的字符串。

抛出
当 num 太小或太大时抛出异常 RangeError。0 ~ 20 之间的值不会引发该异常。有些实现支持更大范围或更小范围内的值。

当调用该方法的对象不是 Number 时抛出 TypeError 异常。
在本例中,我们将把数字舍入为仅有一位小数的数字:

Show the number 13.37 with one decimal:
<script type="text/javascript">
var num = new Number(13.37);
document.write (num.toFixed(1))
</script>

输出:
Show the number 13.37 with one decimal:
13.4

解决方法:
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) 
}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics