Detailed discussion of memory and variable storage in JS

Detailed discussion of memory and variable storage in JS

Preface

In the front-end field, since most of the work is done with UI, memory management is the most easily overlooked part. If you don’t understand memory, you can’t see the essence of many problems and it’s difficult to write more qualified code. This time, I will take you into the world of memory.

JS Magic Number

Case 1: Calculation and transfer of amount

18.9 * 100
=1889.99999999999998

Case 2: Violation of mathematical laws

0.1 + 0.2 === 0.3
// false

(function (a, b, c) {
    return a + b + c === a + ( b + c )
})(0.1, 0.2, 0.3)
// false

Case 3: Infinite loop addition

(function (num) {
    while(true) {
        if (++num % 13 === 0) {
            return num
        }
    }
})(2 ** 53)

Case 4: JSON.parse

JSON.parse('{"a":180143985094813214124}')
//{a: 180143985094813220000}

From the above four cases, we can see that number calculations in computers often bring some "surprises". In order to prevent these unexpected results, we must first understand how Number is stored in Javascript?

Storing Numbers

Computers store data in binary, so numbers also need to be converted into corresponding binary: different combinations of 000 or 111.

How to convert binary

How to convert a number into binary, here is an example to illustrate:

Convert the decimal number 106.6953125106.6953125106.6953125 to binary

When you encounter a decimal conversion, you need to process the integer and decimal parts separately. Divide the integer 106106106 by 222 until the quotient is 000, and take the remainder result of each division by 222.

106 / 2 = 53 ... 0
53 / 2 = 26 ... 1
26 / 2 = 13 ... 0
13 / 2 = 6 ... 1
6 / 2 = 3 ... 0
3 / 2 = 1 ... 1
1 / 2 = 0 ... 1
The result is the remainder arranged from right to left 1101010

Multiply the decimal 0.69531250.69531250.6953125 by 222 until there are no decimal places, and count the integer results after each multiplication.

0.6953125 x 2 = 1.390625 ... 1
0.390625 x 2 = 0.78125 ... 0
0.78125 x 2 = 1.5625 ... 1
0.5625 x 2 = 1.125 ... 1
0.125 x 2 = 0.25 ... 0
0.25 x 2 = 0.5 ... 0
0.5 x 2 = 1 ... 1
The result is the integer digits arranged from left to right 1011001

Putting the calculated 000 111 sequence together gives the converted binary 1101010.10110011101010.10110011101010.1011001, which is expressed in scientific notation as 1.1010101011001∗261.1010101011001*2^61.1010101011001∗26. Now that the binary has been calculated, it needs to be stored in the computer. In Javascript, integers and decimals are not distinguished, and numbers are uniformly stored according to the requirements of double-precision floating-point numbers, which mainly include the following rules:

  • Use 8 bytes (64 bits) 8 bytes (64 bits) 8 bytes (64 bits) to store double-precision floating point numbers
  • Stores data represented by decimals in scientific notation
  • The first bit indicates the sign, and the last 111111 bits indicate the exponent. The exponent is calculated by the bit-filling operation, that is, directly add 102310231023 to the exponent bit.
  • The remaining 525252 digits represent the decimal point. The part exceeding 525252 digits is rounded down to 000 and rounded up to 111.

Since the 11 bits of the exponent do not include the sign bit, an exponent offset is introduced to achieve the effect of positive and negative exponents.

The diagram is as follows:

We put the converted binary numbers into memory according to the rules. First, 106.6953125106.6953125106.6953125 is a positive number, so the sign bit should be 111. 000 represents a positive sign, and 111 represents a negative sign (the picture should show 000, it’s a typo)

Binary 1.1010101011001∗261.1010101011001*2^61.1010101011001∗26 The exponent is 666 (the offset 1023 needs to be added here), which is converted to binary as 100000001011000000010110000000101. The exponent bit requires the two's complement to be placed, and the calculation rule of the two's complement is:

  • The complement of a positive number is itself
  • The complement of a negative number is based on its original code, with the sign bit unchanged, the rest of the bits are inverted, and finally +1. (That is, +1 on the basis of the one's complement)
[+1] = [00000001] Original = [00000001] Reverse [-1] = [10000001] Original = [11111110] Reverse

So the image index should be filled

The mantissa part can be directly filled in with the binary converted from the decimal

The numbers are finally stored in the computer in this form

why 0.1 + 0.2 !== 0.3?

After understanding the principle of digital storage, let's analyze why 0.1+0.2!==0.30.1 + 0.2 !== 0.30.1+0.2!==0.3

First, convert 0.10.10.1 0.20.20.2 0.30.30.3 into binary respectively

0.1 x 2 = 0.2 ... 0
0.2 x 2 = 0.4 ... 0
0.4 x 2 = 0.8 ... 0
0.8 x 2 = 1.6 ... 1
0.6 x 2 = 1.2 ... 1
0.2 x 2 = 0.4 ... 0
0.4 x 2 = 0.8 ... 0
0.8 x 2 = 1.6 ... 1
0.6 x 2 = 1.2 ... 1
The integer digits obtained are arranged from left to right 000110011...

0.1→0.00011(0011)∞

0.2 x 2 = 0.4 ... 0
0.4 x 2 = 0.8 ... 0
0.8 x 2 = 1.6 ... 1
0.6 x 2 = 1.2 ... 1
0.2 x 2 = 0.4 ... 0
0.4 x 2 = 0.8 ... 0
0.8 x 2 = 1.6 ... 1
0.6 x 2 = 1.2 ... 1
0.2 x 2 = 0.4 ... 0
The integer digits obtained are arranged from left to right 001100110...

0.2→0.00110(0110)∞

0.3 x 2 = 0.6 ... 0
0.6 x 2 = 1.2 ... 1
0.2 x 2 = 0.4 ... 0
0.4 x 2 = 0.8 ... 0
0.8 x 2 = 1.6 ... 1
0.6 x 2 = 1.2 ... 1
0.2 x 2 = 0.4 ... 0
0.4 x 2 = 0.8 ... 0
0.8 x 2 = 1.6 ... 1
The obtained integer bits are arranged from left to right 010011001...

0.3→0.01001(1001)∞

The scientific notation is uniformly expressed as

0.1→0.00011(0011)∞→1.(1001)∞∗2 −4

0.2→0.00110(0110)∞→1.(1001)∞∗2 −3

0.3→0.01001(1001)∞→1.(0011)∞∗2 −2

The double-precision floating point number is stored in the computer. The red at the end indicates that the binary exceeds the mantissa, which means that it needs to be rounded up.

After 64-bit double-precision storage, the binary representation is as follows
0.1→0−01111111011−(1001) 12 1010

0.2→0−01111111100−(1001) 12 1010

0.3→0−01111111101−(0011) 12 0011

At this time, 0.1+0.20.1 + 0.20.1+0.20.1+0.2 is not equal to 0.30.30.3

This is why number calculations in computers often bring some "surprises"!

Summarize

This is the end of this article about memory and variable storage in JS. For more relevant JS memory and variable storage content, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Detailed explanation of js variables, scope and memory
  • A brief talk about variables, scope and memory issues in JavaScript
  • JavaScript variables, scope, and memory
  • Variables, scope and memory issues in javascript
  • Example analysis of JavaScript variable scope and memory issues

<<:  Detailed explanation of common commands in MySQL 8.0+

>>:  Record a troubleshooting record of high CPU usage of Tomcat process

Recommend

MySQL database master-slave configuration tutorial under Windows

The detailed process of configuring the MySQL dat...

Simple steps to implement H5 WeChat public account authorization

Preface Yesterday, there was a project that requi...

5 ways to achieve the diagonal header effect in the table

Everyone must be familiar with table. We often en...

What to do after installing Ubuntu 20.04 (beginner's guide)

Ubuntu 20.04 has been released, bringing many new...

Summary of using the reduce() method in JS

Table of contents 1. Grammar 2. Examples 3. Other...

MySQL 8.0 New Features - Introduction to the Use of Management Port

Table of contents Preface Connection Management A...

A brief discussion on Linux virtual memory

Table of contents origin Virtual Memory Paging an...

The submit event of the form does not respond

1. Problem description <br />When JS is use...

Summary of MySQL logical backup and recovery testing

Table of contents 1. What kind of backup is a dat...

JavaScript implementation of verification code case

This article shares the specific code for JavaScr...

Using better-scroll component in Vue to realize horizontal scrolling function

About Recently, in the process of learning Vue, I...

How to implement remote access control in Centos 7.4

1. SSH remote management SSH is a secure channel ...

Example of implementing login effect with vue ElementUI's from form

Table of contents 1. Build basic styles through E...

How to implement form validation in Vue

1. Installation and use First, install it in your...

Summary of JavaScript's setTimeout() usage

Table of contents 1. Introduction 2. The differen...