Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

In front-end development, especially in the field of e-commerce applications, dealing with digital computing can be said to be commonplace, digital computing is undoubtedly the most important. Shopping cart shows a wrong price, wrong discount calculation, background order total amount statistics/report data analysis and other calculation problems, is bound to be fatal.

scenario

Here are two scenarios:

  • The scene of a
// From the Chrome browser console type:
0.1 + 0.2= = =0.3   // Output: false
0.1 + 0.2   // Press Enter to output 0.30000000000000004
Copy the code
  • Scenario 2
// From the Chrome browser console type:
9999999999999999= =10000000000000000  // Output: true
Copy the code

The first time you look at it, it might be a bit of a shock, but for people with front-end experience, it’s a precision problem and the numbers are out of bounds.

reveal

To explain both scenarios, let’s start with binary.

When learning the basic computer, we know that the computer is built by the integrated circuit, such electronic components, its pin can only support 0V or 5V two states, this state also determines that the computer can only process data through binary numbers, that is, 0 and 1. Meanwhile, the basic unit of information that a computer processes is: 1 byte (a byte is equal to 8 binary digits). (PS: The binary concept is not our focus, we just need to know that computers process data according to binary)

JavaScript, on the other hand, follows the IEEE 754 specification and therefore uses double precision, occupying 64 bits. Binary representation is shown as follows:

It means:

  • Bit 1: Used to represent the sign bit
  • Digits 2-12: used to indicate the index
  • Bits 13-64: Used to indicate the mantissa

Therefore, we can see that the computer describes the value using 64 bits, minus 11 bits for the index, the maximum 10 base value that can be described is: Math.pow(2, 53), that is, the value: 9007199254740992. At the same time, there are some irrational numbers in the number, they are infinite, in other words, the computer with finite bits to represent the infinite value, there will be a loss of precision, the number is full, only according to some convention (round) data processing. Here infinite numbers are precisely binary numbers, so seemingly infinite numbers can also correspond to infinite binary representations, as in scenario 1.

Let’s execute scenario 1 from the computer’s point of view:

/ / input:
0.1 + 0.2
// Numeric conversion to binary: Becomes infinite binary, but the number of digits the computer can represent is finite
0.1 >> 0.0001 1001 1001 1001 1001. (1001Infinite loop)0.2 >> 0.0011 0011 0011 0011 0011. (0011Infinite loop)// 10 Decimal to binary calculation: the value ✖️2 is carried, and the decimal place continues ✖️2 until it is 0
0.2*2 = 0.4 0
0.4*2 = 0.8 0
0.8*2 = 1.6 1
0.6*2 = 1.2 1
0.2*2 = 0.4 0
Copy the code

Scenario 2, beyond math.pow (2,53) may have accuracy problems, and be careful when calculating large numbers

// 
Math.pow(2.53)     // Output: 9007199254740992
Math.pow(2.53) +1   // Output: 9007199254740992
Math.pow(2.53) +2   // Output: 9007199254740994
Copy the code

At a glance, does that make sense?

The solution

To solve the problem of numerical calculation accuracy and large number calculation, we can package the library ourselves or use the tripartite library. Github’s 3.6K star big.js library is recommended because of its easy-to-use API, fast runtime, and compressed size of 6K. Of course, if you want to encapsulate your own library, you can do so, for example:

  1. When the calculation of very large numbers is not involved, only the precision problem is considered, and the solution can be: convert the floating point number into an integer, and then divide by the corresponding multiple after the calculation.
  2. When dealing with very large numbers, the simple idea is to slice the value into an array and invert it, then compute it from the lowest to the highest.

Hopefully reading this article will help you understand why there are accuracy issues.