【JS迷你书】Number类型二进制表示法

问你一个问题:JSNumber 类型数据总共有多少个?html

这有答案吗?git

《Ecma-262 Edition 5.1》给出的答案是:18437736874454810627,即 github

那么,具体是怎么算出来的??app

本文主要解决这个问题。less

规范上说,Number 类型使用的是《 IEEE二进制浮点数算术标准(IEEE 754)》的双精度 64 位格式。koa

其核心问题:是怎么用 64 个比特位,来表示一个具体浮点类型数值?jsp

《IEEE 754.pdf》把这 64 位比特分红 3 部分: ui

其中,s 表示符号位,占 1 比特;e 表示指数位,占 11 比特;f 表示分数位,占 52 比特。spa

规范里详细地给出了各类状况所对应的值:3d

上述分类是符合 MECE 原则的,不重复且不遗漏。

其中 e 占 11 位,所以该部分能表示的数字范围是 0 至 2047,即,0 至。分类首先标准就是看 e 是否位于边界。

前两条是指当 e 部分都填充二进制 1 时,即当指数部分为最大值时,表示 NaN 和正负 Infinity 这两种状况。

具体来讲,第一种,当小数部分同时不为零时,此时表示 NaNJS 中的字面量 NaN,正是对应这种状况,另外要求 NaN 始终不能等于自身。

第二种,而当 f 部分为 0 时,根据符号位的正负,来表示相应的正负无穷。

第三条是指当 e 在介于最小值和最大值之间的情形。此时被称为规范化数字,有别于下面的第四条。这里值的肯定方式是 。此时要注意 指的是二进制小数。

举个例子,假设某个数字的 64 位比特表示以下: 1|10000000001|110000...,此时 s 是 1, e,即 1025。那么该数据对应的值 v 是: 而二进制小数 其值是,即 1.75。所以该表示是 -7。

第四条是指非规范化数字情形。此时数字已经很是小了。注意这里是二进制小数是 不一样于第三条里的 。最后一类是正负 0 的情形。

咱们已经把规范过了一遍,如今,咱们来算算开头的问题:Number 类型共有多少个值?

从上述分类中能够看出:后三类是正常值,前两类总共有 种可能(排列组合原理,s 部分为 2047,所以相应的只有一种可能),这么多种可能,却在 JS 中只表示 NaN+Infinity-Infinity 这 3 个值。所以总数

至此,本文接近尾声了。

最后提醒一下,阅读《Ecma-262 Edition 5.1》8.5节不要犯迷糊:

The 18437736874454810622 (that is, ) finite nonzero values are of two kinds: 18428729675200069632 (that is, )of them are normalised, having the form

where s is +1 or −1, m is a positive integer less than but not less than , and e is an integer ranging from −1074 to 971, inclusive.
The remaining 9007199254740990 (that is, ) values are denormalised, having the form

where s is +1 or −1, m is a positive integer less than , and e is −1074.

其中提到了 e 是从 -1070 到 971,这两个数字怎么来的?其实它与《IEEE 754.pdf》说的是同一回事,好比规范化情形,只是从指数部分里拿出了 放到了 m 里面。 m 等价于

本文完。

《JavaScript 迷你书》传送门,全面夯实基础

掘金收藏

相关文章
相关标签/搜索