标签:
最近工作中经常遇到需要处理浮点型计算的问题,开始一直都在用把浮点数先乘以10的对应小数的位数的次方化成整数再去开始计算。
例如100.01+100.02,可以化成(100.01*100+100.02*100)/100来做计算,但是最近发一个浮点数乘以一个10的次方也会有精度问题发生,突然感觉前面的工作是不是有好多地方埋了很多坑啊,不能愉快的工作啦。
正好周未没什么别的计划,想研究下怎么处理JS的浮点型计算的精度问题
既然浮点数的计算精度有问题,那何不就在计算过程中绕过浮点型的计算了,于是有如下思路
这里是加减法的思路:
可以把数字强行转化成字符串,再取得二个值中小数位数长的那一个长度值,再用字符串的方法把二个字符串中的点号给替换掉,再把位数不够的那一个字符在未尾补零后再把二个字符串转化成数字再进行计算,再把计算的值转换成字符串补上小数点,再转换成数字输出,即绕过了浮点的加减法运算
代码如下:
//浮点数加减法 function sumfloat(num0,num1,bzstr){ var ln0,//第一个值的的小数位数 ln1,//第二个值的的小数位数 lnz,//小数位数的最大值 lncz,//小数的差数 num0str,//第一个值数字转字符 num1str,//第二个值数字转字符 resultz;//计算结果 try { ln0=num0.toString().split(".")[1].length;//获取小数位数 }catch(e){ ln0=0; } try { ln1=num1.toString().split(".")[1].length;//获取小数位数 }catch(e){ ln1=0; } lnz=Math.max(ln0,ln1);//取得小数位数的最大值 lncz=ln0-ln1; num0str=clearpoint(num0,"."); num1str=clearpoint(num1,"."); //根据lncz的正负来判断哪个数字的位数是短的,来走补全 if(lncz>0){ num1str=getbq(num1str,lncz); }else if(lncz<0){ num0str=getbq(num0str,Math.abs(lncz)); } //根据传入的符号来判断是做加法还是减法运算 if(bzstr==="+"){ resultz=(Number(num0str)+Number(num1str)).toString(); }else{ resultz=Number(num0str)-Number(num1str).toString(); } //return resultz; return Number(resultz.slice(0,-lnz)+"."+resultz.slice(-lnz)); } //补全0 function getbq(str,len){ for(var i=0;i<len;i++){ str=str+"0"; } return str; } //浮点型数去小数点转字符串 function clearpoint(num,str){ return num.toString().replace(str,""); }
测试结果如下:
测试了几个数都没什么大问题。
个人知识有限,如有不正确的地方,望批评指正,共同学习进步!
标签:
原文地址:http://www.cnblogs.com/xwwin/p/4716747.html