js精确计算

82 阅读1分钟
// -----------------------------------------START---------------------------------------
// -----------------------------------------START---------------------------------------
let suan = {
    ADD(...args){
        // 处理与过滤
        const {nums,pm} = this.filter(args,'max');
        if( !nums.length || nums.length < 2 ){
            return nums[0]||0
        }
        let c = 0;
        for (let i = 0,nlen=nums.length; i < nlen; i++) {
            c += nums[i] * pm
        }
        return c/pm;
    },
    SUB(...args){
        // 处理与过滤
        const {nums,pm} = this.filter(args,'max');
        if( !nums.length || nums.length < 2 ){
            return nums[0]||0;
        }
        let c = 0;
        for (let i = 0,nlen=nums.length; i < nlen; i++) {
            if( !i ){
                c = nums[i] * pm;
            }else{
                c -= nums[i] * pm;
            }
        }
        return c/pm;
    },
    MUL(...args){
        // 处理与过滤
        const {nums,pm} = this.filter(args,'sum');
        if( !nums.length || nums.length < 2 ){
            return nums[0]||0
        }
        let c = 1;
        for (let i = 0,nlen=nums.length; i < nlen; i++) {
            c *= Number((nums[i]+'').replace(".",""))
        }
        return c/pm;
    },
    DIV(...args){
        // 处理与过滤
        const {nums,pm} = this.filter(args,'sub');
        if( !nums.length || nums.length < 2 ){
            return nums[0]||0
        }
        let c = 1;
        for (let i = 0,nlen=nums.length; i < nlen; i++) {
            if( !i ){
                c = Number((nums[i]+'').replace(".",""));
            }else{
                c /= Number((nums[i]+'').replace(".",""));
            }
        }
        return this.MUL(c,pm).toFixed(2);
    },
    filter(l,f){
        let a = [];
        let m = 0;
        let s = 0;
        let si = f === 'sub'?l.length-1:0;
        let of = {
            max(){
                m = Math.max(m,s.length);
            },
            sum(){
                m += s.length;
            },
            sub(i){
                if( !i ){
                    m = s.length;
                    return;
                }
                m -= s.length;
            },
        }
        for (let i = 0,len=l.length; i < len; i++) {
            if( l[i] = l[i] * 1 ){
                s = (l[ Math.abs(si-i) ]+'').split(".")[1]||'';
                of[f] && of[f](i);
                a.push( l[i] );
            }
        }
        return {
            nums: a,
            pm: Math.pow(10, m)
        };
    },
}
// -----------------------------------------END-----------------------------------------
// -----------------------------------------END-----------------------------------------


// -----------------------------------------START---------------------------------------
// -----------------------------------------START---------------------------------------
var calc = {
    /*
    函数,加法函数,用来得到精确的加法结果  
    说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。
    参数:arg1:第一个加数;arg2第二个加数;d要保留的小数位数(可以不传此参数,如果不传则不处理小数位数)
    调用:Calc.Add(arg1,arg2,d)  
    返回值:两数相加的结果
    */
    Add: function (arg1, arg2) {
        arg1 = arg1.toString(), arg2 = arg2.toString();
        var arg1Arr = arg1.split("."), 
        arg2Arr = arg2.split("."), 
        d1 = arg1Arr.length == 2 ? arg1Arr[1] : "", 
        d2 = arg2Arr.length == 2 ? arg2Arr[1] : "";
        var maxLen = Math.max(d1.length, d2.length);
        var m = Math.pow(10, maxLen);
        var result = Number(((arg1 * m + arg2 * m) / m).toFixed(maxLen));
        var d = arguments[2];
        return typeof d === "number" ? Number((result).toFixed(d)) : result;
    },
    /*
    函数:减法函数,用来得到精确的减法结果  
    说明:函数返回较为精确的减法结果。 
    参数:arg1:第一个加数;arg2第二个加数;d要保留的小数位数(可以不传此参数,如果不传则不处理小数位数
    调用:Calc.Sub(arg1,arg2)  
    返回值:两数相减的结果
    */
    Sub: function (arg1, arg2) {
        return Calc.Add(arg1, -Number(arg2), arguments[2]);
    },
    /*
    函数:乘法函数,用来得到精确的乘法结果  
    说明:函数返回较为精确的乘法结果。 
    参数:arg1:第一个乘数;arg2第二个乘数;d要保留的小数位数(可以不传此参数,如果不传则不处理小数位数)
    调用:Calc.Mul(arg1,arg2)  
    返回值:两数相乘的结果
    */
    Mul: function (arg1, arg2) {
        var r1 = arg1.toString(), r2 = arg2.toString(), m, resultVal, d = arguments[2];
        m = (r1.split(".")[1] ? r1.split(".")[1].length : 0) + (r2.split(".")[1] ? r2.split(".")[1].length : 0);
        resultVal = Number(r1.replace(".", "")) * Number(r2.replace(".", "")) / Math.pow(10, m);
        return typeof d !== "number" ? Number(resultVal) : Number(resultVal.toFixed(parseInt(d)));
    },
    /*
    函数:除法函数,用来得到精确的除法结果  
    说明:函数返回较为精确的除法结果。 
    参数:arg1:除数;arg2被除数;d要保留的小数位数(可以不传此参数,如果不传则不处理小数位数)
    调用:Calc.Div(arg1,arg2)  
    返回值:arg1除于arg2的结果
    */
    Div: function (arg1, arg2) {
        var r1 = arg1.toString(),
        r2 = arg2.toString(), m, resultVal, d = arguments[2];
        m = (r2.split(".")[1] ? r2.split(".")[1].length : 0) - (r1.split(".")[1] ? r1.split(".")[1].length : 0);
        resultVal = Number(r1.replace(".", "")) / Number(r2.replace(".", "")) * Math.pow(10, m);
        return typeof d !== "number" ? Number(resultVal) : Number(resultVal.toFixed(parseInt(d)));
    },
};
// -----------------------------------------END-----------------------------------------
// -----------------------------------------END-----------------------------------------


// -----------------------------------------START---------------------------------------
// -----------------------------------------START---------------------------------------
//加    
function floatAdd(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 floatSub(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));    
   //动态控制精度长度    
   n=(r1>=r2)?r1:r2;    
   return ((arg1*m-arg2*m)/m).toFixed(n);    
}    
//乘    
function floatMul(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);     
}     
//除   
function floatDiv(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){}     
       
     r1=Number(arg1.toString().replace(".",""));  
  
     r2=Number(arg2.toString().replace(".",""));     
     return (r1/r2)*Math.pow(10,t2-t1);     
}  
// -----------------------------------------END-----------------------------------------
// -----------------------------------------END-----------------------------------------


// -----------------------------------------START---------------------------------------
// -----------------------------------------START---------------------------------------
/**
 * 加法函数,用来得到精确的加法结果
 * @param {Object} arg1
 * @param {Object} arg2
 */
 function accAdd(arg1, arg2) {
    var r1 = deal(arg1);
    var r2 = deal(arg2);
    var m = Math.pow(10, Math.max(r1, r2))
    return(arg1 * m + arg2 * m) / m
}

/**
 * 乘法函数,用来得到精确的乘法结果
 * @param {Object} arg1
 * @param {Object} arg2
 */
function accMul(arg1, arg2) {
    var m = 0;
    m += deal(arg1);
    m += deal(arg2);
    var r1 = Number(arg1.toString().replace(".", ""));
    var r2 = Number(arg2.toString().replace(".", ""));
    return(r1 * r2) / Math.pow(10, m)
}

/**
 * 除法函数,用来得到精确的除法结果
 * @param {Object} arg1
 * @param {Object} arg2
 */
function accDiv(arg1, arg2) {
    var t1 = deal(arg1);
    var t2 = deal(arg2);
    var r1 = Number(arg1.toString().replace(".", ""))
    var r2 = Number(arg2.toString().replace(".", ""))
    return(r1 / r2) * Math.pow(10, t2 - t1);
}

/**
 * 求小数点后的数据长度
 */
function deal(arg) {
    var t = 0;
    try {
        t = arg.toString().split(".")[1].length
    } catch(e) {}
    return t;
}
// -----------------------------------------END-----------------------------------------
// -----------------------------------------END-----------------------------------------