Js numerical precision into the pit again

js numeric types have been calculated a pit, is the question about the accuracy of the calculation. When calculating 0.1 + 0.2,0.3-0.1 other operations in js, there will be a very long list of amazing value, I believe many people have encountered

0.1+0.2  //0.30000000000000004
0.3-0.1  //0.19999999999999998复制代码

About the cause of the problem, the Internet has a lot of explanation, the general accuracy of floating-point type is js problems caused, so when calculations we usually take some methods, the value of the interception of need.

Back to the topic, this pit is encountered accuracy problems, but not a subtraction but multiplication, a floating-point number is multiplied by 10, the result is stunning long --------

0.68*10  //6.800000000000001复制代码

Many people may encounter precision multiplication problem, but I really was the first time such a problem. BACKGROUND problem arises in that the rear end of a floating point number returns m, on the basis of superior distal end 10, is converted to "m off" to show the words on the page. Demand is very simple, but there is a hidden pit.

In fact, to solve this pit is not difficult, there are many ways online, here are a few:

( . 1) Method toFixed

Float * 10 and then call toFixed ways to solve this problem, but there is a problem, the problem is that there will be rounded, if required accurate return value to show the background, this method will be flawed.

(0.68*10).toFixed(2)  //此时没问题,结果为6.80
(0.0686*10).toFixed(2)  //小数位数多的时候就会有四舍五入问题,此时结果为0.69复制代码

(2) The floating-point number multiplied by a multiple of 10, then divided by respective multiples of 10

This method is also very common, the floating-point number is converted to an integer multiple of the corresponding divided into a floating point. This method can basically cover large part of the problem, but not a method to try is uncertain when the number of bits of floating point numbers can not accurately determine the exact multiplied by a multiple of 10.

0.68*1000/100   //此时结果正常,结果为6.8

假如返回的浮点数不确定位数,但是依旧按乘1000/100方式计算
0.00000068*1000/100   //结果又很给力了, 结果为0.000006799999999999999复制代码

(3) conversion using the correlation method Math

This method is the use of Math.round Math.pow and data processing methods, a method borrowed from the Internet

function myFixed(a, b) {
  return Math.round(a * Math.pow(10, b)) / Math.pow(10, b);
}
console.log(0.68*10);              //6.800000000000001
console.log(myFixed(0.68*10, 2));  //6.8复制代码

( 4) The method of converting a string

Finally, talk about the way we fill the pit, because here the application of value only to convert it to a discount value, it can be said is that no arithmetic processing, and therefore uses a straightforward method of string interception directly on the code:

//此方法考虑数值都是大于等于0的数值,并且对0和大于1的数值进行了展示(理论上折扣券不会出现0和大于1的情况)
function discounts(discountNumber){  
    if (!discountNumber && discountNumber !== 0) {
        return  
    }  
    const expPoint = /\./
    let countString = String(discountNumber)  
    let discountString = ''  
    if(countString < 1 && expPoint.test(countString)){    
        let discountArr = countString.split('.')[1].split('')    
        if(discountArr.length === 1){      
            discountString = discountArr[0]    
        }else{      
            let discountStringFirst = discountArr[0]      
            let discountStringSecond = discountArr.slice(1).join('')      
            discountString = discountStringFirst + '.' + discountStringSecond
        }
    }else{    
        discountString = countString * 10  
    }  
    return discountString
}

discounts(0)     //0
discounts(0.3)   //3
discounts(0.68)  //6.8
discounts(0.9)   //9
discounts(1)     //10
discounts(1.02)  //10.2复制代码

This problem has been resolved, and basically cover all normal circumstances.

Last but not least, on numerical accuracy problems in development must be careful, the slightest mistake will fall into the pit long floating-point number, in this case also the record and tell yourself, avoid back again into the pit.


Reproduced in: https: //juejin.im/post/5d00f01e518825382565c473

Guess you like

Origin blog.csdn.net/weixin_34026276/article/details/93169125