The pit of automatic primary key in JS precision loss

1. Scenario description


 

    It is found that after js converts the data in the response into json format, the value is different.
    Reason: In js, the Number type is uniformly handled as a floating-point type. The loss of precision of large integers is essentially the same as that of floating-point numbers. The maximum number of mantissa bits is 52 bits. Therefore, the largest integer that can be accurately represented in JS is Math.pow(2 , 53), the decimal is 9007199254740992, and the precision may be lost if it is greater than 9007199254740992.

Solution: The background converts Long to string and returns it to the front section.

2. Introduction

to floating-point numbers     For floating-point data, single-precision type (float) and double-precision type (double) are used, which are stored in accordance with the floating-point number storage standard (developed by IEEE). Float data occupies 32 bits, and double data occupies 64 bits.

    单精度的存储方式如下图所示:


    双精度的存储方式如下图所示:


三、浮点数转二进制
      例如:9.2转二进制
      整数部分:9 ==> 1001
      小数部分转二进制:小数乘以2,取Integer, continue to multiply the fractional part by 2, round to the whole, until the fractional part 0 is obtained, arrange the integers in order.
      For example, 0.2
          0.2 * 2 = 0.4, round 0, the fractional part 0.4
          0.4 * 2 = 0.8, round 0, the fractional part 0.8
          0.8 * 2 = 1.6, rounded to 1, fractional part 0.6
          0.6 * 2 = 1.2, rounded to 1, fractional part 0.2
          .... Infinite loop is
      0011*N

4. Binary storage of floating-point numbers

        • Sign bit: 0 for positive numbers, 1 for negative numbers.
        • For the exponent part N, because the exponent can be positive or negative, the exponent range that the 8-bit exponent can represent should be: -127~128, so it can be offset, according to the storage label of floating-point numbers (IEEE), float The starting number of the exponent of the type is 127 (binary 0111 1111), and the starting number of the exponent of the double type is 1023 (binary 011 1111 1111). On this basis, add the exponent to get the representation of the exponent in memory. So the exponent Part of the storage adopts shift storage, the stored data is 32-bit metadata +127, 64-bit is +1023
        • The mantissa is directly filled in, if the number of digits is insufficient, 0 is added, and if there are too many digits, 0 is rounded to 1.

    举个栗子:9.125
    整数部分:9.125==>9==>1001
    小数部分:
        0.125 * 2 = 0.25 ==> 取整0,余数0.25 ==>0
        0.25 * 2 = 0.5 ==> 取整0, Remainder 0.5 ==>0
        0.5*2 = 1.0 ==> Rounding to 1 ==>1
    9.125 ==> 1001.001==> 1.001001*2^3
    1.001001 * 2^3 ==>
    0 127 +3 0010 01 ==>
    0 1000 0010 0010 01 ==> 0100 0001 0001 0010 0000000000000000


5. Loss of precision of floating-point numbers
    2.2 is converted into binary as 0 0111 1110 00110011001100110011 …. Infinite, but because the number of digits stored in float and double is limited, the part that exceeds the number of digits must be truncated.
    This leads to the possibility that 2.2 is eventually retained:
    0 (1 sign bit) 0111 1110 (8 exponent bits) 00110011001100110011... (23 bits)

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326419319&siteId=291194637