The most understandable explanation of the accuracy problemFor example, the number 1÷3=0.33333333... Everyone knows that 3 will repeat infinitely, and mathematics can express it, but the computer needs to store it so that it can be retrieved and used next time. But 0.333333... this number repeats infinitely, how do you let the computer store it? No matter how big the computer's memory is, it can't store everything, right! So it can't store a value relative to mathematics, it can only store an approximate value, so when the computer stores it and then takes it out for use, there will be accuracy problems. JS exceeds the precision of the number solution1. The maximum safe number in js is Math.pow(2,53) - 1. If the number exceeds this, the precision will be lost. You can solve it by converting the number into a string, as follows: // js maximum safe number: Math.pow(2, 53)-1 let a = '123456444565456.889' let b = '121231456.32' // a + b = '123456565796913.209' function addTwo(a, b) { //1. Compare the lengths of two numbers and add 0 to the front of the shorter one if (a.length > b.length) { let arr = Array(a.length - b.length).fill(0); b = arr.join('') + b } else if (a.length < b.length) { let arr = Array(b.length - a.length).fill(0); a = arr.join('') + a } //2. Reverse the two numbers (this is because people are used to adding from left to right, but numbers are added from right to left, so reversing them is easier to understand) a = a.split('').reverse(); b = b.split('').reverse(); //3. Loop through two arrays and add them. If the sum is greater than 10, then sign = 1, and the value at the current position is (sum % 10) let sign = 0; //mark whether there is carry let newVal = []; //used to store the final result for (let j = 0; j < a.length; j++) { let val = a[j] / 1 + b[j] / 1 + sign; // Divide by 1 to ensure that they are all numbers. You can also use Number() here. if (val >= 10) { sign = 1; newVal.unshift(val % 10) // unshift is used here instead of push because it saves the need to use reverse } else { sign = 0; newVal.unshift(val) } } // The last addition needs to add a digit '1' return sign && newVal.unshift(sign) && newVal.join('') || newVal.join('') } // Refer to other friends' concise writing function addTwo(a,b) { let temp = 0 let res = '' a = a.split('') b = b.split('') while(a.length || b.length || temp) { temp += Number(a.pop() || 0) + Number(b.pop() || 0) res = (temp%10) + res temp = temp > 9 } return res.replace(/^0+/g, '') } 2. When it comes to adding decimal parts, encapsulate the above method once and the complete implementation is as follows: let a = '123456444565456.889' let b = '121231456.32' // a + b = '123456565796913.209' function addTwo(a = '0',b = '0', isHasDecimal=false) { //1. Compare the lengths of two numbers and add 0 to the front of the shorter one if (a.length > b.length) { let arr = Array(a.length - b.length).fill(0); b = isHasDecimal && (b + arr.join('')) || arr.join('') + b } else if (a.length < b.length) { let arr = Array(b.length - a.length).fill(0); a = isHasDecimal && (a + arr.join('')) || arr.join('') + a } //2. Reverse the two numbers (this is because people are used to adding from left to right, but numbers are added from right to left, so reversing them is easier to understand) a = a.split('').reverse(); b = b.split('').reverse(); //3. Loop through two arrays and add them. If the sum is greater than 10, then sign = 1, and the value at the current position is (sum % 10) let sign = 0; //mark whether there is carry let newVal = []; //used to store the final result for (let j = 0; j < a.length; j++) { let val = a[j] / 1 + b[j] / 1 + sign; // Divide by 1 to ensure that they are all numbers. You can also use Number() here. if (val >= 10) { sign = 1; newVal.unshift(val % 10) // unshift is used here instead of push because it saves the need to use reverse } else { sign = 0; newVal.unshift(val) } } // The last addition needs to add a digit '1' return sign && newVal.unshift(sign) && newVal.join('') || newVal.join('') } function add(a,b) { let num1 = String(a).split('.') let num2 = String(b).split('.') let intSum = addTwo(num1[0], num2[0]) let res = intSum if (num1.length>1 || num2.length > 1) { let decimalSum = addTwo(num1[1], num2[1], true) if (decimalSum.length > (num1[1]||'0').length && decimalSum.length > (num2[1]||'0').length) { intSum = addTwo(intSum, decimalSum[0]) decimalSum = decimalSum.slice(1) res = `${intSum}.${decimalSum}` } else { res = `${intSum}.${decimalSum}` } } return res } console.log(add(a, b)) // 123456565796913.209 // console.log(add('325', '988')) // 1313 Look at some typical problems with JS digital precision loss
SummarizeThis is the end of this article about how to solve the problem of out-of-precision numbers in JS. For more relevant content about out-of-precision numbers in JS, please search for previous articles on 123WORDPRESS.COM or continue to browse the related articles below. I hope you will support 123WORDPRESS.COM in the future! You may also be interested in:
|
<<: Installing MySQL 8.0.12 based on Windows
>>: Teach you how to deploy Vue project with Docker
<div class="box"> <img /> &...
Table of contents Manual backup Timer backup Manu...
Copy code The code is as follows: <!DOCTYPE ht...
Payment countdown to return to the home page case...
Import the data exported from the Oracle database...
effect: The GROUP_CONCAT function can concatenate...
Table of contents What are immutable values? Why ...
Preface When testing, in order to test the projec...
Preface The reason why MySQL's innodb engine ...
Table of contents 1. Introduction 2. Main text 2....
When using justify-content:space-between layout, ...
<br />Previously, we learned how to set cell...
1. Background Although I have read many blogs or ...
Ping www.baidu.com unknown domain name Modify the...
Table of contents Two ways to solve the problem o...