Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JavaScript Numbers #78

Open
hushicai opened this issue Sep 13, 2019 · 5 comments
Open

JavaScript Numbers #78

hushicai opened this issue Sep 13, 2019 · 5 comments

Comments

@hushicai
Copy link
Owner

hushicai commented Sep 13, 2019

JavaScript浮点数相关资料。

@hushicai
Copy link
Owner Author

hushicai commented Sep 13, 2019

双精度浮点数存储格式:

image

sign(符号): 用来表示正负号

exponent(指数): 用来表示次方数

mantissa(尾数): 用来表示精确度

符号

0代表数值为正,1代表数值为负。

指数

双精度浮点数在存储指数位时,会加上一个固定的偏移值。

IEEE 754标准规定该固定值为2^(e-1) - 1,其中e为指数位的长度,即2^(11 - 1) - 1 = 1023

尾数

尾数一般要求规格化,把尾数处理到(0, 2)区间内,这样可以省去小数点前的1

例子

例如0.1 转成二进制:

0.1.toString(2)
// "0.0001100110011001100110011001100110011001100110011001101"

科学计数法:

1.100110011001100... x 2^-4

我们自己算出来的是-4,但实际计算机存储时,会加上偏移值,即E = -4 + 1023 = 1019

Number(1019).toString(2)
// "1111111011"

M 舍去首位的1,得到 100110011001100...,最终就是:

image

references

@hushicai
Copy link
Owner Author

@hushicai
Copy link
Owner Author

@hushicai
Copy link
Owner Author

@hushicai
Copy link
Owner Author

hushicai commented Sep 18, 2019

安全整数

(-2^53, 2^53)范围内,所有的整数都有唯一的浮点数表示,这就是所谓的安全整数。

2^53

二进制表示:

1000000...000 (一个1,53个0)

科学计数法:

1.000000...000 x 2^53(小数点后53个0)

其实就相当于小数点往左移动了53位。

双精度表示法:

符号位:0,指数:53,尾数:1.000000...000 (小数点后52个0)

由于双精度浮点数的尾数位数限制,最后一位0丢失了,精度丢失了,所以不认为是一个安全整数

2^53 - 1

二进制表示:

11111111111111111111111111111111111111111111111111111(53个1)

科学计数法:

1.111111...111 x 2^52(小数点后52个1)

双精度表示法:

符号位:0,指数:52,尾数:1.111111....111 (小数点后52个1)

2^53 - 2

二进制表示:

11111111111111111111111111111111111111111111111111110(52个1,一个0)

科学计数法:

1.111111...1110 x 2^52(小数点后51个1,一个0)

双精度表示法:

符号位:0,指数:52,尾数:1.111111....110 (小数点后51个1,一个0)

以此类推,以上范围内的整数都可以由一个唯一的浮点数表示。

如果超出了以上范围,存储就可能不唯一了,例如2^53 + 1

2^53 + 1

二进制表示:

1000000...001 (一个1,52个0,一个1)

科学计数法:

1.000000...001 x 2^53(小数点后52个0,一个1)

双精度表示法:

符号位:0,指数:53,尾数:1.000000...000 (小数点后52个0)

由于双精度浮点数的尾数位数限制,最后一位1要丢掉。

所以实际上2^53 + 12^53的存储是一样的:

Math.pow(2, 53) === Math.pow(2, 53) + 1 // true

整数和浮点数不再一一对应,所以就不安全了。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant