# Don’t say much, code first.

``````function judgeFloat(n, m) {
const binaryN = n.toString(2);
const binaryM = m.toString(2);
Log (` \$ {n} binary is \${binaryN} `);
Log (` \$ {m} binary is \${binaryM} `);
const MN = m + n;
const accuracyMN = (m * 100 + n * 100) / 100;
const binaryMN = MN.toString(2);
const accuracyBinaryMN = accuracyMN.toString(2);
Log (` \$ {n}+\$ {m} binary is \${binaryMN} `);
Log (` \$ {accuracymn} binary is \$ {accuracybinaryman} `);
Log (` \$ {n}+\$ {m} binary to decimal is \${to10(binaryMN)} `);
Log (` \$ {AccurateMn} binary is converted to decimal again is \$ {TO10 (AccurateBinaryMan)} `);
Log (` \$ {n}+\$ {m} counts as \$ {(to10 (binary Mn) = = = to10 (accurate binary ymn)) in js)?  '':' not'} exact');
}
function to10(n) {
const pre = (n.split('.') - 0).toString(2);
const arr = n.split('.').split('');
let i = 0;
let result = 0;
while (i < arr.length) {
result += arr[i] * Math.pow(2, -(i + 1));
i++;
}
return result;
}
judgeFloat(0.1, 0.2);
judgeFloat(0.6, 0.7);``````

Due to`JavaScript`There is no decimal in`Binary`Convert to`Decimal system`Method, so manually implemented a. # First, let’s come to a simple conclusion.

All the data in the computer is based on`Binary`Stored, so the computer must first convert the data into`Binary`To calculate, and then in the calculation results into`Decimal system`.

It is not difficult to see from the above code, in the calculation`0.1+0.2`At that time,`Binary`The calculation lost precision, resulting in reconversion into`Decimal system`The results were not in line with the expected results.

In fact, there are some theme parties. A function does not allow you to understand it in depth. You have to continue to look at the following …

# Analysis of Results-More Questions

`0.1`And`0.2`The binary numbers of the are all decimals with 1100 infinite cycles. Let’s look at the results calculated by JS one by one.

Binary of 0.1

``0.0001100110011001100110011001100110011001100110011001101``

Binary of 0.2

``0.001100110011001100110011001100110011001100110011001101``

In theory, the sum of the above results should be:

``0.0100110011001100110011001100110011001100110011001100111``

The binary of 0.1+0.2 calculated by actual JS

``0.0100110011001100110011001100110011001100110011001101``

As a code obsessive-compulsive disorder, I have a new problem:

Is there so many bits instead of more in the 0.1 binary calculated by Why js? ? ?

Is the binary result of (0.1+0.2) calculated by Why js different from that of (0.1+0.2) calculated by ourselves? ? ?

Why 0.1 binary+0.2 binary! = 0.3 binary? ? ?

# How js Stores Binary Decimal Numbers

decimal`Binary`Most of them are infinite loops,`JavaScript`How do you store them?

InECMAScript® language specificationAs can be seen in,`ECMAScript`hit the target`Number`Type compliance`IEEE 754`Standards. It is represented by a 64-bit fixed length.

In fact, many languages follow this standard for numeric types, for example`JAVA`So many languages have the same problems as above.

So don’t spray when you meet this kind of problem next time.`JavaScript`

If you are interested, you can look at this website.http://0.30000000000000004.com/Yes, you are right, that ishttp://0.30000000000000004.com/! ! !

# IEEE 754

The IEEE754 standard contains a binary representation of a set of real numbers. It consists of three parts:

• Sign bit
• Exponential bit
• Ending digit

The number of bits in each part of floating point numbers with three precision is as follows: `JavaScript`It uses 64-bit double-precision floating-point encoding, so its`Sign bit`hold`1`Bits, Index Bits`11`Bits, mantissa bits accounted for`52`Bits.

What do we understand below`Sign bit``Exponential bit``Ending digit`In order to`0.1`For example:

Its binary is:`0.0001100110011001100 ...`

In order to save storage space, it is expressed by scientific counting in computers, that is

`1.100110011001100 ...`X 2-4

If this is not easy to understand, think about decimal numbers:

`1100`The scientific counting method of is`11`X 102

So: `Sign bit`Is to identify the positive and negative,`1`show`Negative`,`0`show`Positive`;

`Exponential bit`Store the index of scientific counting method;

`Ending digit`Storing the effective number after scientific counting method;

Therefore, the binary we usually see is actually the mantissa bits actually stored by the computer.

# ToString(2 in js (2)

Since mantissa bits can only be stored`52`A number, this can explain`toString(2)`The results of the implementation of the:

If the computer does not have storage space limitations, then`0.1`The`Binary`Should be:

``0.00011001100110011001100110011001100110011001100110011001  ...``

Scientific counting mantissa

``1.1001100110011001100110011001100110011001100110011001  ...``

However, due to restrictions, the number of significant digits is`53`Bits and subsequent numbers cannot be stored, it follows, if so`1`Just move forward`1`If it is`0`The principle of abandoning.

The 53rd bit of the binary scientific counting method of 0.1 is 1, so the following results are obtained:

``0.0001100110011001100110011001100110011001100110011001101``

`0.2`With the same problem, in fact, it is precisely because of such storage that there is a loss of precision, which leads to`0.1+0.2! =0.3`.

As a matter of fact, there are still many calculations with the same accuracy problem. We cannot write them all down, so when there are numerical calculations in the program, we’d better use the tool library to help us solve them. Here are two recommended open source libraries:

Now let’s look at the other two questions above.

# Why is the binary of 0.1 calculated Why JavaScript so many bits instead of more? ? ?

Above`toString`The principle helps us to solve this problem, in the effective number first`53`Figures after bits will follow`1 into 0`The principle of, only allowed to store in memory`52`A significant number.

# Why is the binary result of (0.1+0.2) calculated Why JavaScript different from that of (0.1+0.2) calculated by ourselves? ? ?

Our own calculation of 0.1+0.2:

``0.0100110011001100110011001100110011001100110011001100111``

In fact, the effective number of this result has exceeded`52`Bit, we will proceed from the end`1 into 0`The following results were obtained

``0.0100110011001100110011001100110011001100110011001101``

# The maximum number that JavaScript can represent

By and`IEEE 754`Limitations of double precision 64-bit specification:

`Exponential bit`The maximum number that can be expressed:`1023`(Decimal)

`Ending digit`The maximum number that can be expressed is the mantissa bit`1`The situation of

So the largest number JavaScript can represent is acceded to the throne

`1.111 ...`X 21023This result is converted to decimal`1.7976931348623157e+308`The result is`Number.MAX_VALUE`.

# Maximum safety figure

In JavaScript`Number.MAX_SAFE_INTEGER`Indicates the maximum safety figure. The calculation result is`9007199254740991`That is, there will be no loss of precision (except decimals) within this range of numbers, which are actually`1.111 ...`X 252.

We can also use some open source libraries to handle large integers:

In fact, the government has also considered this issue.`bigInt`Type in`es10`It has been proposed in, now`Chrome`It is already available in.

# BigInt type

`BigInt`It is the seventh primitive type.

`BigInt`Is an integer with any precision. This means that variables can now be calculated`9007199254740991`That is, the number above the maximum safe integer.

``const b = 1n;  //append n to create BigInt``

In the past, greater than was not supported.`9007199254740992`The integer value of. If it exceeds, the value will be locked to`MAX_SAFE_INTEGER + 1`:

``````const limit = Number.MAX_SAFE_INTEGER;
⇨ 9007199254740991
limit + 1;
⇨ 9007199254740992
limit + 2;
⇨ 9007199254740992 <--- MAX_SAFE_INTEGER + 1 exceeded
const larger = 9007199254740991n;
⇨ 9007199254740991n
const integer = BigInt(9007199254740991);  // initialize with number
⇨ 9007199254740991n
const same = BigInt("9007199254740991");  // initialize with "string"
⇨ 9007199254740991n``````

typeof

``````typeof 10;
⇨ 'number'
typeof 10n;
⇨ 'bigint'``````