【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 迷你書》傳送門,全面夯實基礎

掘金收藏

相關文章
相關標籤/搜索