js浮点数乘除法

JS在处理浮点数计算时经常会遇到精度的问题,上一篇博客封装了JS浮点数加减法的方法,这一次来封装一下js浮点数乘除法运算。


 

其实浮点除法的封装跟加减法的封装原理是一样,只是在第一次计算完后会再复位小数位数的时候稍微会复杂一点。

加法运算在第一次清除小数点计算后,根据小数位数的最大值可以知道计算后的结果应该再复位多少位小数。

而乘除法运算得分二种情况:

乘法运算时,二个数去掉小数点,相当于放大了10的对应二数小数点位数的和的次幂,所以计算完后的结果应该保留至少对应小数位数的和的位数;

除法运算时,二个数去掉小数点,相当于乘上了10的(被除数的小数位数-除数的小们数)次幂,如果被除数的小数位数-除数的小位数大于0则是小数增加对应位,如果是小于0则小数位数减少对应位

 


 

代码如下

 

//浮点数乘除法
    function muldivfloat(num0,num1,bzstr){
        var ln0=getws(num0),//第一个值的的小数位数
            ln1=getws(num1),//第二个值的的小数位数
            lnz=Math.max(ln0,ln1),//取得小数位数中的最大数
            lncz,//小数位数的统计值
            num0str,//第一个值数字转字符
            num1str,//第二个值数字转字符
            resultz,//计算结果
            lnqh;//除法后结果存储小数
        
        if(lnz===0){//如果数字原本就是整形,直接执行计算
            if(bzstr==="*"){
                resultz=Number(num0)*Number(num1);
            }else{
                resultz=Number(num0)/Number(num1);
            }
            return resultz;
        }
        
        num0str=clearpoint(num0,".");
        num1str=clearpoint(num1,".");
        //根据传入的符号来判断是做乘法还是除法运算
        if(bzstr==="*"){
            lncz=ln0+ln1;//小数位数的总数
            resultz=addwsfront((Number(num0str)*Number(num1str)).toString(),lncz);//对乘法运算后的结果执行位数补全
            return Number(resultz.slice(0,-lncz)+"."+resultz.slice(-lncz));
        } else {
            lncz=ln0-ln1;//小数位数的差数
            resultz=Number(num0str)/Number(num1str);
            if(lncz===0){//如果除数,被除除数小数位相同,即直接返回计算值
                return resultz;
            }
            lnqh=getws(resultz);//除法计算后可能的小数位数
            resultz=clearpoint(resultz,".");//除法运算结果去小数位数
            lncz=lncz+lnqh;//最后应该保留的小数位数
            if(lncz>0){//如果要保留的小数位数不够
                resultz=addwsfront(resultz,lncz);//对计算的结果前补0
                return Number(resultz.slice(0,-lncz)+"."+resultz.slice(-lncz));
            }else {//如果要保留的小数位数小于0
                lncz=Math.abs(lncz);
                resultz=addwsback(resultz,lncz);//对计算的结果后补0
                console.log(lncz,resultz);
                return Number(resultz);
            }
            
        }
        
        
    }
    //后补0补够位数
    function addwsback(str,len){
        for(var i=0;i<len;i++){
            str=str+"0";
        }
        return str;
    }
    //前置0补够位数
    function addwsfront(str,len){
        var getStr='',
            saveStr='',
            strLen=0,//存储当前字符串的长度
            addLen=0,//应该补位的个数
            returnStr='';
        //如果传进去的值是负值,那就要先存储符号
        if(str.indexOf('-')!=-1){
            getStr=str.replace('-','');
            saveStr='-';
        }else{
            getStr=str;
        }
        strLen=getStr.length;
        addLen=len-strLen;
        if(addLen<=0){
            returnStr=str;
        } else {
            for(var i=0;i<addLen;i++){
                getStr="0"+getStr;
            }
            returnStr=saveStr+getStr;
        }
        return returnStr;
    }
    //取得小数位数
    function getws(num){
        var ln=0;
        try {
            ln=num.toString().split(".")[1].length;//获取小数位数
        }catch(e){
            ln=0;
        }
        return ln;
    }
    //补全0
    function getbq(str,len){
        for(var i=0;i<len;i++){
            str=str+"0";
        }
        return str;
    }
    //浮点型数去小数点转字符串
    function clearpoint(num,str){
        var getStr=num.toString();
        if(getStr.indexOf(str)!=-1){
            return getStr.replace(str,"");
        }
        return getStr;
    }
View Code

 

结果如下:

至少575659.82*100是没有精度的问题啦,呵呵。

在线测试地址

个人知识有限,如有不正确的地方,望指正,共同学习进步!

现已把加减乘除打包成一个JS文件并修正了一些错误与bug,放在我的个人github空间里,欢迎star,欢迎下载使用,github地址

posted @ 2015-08-18 01:03  !win !  阅读(2811)  评论(0编辑  收藏  举报