当前位置:网站首页>JS floating point multiplication and division method can not accurately calculate the problem

JS floating point multiplication and division method can not accurately calculate the problem

2022-06-25 14:18:00 jason_ renyu

JS The problem of accurate calculation is a pain point for some people to do finance or some calculation functions , for example :

//  Add 
0.1 + 0.2 = 0.30000000000000004
0.1 + 0.7 = 0.7999999999999999
0.2 + 0.4 = 0.6000000000000001
 
//  Subtraction 
0.3 - 0.2 = 0.09999999999999998
1.5 - 1.2 = 0.30000000000000004
 
//  Multiplication 
0.8 * 3 = 2.4000000000000004
19.9 * 100 = 1989.9999999999998
 
//  division 
0.3 / 0.1 = 2.9999999999999996
0.69 / 10 = 0.06899999999999999
 
//  Compare 
0.1 + 0.2 === 0.3 // false
(0.3 - 0.2) === (0.2 - 0.1) // false

Common solutions use math.js, If in vue or react In the project ( Below with vue For example ) Will use the corresponding mathjs.

Official website : http://mathjs.org/
cdn Address :https://cdnjs.cloudflare.com/ajax/libs/mathjs/5.0.0/math.js

JS Application examples in :

<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/5.0.0/math.js"></script>
<script type="text/javascript"> function fn_click(p){
       var a , b; a=0.7; b=0.1; if(p==1){
       alert(a+b); }else if(p==2){
       alert(eval("a+b")); }else if(p==3){
       math.config({
       number: 'BigNumber' }); var result = math.parser().eval(a + "+" + b) alert(result); } } </script>
</head>
<body>
  <input type="button" value="0.7+0.1" onclick="fn_click(1);" />
  <input type="button" value="eval(0.7+0.1)" onclick="fn_click(2);" />
  <input type="button" value="mathjs(0.7+0.1)" onclick="fn_click(3);" />
</body>
</html>

stay Vue Application examples in :
 Insert picture description here
 Insert picture description here

however , Use this way mathjs There will be many problems with large numbers , Below we use native js To encapsulate a solution to such a problem

Multiplication

const NumberMul = function(arg1, arg2) {
    
    var m = 0;
    var s1 = arg1.toString();
    var 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);
}

Add

const NumberAdd = function(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);
}

Subtraction

const NumberSub = function(arg1, arg2) {
    
    var re1, re2, m, n;
    try {
    
        re1 = arg1.toString().split(".")[1].length;
    } catch (e) {
    
    re1 = 0;
    }
    try {
    
        re2 = arg2.toString().split(".")[1].length;
    } catch (e) {
    
        re2 = 0;
    }
    m = Math.pow(10, Math.max(re1, re2)); 
    n = (re1 >= re2) ? re1 : re2;
    return ((arg1 * m - arg2 * m) / m).toFixed(n);
}

division

//  Divisor , Divisor ,  The number of decimal places reserved 
const NumberDiv = function (arg1,arg2,digit){
    
    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(".",""))
    // Get calculated value after decimal point 
   var result= ((r1/r2)*Math.pow(10,t2-t1)).toString()
    var result2=result.split(".")[1];
    result2=result2.substring(0,digit>result2.length?result2.length:digit);
 
    return Number(result.split(".")[0]+"."+result2);
}

Be careful : Divisor arg2 Not for 0, There is no judgment here , Attention, little friend

Usage mode ( Take multiplication as an example )

console.log(NumberMul(0.0058,100))
If in vue Used in , You can also put methods into the global , You can also use a single application in a page

for example ( Take the global approach as an example )

Vue.prototype.NumberMul = function(arg1, arg2) {
    
    var m = 0;
    var s1 = arg1.toString();
    var 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);
}

If this article is of great use to you, please like it !

In this paper, the reference :https://www.cnblogs.com/bushui/p/12150947.html

原网站

版权声明
本文为[jason_ renyu]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202200522173852.html