JS 中无论 整数 或是 小数 都是 Number 类型

  1. typeof 0.1 // number
  2. typeof 1 // number

前置

十进制转二进制

10 / 2 = 5 … 0
5 / 2 = 2 … 1
2 / 2 = 1 … 0
1 / 2 = 0 … 1
然后由把余数由下往上,得出二进制

十进制 二进制
10 1010

科学记数法

在储存时,使用科学记数法来记存在

15000 -> 1.5 x 10^4
1200 -> 1.2 x 10^3

对于二进制,科学记数法的第一位整数要为 1,所以对于小数会出现负数
1010 -> 1.01 x 2^3
0.00101 -> 1.01 x 2^-3

数字存储方式

使用 IEEE 754 规范,以 64位 双精度浮点数来存储
image.png
最高位为符号位

  • 0 正数 1负数

往后 11 位为指数位
最后的 52 位 是有效数,即小数点后的数字

整数

以十进制 10 来说,
转为二进制是 1010,
以科学计数法是 1.01 x 2^3

符号位 正数是 0;
指数位 2^3 指数位就存 3 +(2^11 -1)= 3 + 1024 = 1026,1026 转为二进制 10000000010;
有效数 .01 -> .0100000000000000000000000000000000000000000000000000共 52位 :::info 符号位 指数位 有效数
0 10000000010 0100000000000000000000000000000000000000000000000000 ::: 所以最终储存结果是
0100000000100100000000000000000000000000000000000000000000000000

小数

以十进制 0.1 来说,
整数部分是 0

对于小数是以
0.1 x 2 = 0.2
0.2 x 2 = 0.4
0.4 x 2 = 0.8
0.8 x 2 = 1.6 当积大于 1 时,再拿其小数部分继续乘 2
0.6 x 2 = 1.2

0.2 x 2 = 0.4 后面开始不断地重复
0.2 x 2 = 0.8
0.8 x 2 = 1.6
0.6 x 2 = 1.2

0.2 x 2 = 0.4
0.2 x 2 = 0.8
0.8 x 2 = 1.6
0.6 x 2 = 1.2

0.2 x 2 = 0.4
0.2 x 2 = 0.8
0.8 x 2 = 1.6
0.6 x 2 = 1.2

0.2 x 2 = 0.4
0.2 x 2 = 0.8
0.8 x 2 = 1.6
0.6 x 2 = 1.2

会不断地重复,然后拿其积的整数部分
0.000110011001100110011
转为科学记数法
1.1001100110011… x 2^-4

符号位 正数是 0;
指数位 2^-4 指数位就存 -4 + 1023 = 1019,1019 转为二进制 1111111011,只有 10 位往前补 0,成为 11位;
有效数 . 10011001100110011001100110011001100110011001100110011… 截取 52 位,看第 53 位作 零舍一入 (1 时向前进一位,0则不变)
所以现在 53 位是 1,1001100110011001100110011001100110011001100110011010 :::info 符号位 指数位 有效数
0 01111111011 1001100110011001100110011001100110011001100110011010 ::: 所以最终储存结果是
0011111110111001100110011001100110011001100110011001100110011001

因为零舍一入
0.1 在计算机存储的时候会比 0.1 大一点
同理 0.2 在计算机存储的时候也会比 0.2 大一点

0.1 + 0.2 == 0.3 ?