Why 0.1 + 0.2! = = 0.3

console.log( 0.1 + 0.2= =0.3) //false
Copy the code

When performing arithmetic operations, JS will first convert the decimal number to the binary number and then calculate. The decimal number to the binary number is rounded by x 2. The binary number of 0.1 and 0.2 is an infinite repeating decimal number.

In JS, a number has only 64 bits, in which the precision bits (significant bits) have only 52 bits, so when there is an infinite repeating decimal, the first 52 bits (similar to rounding decimal) will be cut through the rule of 0 round 1, which leads to the loss of precision bits. 0.1 has a larger number of numbers involved in the calculation, and 0.2 has a smaller number involved in the calculation, so the result is not necessarily equal to 0.3.

0.1 + 0.2 the extra 0.0… Where does the four come from

console.log( 0.1 + 0.2) / / 0.30000000000000004
Copy the code

0.1 to binary computing

Binary number is infinite decimals 0.1:0.00011001100110011001100110011001100110011001100110011001…

53 is 1, when in front of the interception of 52 0 s 1 into the actual participation after operation is: 0.0001100110011001100110011001100110011001100110011010

0.2 to binary calculation

Binary number is infinite decimals 0.2:0.00110011001100110011001100110011001100110011001100110011…

53 is 0, 0 when in front of the interception of 52 s involved in actual operation is: after 1 in 0.0011001100110011001100110011001100110011001100110011

The extra 0.0… 4

So 0.0… 4 is the sum of the input part of 0.1 rounded off by 0 and the input part of 0.2 rounded off by 0.

Why does 0.1 + 0.1 === 0.2

0.1 to binary is an approximation, and 0.2 to binary is an approximation, and the sum of the two approximations happens to be equal to another approximation.

It just happens to be equal, and floating-point numbers are still not compared by the === sign.

The correct way to compare floating point numbers

The correct way to compare floating-point numbers is to compare whether absolute values are within the minimum accuracy range provided by JS

console.log( Math.abs(0.1 + 0.2 - 0.3) < =Number.EPSILON) //true
Copy the code

How does JavaScript represent a number

A double – precision floating – point number

The Number type in JS basically conforms to the double precision floating point Number rules stipulated by IEEE 754-2008. IEEE can read as I Treble E. According to the definition of floating-point numbers, double-precision floating-point numbers are made up of 64 bits, as shown below :(bits here refer to binary, 0 or 1)

The 64-bit bits are:

  • Sign bit 1 bit: does not participate in the calculation, 0 represents a positive number, 1 represents a negative number;
  • Exponential digit 11: there is a base value of 01111111111, below which the exponential digit is negative. Because the exponential bits have no sign bits, and the exponential bits of scientific notation can be negative. The conversion subtracts this base value;
  • 52 significant digits: significant digits hide a 1 because starting with 0 is meaningless;

The significant bits determine the precision of this number, and the exponential bits indicate the range of floating-point representations. Floating-point numbers can represent very large numbers. At the maximum number, not every integer may be represented, and the larger the number, the sparser the number, because significant digit accuracy is lost. The formula for converting 64-bit binary to decimal is:

  • Decimal digit = sign digit + significant digit x 2^(exponent -2047)

The exponential and significant digits above correspond to the scientific counting method. A decimal number converted to binary and then to binary scientific numerals, resulting in exponential and significant digits.

The process of converting a decimal number to a 64-bit floating-point number

Graph TD 10 base to binary --> binary to scientific notation to get exponential and significant digits --> exponential and significant digits are represented in binary

Taking the decimal number 12.25 as an example, the conversion to 64-bit binary is as follows:

  • The first step is to convert the integer part 12 to binary to get 1100;
  • In the second step, the decimal part 0.25 is converted to binary to get 0.01.
  • The third step, the combined result is 1100.01;
  • In the fourth step, the binary number is converted into scientific notation to obtain the exponential and significant digits
    • According to the laws of scientific counting, the integer part is reserved for one bit, so the decimal point is moved three places to the left, resulting in the exponential place 3 and the significant place 1.10001
  • Fifth, determine the value of each bit of the double – precision floating-point number
    • Sign bit 1 bit: 0 positive
    • Index bit 11:3 -> 00000000011 -> 00000000011 + 01111111111 (reference value) -> 10000000010
    • Significant digit 52: 1.10001 – > 1.1000100000000000000000000000000000000000000000000000 – > For 1000100000000000000000000000000000000000000000000000, the first is one hidden.
  • Step 6, merging the results as follows: 0100000000101000100000000000000000000000000000000000000000000000 per person

Hexadecimal conversion

How to convert decimal to binary

The conversion rule is rounded x 2, decimal number 0.8125 = 0.11101, the conversion process to binary is as follows:

Decimal number 0.2 = 0.0011001100110011001100110011001100110011001100110011… , from the 5th decimal point into the infinite loop, the conversion to binary process is as follows:

How to convert a decimal integer to a binary floating point number

The conversion rule is ÷ 2 mod, decimal number 125 = 1111101, conversion to binary process is as follows:

Recommended conversion tools:

  • www.h-schmidt.net/FloatConver…
  • www.binaryconvert.com/convert_dou…

If there are mistakes welcome to point out, welcome to discuss together!