摘要:例如指數實際值為,在單精度浮點數中的指數域編碼值為,即采用指數的實際值加上固定的偏移值的辦法表示浮點數的指數,好處是可以用長度為個比特的無符號整數來表示所有的指數取值,這使得兩個浮點數的指數大小的比較更為容易。
自己整理、設計的,轉載請注明原帖。先從這個demo看起:http://alvarto.github.io/Visu...
數軸 說明關于Number.MAX_VALUE和Number.MIN_VALUE:這個結果為了好看被我四舍五入了……
關于±0:紫云飛:JavaScript中的兩個0
關于數組的最大索引:紫云飛:JavaScript:數組能越界?
關于JavaScript可以精確表示到個位的最大整數:阮一峰:JavaScript數值
關于Number表示的內存模型參考國際標準IEEE 754,我畫了一張圖幫助理解:
注,這里的字符是從左到右排的,和wiki之類的資料順序相反。wiki資料考慮的是比較的順序(符號-指數位-有效數字),而我這里考慮到的是閱讀順序(從0到63位,從左到右)。
中間的指數位是如何同時表示正負指數值的呢,和“符號位+有效數字位”的常規表示方法不同,指數是使用偏移法來做的:
IEEE 754:指數偏移值
指數偏移值(exponent bias),是指浮點數表示法中的指數域的編碼值為指數的實際值加上某個固定的值,IEEE 754標準規定該固定值為2^(e-1)-1,其中的e為存儲指數的比特的長度。
以單精度浮點數為例,它的指數域是8個比特,固定偏移值是28-1 - 1 = 128?1 = 127.單精度浮點數的指數部分實際取值是從128到-127。例如指數實際值為1710,在單精度浮點數中的指數域編碼值為14410,即14410 = 1710 + 12710.
采用指數的實際值加上固定的偏移值的辦法表示浮點數的指數,好處是可以用長度為e個比特的無符號整數來表示所有的指數取值,這使得兩個浮點數的指數大小的比較更為容易。
因此,在JavaScript里面的指數位,是從1-2^(11-1),也就是從-1023開始,表示了(-1023,1024)這個區間。
實際指數值 | 存儲的指數值 |
-1022 | 1 |
0 | 1023 |
1023 | 2046 |
Number保留了指數值0和2047用于表示一些特殊的值。總的表示表格如下:
X | Y | 表示的值 |
=0 | =0 | ±0 |
≠0 | =2047 | NaN |
=0 | =2047 | ±Infinity |
≠0 | =0 | 反規格化值(Denormalized):f(0.x , 1 , z) |
∈(0,2047) | 規格化值(Normalized):f(1.x , y , z) | |
f(i,j,k) = (-1)k · 2-1023+j · i |
前52位能表示的最大值是下面這個(下面是52位+1位默認的1):
parseInt("11111111111111111111111111111111111111111111111111111",2) -> 9007199254740991 //即2^53-1
而下一個值是:
parseInt("100000000000000000000000000000000000000000000000000000",2) -> 9007199254740992 //即2^53
根據內存模型,畫一張圖就可以知道:
從第2^53位開始,第一個進制被舍棄,這個時候,2^53+1==2^53,每兩個值都會有一個值出現這種不精確的情形。再過N個值,會出現每4個值里面都有3個值不精確;再過M個值,會出現每2^K個值里有2^K-1個值不精確;以此類推……(小題目:這個N值是多少?)
最大可表示的正數驗證:
Number.MAX_VALUE.toString(2) -> "1111111111111111111111111111111111111111111111111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" var a = Number.MAX_VALUE.toString(2).split("") , b = [ a.filter(function(i){return i==0}).length , a.filter(function(i){return i==1}).length ] ; b -> [971, 53] Number.MAX_VALUE === (Math.pow(2,53)-1)*Math.pow(2,971) -> true
QED
最小可表示的正數還記得前面的表格嗎:
X | Y | 表示的值 |
≠0 | =0 | 反規格化值(Denormalized):f(0.x , 1 , z) |
∈(0,2047) | 規格化值(Normalized):f(1.x , y , z) | |
f(i,j,k) = (-1)k · 2-1023+j · i |
非規格化值是這樣表示的:
最小正數的內存模型
驗證:
Number.MIN_VALUE.toString(2) -> "0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001" var a = Number.MIN_VALUE.toString(2).split(""); a.filter(function(i){return i==0}).length - 1 -> 1073 Number.MIN_VALUE === Math.pow(2,-1074) -> true參考資料
除了IEEE 754的維基頁面,還有這篇文章,解釋的非常清晰:"How numbers are encoded in JavaScript"
最后再推一次:輸入表達式,返回對應Number值的內存模型的DEMO
http://alvarto.github.io/Visu...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/87479.html
摘要:問題引入接觸過事件循環的同學大都會糾結一個點,就是在中和執行順序的隨機性。當隊列被執行完,或者執行的回調數量達到上限后,事件循環才會進入下一個階段。嵌套的在下一個事件循環的階段執行回調輸出嵌套的。 問題引入 接觸過事件循環的同學大都會糾結一個點,就是在Node中setTimeout和setImmediate執行順序的隨機性。 比如說下面這段代碼: setTimeout(() => { ...
摘要:將大的先放在后面,再下一次可以把相同大的放在上一次的之前,順序改變。 之前介紹的排序算法: 【算法】插入排序——希爾排序+直接插入排序_Rinne’s blog-C...
摘要:實際上這個情形中存在冪定律實際上絕大多數的計算機算法的運行時間滿足冪定律。基于研究得知,原則上我們能夠獲得算法,程序或者操作的性能的精確數學模型。 前言 上一篇:并查集下一篇:棧和隊列 在算法性能上我們常常面臨的挑戰是我們的程序能否求解實際中的大型輸入:--為什么程序運行的慢?--為什么程序耗盡了內存? 沒有理解算法的性能特征會導致客戶端的性能很差,為了避免這種情況的出線,需要具備算法...
我們在學習javascript時,經常會聽到萬物皆對象,但是呢,其實萬物皆對象的對象也有區別。分為普通對象和函數對象。1.對象分為函數對象和普通對象? ??通過new Function()創建的對象都是函數對象,其他的都是普通對象。showImg(https://segmentfault.com/img/bVbtWre?w=526&h=252); 2.構造函數而提到new關鍵字,我們不得不提到構造...
閱讀 1876·2019-08-29 16:44
閱讀 2179·2019-08-29 16:30
閱讀 788·2019-08-29 15:12
閱讀 3534·2019-08-26 10:48
閱讀 2664·2019-08-23 18:33
閱讀 3785·2019-08-23 17:01
閱讀 1947·2019-08-23 15:54
閱讀 1310·2019-08-23 15:05