Number_js decimal calculation accuracy problem (mathjs)


In js, there is no distinction between floating-point and integer types, as long as it is a number, it is a number type.

In a computer, all data is 二进制stored in the form of .

(decimal) decimal to binary conversion

Decimal decimals are converted to binary 乘2取整法至值为0或无限循环until adopted.

Example -> 0.1

Convert 0.1 to binary for storage

0.1*2=0.2 --------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
0.4*2=0.8 --------0
0.8*2=1.6 --------1
0.6*2=1.2 --------1

So 0.1 converted to binary is 0.00011 0011 0011 0011 ...

Example -> 0.2
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
0.4*2=0.8 --------0
0.8*2=1.6 --------1
0.6*2=1.2 --------1

So 0.2 converted to binary is 0.0011 0011 0011 0011 ...

decimal storage

The number type in js is equivalent to the double type in other strongly typed languages, that is, the double precision floating point type. A number type data is represented by 64位a binary number. The 64-bit binary number functions as follows:
insert image description here

  • Sign bit: used to indicate the sign of the number, 0 is a positive number, 1 is a negative number
  • Exponent bit: Generally, scientific notation is used to express the numerical value, but here it is generally binary scientific notation, indicating how many powers of 2
  • Decimal Places: store decimals
Example of decimal storage process --> 0.1 storage
  • [1] Convert 0.1 to binary

    0.1 converted to binary is 0.00011 0011 0011 0011 ...

  • [2] The scientific notation IEEE745 standard is used to store decimals, and all values ​​are converted to 1.xxxxxthis format by default

    Tips: In the end, all data is 1.xxxx, and the data format is uniform, so 1 is omitted when storing, which can store one more decimal place!

    0.1 is stored in this format as 1.1001 1001 1001 1... * 2 to the power of -4

  • [3] Stored procedure

    • (1) sign bit

      positive number: 0

    • (2) Index bit

      The exponent occupies 11 bits in total, and the values ​​are 00000000000~11111111111. The
      intermediate value 11111111111/2 01111111111 is regarded as a
      positive value of 0++
      -1 01111111110
      -2 0111111101

      Negative value –
      1 10000000000
      2 100 00000001

      The exponent of 0.1 is -4 and converted to binary as 01111111011

    • (3) Decimal place storage: only 52 decimal places can be stored, so keep the decimal places as 52

      NOTE: Decimal-like rounding in stored procedures:若是末尾为1,则前一位加1,若是末尾为0,则不变

      The decimal place of 0.1 is
      1001100110011001100110011001100110011001100110011001...
      The last digit is
      1001100110011001100110011001100110011001100110011010

    • The final storage result is: 0011111110111001100110011001100110011001100110011001100110011010

      Therefore, the precision may be lost when the decimal is stored.

decimal calculation

When calculating decimals, the data is converted into 对应的binary and then calculated

When calculating the addition of floating-point numbers, it is necessary to perform "alignment" first, 较小convert the exponent to the exponent 较大, and shift the decimal part to the right accordingly. ==>省略后不要忘记进位哦~

Example to illustrate decimal calculation 0.1+0.2

0.1 converted to binary is 1.1001 1001 1001 ... * 2 to the -4 power
0.2 converted to binary is 1.1001 1001 1001 ... * 2 to the -3 power

The powers of the two are not the same

0.11001100110011001100110011001100110011001100110011010
1.1001100110011001100110011001100110011001100110011010

结果
10.0110011001100110011001100110011001100110011001100111 0
转化为标准形式
1.0011001100110011001100110011001100110011001100110011 10
保留52位小数
1.0011001100110011001100110011001100110011001100110100
存储
0 01111111011 0011001100110011001100110011001100110011001100110100

Decimal Storage Summary

That is to say, the decimal loses its precision once during the storage process, and loses its precision once again during the calculation, so the result is inaccurate and there are too many decimal places during the calculation process;

So how to solve the problem of loss of precision when calculating decimals?

  1. Can convert decimals to integers for calculations
  2. Use Number's toFixed method to retain fixed decimal places (no decimals will be filled with 0)
  3. Use the plugin mathjs to solve

mathjs plugin

  • download

    npm install mathjs
    
  • configuration

    import {
          
           create, all } from 'mathjs'
    const config = {
          
          
      number: 'BigNumber', // 可选值:number BigNumber
    }
    const math = create(all, config)
    

    Note that if the number configuration item is , BigNumberit can solve the problem of decimals losing precision, and if the value is number, the decimal calculation will still lose precision!

  • Use evaluatemethods to solve the problem of infertility

    math.evaluate(0.1+0.2) // 0.30
    

Guess you like

Origin blog.csdn.net/qq_43260366/article/details/129625970