Number 存储和计JS 所能表达的最大最小值计算方法



JS 中最大的数计算方法
- 指数位应该是 11 位 1, 存储指数为 2 ^ 11 - 1 = 2047, 其中最后一位代表 Infinity, 所以实际指数为 2047 - 1023 - 1 = 1023
- 当指数位不为最小的情况下, 精度位前面是 1
- 精度位应该是 52 位 1, 最小精度为 2 ^ 52
- 所以最大数的计算应为, 2 ^ 1024 - 2 ^ 52, 因为 2 ^ 1024 已经是 Infinity 了, 所以我们需要换种计算方法, 即为 2 ^1023 - 2 ^ 52 + 2 ^ 1023
JavaScript
// JS最大数
Math.pow(2, 1023) - Math.pow(2, 1023 - 52) + Math.pow(2, 1023);
> 1.7976931348623157e308
// JS最小数改变符号即可
> -1.7976931348623157e308
JS 中最小正小数计算方法
- 指数位应该是 11 位 0, 存储指数为 0, 实际指数位为 0 - 1023 = -1023
- 当指数位最小的情况下, 精度位前面是 0
- 精度位应该是 51 位 0 和 1 位 1, 最小精度为 2 ^ 52
- 所以最小正小数数的计算应为, 2 ^ (-52 - 1022)
JavaScript
// JS最小正小数
Math.pow(2, -52 - 1022);
> 5e-324
// JS最大负小数改变符号即可
> -5e-324
JS 中的精确(安全)数字
这里我们只讨论精确整型, 而不讨论精确浮点数
最大精确(安全)整型
最大的精确的整形数字应该的指数位应该是0, 然后精度位应该是 52 位 1, 加上最前面的一位 1, 所以应为 2 ^ 53 - 1
JavaScript
// JS最小安全整型为 +0 和 -0
> +0
> -0
// JS最大安全整型
Math.pow(2, 53) - 1;
> 9007199254740991
为什么不讨论精确(安全)浮点数
只要是数字的有效位超过 52 位, 都不是精确数字, 在二进制转换或计算中都有可能丢失精度. (所以所有二进制循环小数都不是精确数字)
Reference
该死的 IEEE-754 浮点数,说「约」就「约」,你的底线呢?以 JS 的名义来好好查查你
IEEE 754 表示:你尽管抓狂、骂娘,但你能完全避开我,算我输。 首先我们还是来看几个简单的问题,能说出每一个问题的 细节 的话就可以跳过了,而如果只能泛泛说一句"因为IEEE754浮点数精度问题",那么下文还是值得一看。 第一个问题是知名的 0.
https://juejin.cn/post/6844903474480709640
IEEE754 浮点数格式 与 Javascript number 的特性
Javascript 作为一门动态语言,其数字类型只有 number 一种。 nubmer 类型使用的就是 IEEE754 标准中的 双精度浮点数 。Javascript 数字的许多特性都依赖于此标准,例如令人费解的 0.
https://segmentfault.com/a/1190000008268668

Discussion
留言与讨论
想法、补充和不同意见都欢迎。