成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

數(shù)字在JavaScript中是如何編譯的

Moxmi / 1635人閱讀

摘要:數(shù)字數(shù)字都是浮點數(shù),按照標準進行存儲。因此,只有偶數(shù)可以在范圍內(nèi)表示。但只有超過指數(shù)的上限才稱為中的溢出。結論在這篇博文中,我們研究了如何將其浮點數(shù)轉換為位。

JavaScript中的所有數(shù)字都是浮點數(shù)。這篇博客文章解釋了這些浮點數(shù)如何在64位二進制內(nèi)部表示。由于特別考慮,本文中的數(shù)字將用整數(shù)表示,以便在閱讀本文后,您將了解在以下交互中會發(fā)生什么:

(譯者注:浮點數(shù)并不一定等于小數(shù),定點數(shù)也并不一定就是整數(shù)。所謂浮點數(shù)就是小數(shù)點在邏輯上是不固定的,而定點數(shù)只能表示小數(shù)點固定的數(shù)值,具用浮點數(shù)或定點數(shù)表示某哪一種數(shù)要看用戶賦予了這個數(shù)的意義是什么。)

    > 9007199254740992 + 1
    9007199254740992

    > 9007199254740992 + 2
    9007199254740994
JavaScript數(shù)字

JavaScript數(shù)字都是浮點數(shù),按照IEEE 754 standard標準進行存儲。該標準有幾種格式。 JavaScript使用binary64或雙精度。正如前面的名稱所表示的,數(shù)字以二進制格式存儲在64位中。這些比特分配如下:分數(shù)占據(jù)比特0到51,指數(shù)占據(jù)比特52到62,符號占用比特63。

| sign (1 bit)
63

| exponent (11 bit)

62

52

| fraction (52 bit)

51

|

這些組件的工作原理如下:如果符號位為0,則數(shù)字為正數(shù),否則為負數(shù)。粗略地說,分數(shù)包含數(shù)字的值,而指數(shù)表示該點的位置。在下面,我們經(jīng)常使用二進制數(shù)字,這在浮點數(shù)方面有點不尋常。二進制數(shù)字將以前綴??百分比符號(%)標記。雖然JavaScript數(shù)字以二進制格式存儲,但默認輸出為十進制[1]。在示例中,我們通常會使用該默認值。

分數(shù)

以下是表示非負浮點數(shù)的一種方法:有效數(shù)(或尾數(shù))包含數(shù)字,作為自然數(shù),指數(shù)指定點的左邊(負指數(shù))或右邊(正指數(shù))的點數(shù)應該轉移。 JavaScript數(shù)字使用有理數(shù)作為有效數(shù):1._f_其中_f_是52位小數(shù)。忽略符號,數(shù)字是有效數(shù)字乘以2_p_,其中_p_是指數(shù)(在稍后將解釋的轉換之后)。

比如:

| f = %101, p = 2 | Number: %1.101 × 22 = %110.1 |
| f = %101, p = ?2 | Number: %1.101 × 2?2 = %0.01101 |
| f = 0, p = 0 | Number: %1.0 × 20 = %1 |

表示整數(shù)

整數(shù)的編碼有多少位?有效數(shù)字有53個數(shù)字,一個在點之前,52個點。用_p_ = 52,我們有一個53位的自然數(shù)。唯一的問題是最高位始終為1.也就是說,我們沒有全部位可供我們隨意使用。分兩步去除這個限制。首先,如果你需要一個最高位為0的53位數(shù),然后是1,那么你設置_p_ = 51.分數(shù)的最低位成為該點之后的第一個數(shù)字,整數(shù)為0。依此類推,直到你處于編碼數(shù)字1的_p_ = 0和_f_ = 0。

| | 52 | 51 | 50 | ... | 1 | 0 | (bits) |
| p=52 | 1 | f51 | f50 | ... | f1 | f0 | |
| p=51 | 0 | 1 | f51 | ... | f2 | f1 | f0=0 |
| | ... |
| p=0 | 0 | 0 | 0 | ... | 0 | 1 | f51=0, etc. |

其次,對于全部53位,我們?nèi)匀恍枰硎玖?。如何做到這一點在下一節(jié)中解釋。請注意,由于符號是多帶帶存儲的,因此整數(shù)的幅度(絕對值)為53位。

指數(shù)

指數(shù)的長度是11位,這意味著它的最低值是0,最高值是2047(211-1)。為了支持負指數(shù),使用所謂的偏移二進制編碼:1023是零,所有較低數(shù)字都是負數(shù),所有較高數(shù)字都是正數(shù)。這意味著你從指數(shù)中減去1023將其轉換為正常數(shù)字。因此,我們以前使用的變量_p_等于_e_-1023,并且有效數(shù)字乘以2_e_-1023。

偏移量二進制編碼中的一些數(shù)字:

    %00000000000     0  →  ?1023  (lowest number)
    %01111111111  1023  →      0
    %11111111111  2047  →   1024  (highest number)
                         
    %10000000000  1024  →      1
    %01111111110  1022  →     ?1 

你倒置它的位并減1就能將一個數(shù)變?yōu)樨摂?shù)了。

特殊的指數(shù)

兩個指數(shù)值是保留的:最低的一個(0)和最高的一個(2047)。 2047的指數(shù)用于無窮大和NaN(非數(shù)字)值[2]。 IEEE 754標準有許多NaN值,但JavaScript都將它們表示為單個值NaN。指數(shù)0用于兩種能力。首先,如果分數(shù)也是0,那么整數(shù)就是0.由于符號是分開存儲的,我們同時具有-0和+0(詳見[3])。

其次,0的指數(shù)也用于表示非常小的數(shù)字(接近零)。然后該分數(shù)必須是非零的,如果是正數(shù),則通過計算該數(shù)字

%0._f_ × 2?1022

這種表示是_非規(guī)范化_。先前討論的表示被稱為_標準化_??梢砸砸?guī)范化方式表示的最小的正數(shù)(非零)數(shù)是

%1.0 × 2?1022

最大的非正規(guī)化數(shù)字是

%0.1 × 2?1022

因此,在標準化和非標準化數(shù)字之間切換時沒有漏洞。

總結:指數(shù)

| (?1)_s_ × %1._f_ × 2_e_?1023 | normalized, 0 < e < 2047 |
| (?1)_s_ × %0._f_ × 2_e_?1022 | denormalized, e = 0, f > 0 |
| (?1)_s_ × 0 | e = 0, f = 0 |
| NaN | e = 2047, f > 0 |
| (?1)_s_ × ∞ (infinity) | e = 2047, f = 0 |

用_p_ = e - 1023,指數(shù)的范圍是

?1023 < p < 1024
小數(shù)部分

并非所有小數(shù)都可以用JavaScript精確表示,如下所示:

    > 0.1 + 0.2
    0.30000000000000004

小數(shù)部分0.1和0.2都不能精確地表示為二進制浮點數(shù)。但是,與實際值的偏差通常太小而不能顯示。加法導致偏差變得可見。另一個例子:

    > 0.1 + 1 - 1
    0.10000000000000009

表示0.1對于表示分數(shù)110來說是個挑戰(zhàn)。困難的部分是分母10,其分母的因子分解是2×5.指數(shù)只允許你用2的冪除整數(shù),所以沒有辦法得到5英寸。比較:13不能精確地表示為小數(shù)部分。它近似于0.333333 ...

相反,將二進制小數(shù)表示為小數(shù)部分總是可能的,您只需要收集足夠多的二進制數(shù)(其中每十個都有一個)。例如:

%0.001 = 18 = 12 × 2 × 2 = 5 × 5 × 5(2×5) × (2×5) × (2×5) = 12510 × 10 × 10 = 0.125
比較小數(shù)部分

因此,當您使用具有小數(shù)值的小數(shù)輸入時,不應直接比較它們。相反,考慮舍入誤差的上限。這樣的上限稱為machine epsilon。雙精度的標準epsilon值是2-53。

    var epsEqu = function () { // IIFE, keeps EPSILON private
        var EPSILON = Math.pow(2, -53);
return function epsEqu(x, y) {
            return Math.abs(x - y) < EPSILON;
};
}();

上述功能可確保在正常比較不充分的情況下獲得正確結果:

    > 0.1 + 0.2 === 0.3
    false
    > epsEqu(0.1+0.2, 0.3)
    true
最大整數(shù)

如果有人說“_x_是最大整數(shù)”,這意味著什么?這意味著可以表示范圍為0≤_n_≤_x_的每個整數(shù)_n_,并且對于大于_x_的任何整數(shù)都不能成立。 253符合該法案。以前的所有數(shù)字都可以表示:

    > Math.pow(2, 53)
    9007199254740992
    > Math.pow(2, 53) - 1
    9007199254740991
    > Math.pow(2, 53) - 2
    9007199254740990

但是下一個整數(shù)不能被表示:

    > Math.pow(2, 53) + 1
    9007199254740992

253的一些方面是上限可能是令人驚訝的。我們將通過一系列問題來看待他們。要記住的一件事是整數(shù)范圍的高端限制資源是分數(shù);指數(shù)仍有增長空間。

為什么是53位?您有53位可用于幅度(不包括符號),但分數(shù)只包含52位。這怎么可能?正如您在上面看到的那樣,指數(shù)提供了第53位:它移動了分數(shù),因此除零之外的所有53位數(shù)都可以表示,并且它有一個特殊值來表示零(連同零的一部分)。

為什么最高的整數(shù)不是253-1?通常,_x_位表示最低的數(shù)字是0,最高的數(shù)字是2_x_-1。例如,最高的8位數(shù)字是255.在JavaScript中,最高分數(shù)確實用于數(shù)字253-1,但可以表示253,這要歸功于指數(shù)的幫助 - 它僅僅是一個分數(shù)_f_ = 0并且指數(shù)_p_ = 53(轉換后):

%1._f_ × 2_p_ = %1.0 × 253 = 253

為什么高于253的數(shù)字可以代表?

示例:

    > Math.pow(2, 53)
    9007199254740992
    > Math.pow(2, 53) + 1  // not OK
    9007199254740992
    > Math.pow(2, 53) + 2  // OK
    9007199254740994

    > Math.pow(2, 53) * 2  // OK
    18014398509481984

253×2的作品,因為指數(shù)可以使用。每乘以2只是將指數(shù)遞增1并且不影響分數(shù)。因此,就最大分數(shù)而言,乘以2的冪不是問題。為了明白為什么可以加2到253,而不是1,我們用前面的表擴展53和54的附加位,以及_p_ = 53和_p_ = 54的行:

| | 54 | 53 | 52 | 51 | 50 | ... | 2 | 1 | 0 | (bits) |
| p=54 | 1 | f51 | f50 | f49 | f48 | ... | f0 | 0 | 0 | |
| p=53 | | 1 | f51 | f50 | f49 | ... | f1 | f0 | 0 | |
| p=52 | | | 1 | f51 | f50 | ... | f2 | f1 | f0 | |

查看行(_p_ = 53),應該很明顯,JavaScript數(shù)字可以將位53設置為1.但是,因為分數(shù)_f_只有52位,所以位0必須為零。因此,只有偶數(shù)_x_可以在253≤_x_ <254范圍內(nèi)表示。在行(_p_ = 54)中,該間距增加到4的倍數(shù),范圍在254≤_x_ <255:

    > Math.pow(2, 54)
    18014398509481984
    > Math.pow(2, 54) + 1
    18014398509481984
    > Math.pow(2, 54) + 2
    18014398509481984
    > Math.pow(2, 54) + 3
    18014398509481988
    > Math.pow(2, 54) + 4
    18014398509481988

等等...

IEEE 754例外

IEEE 754標準描述了五個例外,其中一個不能計算精確的值:

無效:執(zhí)行了無效操作。例如,計算負數(shù)的平方根。返回NaN [2]。

    > Math.sqrt(-1)
    NaN

除以零:返回正負無窮[2]。

    > 3 / 0
    Infinity
    > -5 / 0
    -Infinity

溢出:結果太大而無法表示。這意味著指數(shù)太高(_p_≥1024)。根據(jù)符號,有正面和負面溢出。返回正負無窮。

    > Math.pow(2, 2048)
    Infinity
    > -Math.pow(2, 2048)
    -Infinity

下溢:結果太接近零來表示。這意味著指數(shù)太低(_p_≤-1023)。返回非規(guī)格化的值或零。

    > Math.pow(2, -2048)
    0

不精確:操作產(chǎn)生了不準確的結果 - 要保留的分數(shù)有太多有效數(shù)字。返回一個舍入結果。

    > 0.1 + 0.2
    0.30000000000000004
    
    > 9007199254740992 + 1
    9007199254740992

#3和#4是關于指數(shù),#5是關于分數(shù)。 #3和#5之間的區(qū)別非常微妙:在第五個例子中,我們超過了分數(shù)的上限(這將是整數(shù)計算中的溢出)。但只有超過指數(shù)的上限才稱為IEEE 754中的溢出。

結論

在這篇博文中,我們研究了JavaScript如何將其浮點數(shù)轉換為64位。它根據(jù)IEEE 754標準中的雙精度進行。由于數(shù)字的顯示方式,人們往往會忘記JavaScript不能精確地表示分母的因子分解包含2以外的數(shù)字的小數(shù)部分。例如,可以表示0.5(12),而0.6(35)不能表示。人們也往往忘記了三個組件符號,指數(shù),一個數(shù)字的小數(shù)部分一起工作來表示一個整數(shù)。但是,當Math.pow(2,53)+ 2可以表示時,會遇到這種情況,但Math.pow(2,53)+ 1不能。

網(wǎng)頁“IEEE-754 Analysis”允許您輸入一個數(shù)字并查看其內(nèi)部表示。

來源和相關閱讀

這篇文章的來源:

“IEEE Standard 754 Floating-Point” by Steve Hollasch.

“Data Types and Scaling (Fixed-Point Blockset)” in the MATLAB documentation.

“IEEE 754-2008” on Wikipedia.

This post is part of a series on JavaScript numbers, which includes:

Displaying numbers in JavaScript

NaN and Infinity in JavaScript

JavaScript’s two zeros

文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://systransis.cn/yun/95003.html

相關文章

  • C語言進階第一問:數(shù)據(jù)內(nèi)存中是如何存儲?(手把手帶你深度剖析數(shù)據(jù)內(nèi)卒中存儲,超全解析,碼住不

    摘要:在符號位中,表示正,表示負。我們知道對于整型來說,內(nèi)存中存放的是該數(shù)的補碼。在計算機系統(tǒng)中,數(shù)值一律用補碼來表示和存儲。表示有效數(shù)字,。規(guī)定對于位的浮點數(shù),最高的位是 ...

    ghnor 評論0 收藏0
  • 悄悄掀起 WebAssembly 神秘面紗

    摘要:在拿到這塊內(nèi)存后,是擁有完全操作的權利的。后面定義了一個函數(shù),并導出為函數(shù)。首先,使用在棧內(nèi)壓入一個位整型常數(shù),然后使用在棧內(nèi)壓入一個位整型常數(shù),之后調用指令,這個指 前端開發(fā)人員想必對現(xiàn)代瀏覽器都已經(jīng)非常熟悉了吧?HTML5,CSS4,JavaScript ES6,這些已經(jīng)在現(xiàn)代瀏覽器中慢慢普及的技術為前端開發(fā)帶來了極大的便利。得益于 JIT(Just-in-time)技術,Java...

    qc1iu 評論0 收藏0
  • TypeScript Start: 什么是 TypeScript

    摘要:最近開始用來寫項目,寫起來還是挺順暢的。和在類型上的區(qū)別被稱作是一種動態(tài)腳本語言,其中有一個被瘋狂詬病的特性缺乏靜態(tài)強類型。當然,這是可以的,此時變量的類型已經(jīng)發(fā)生改變字符串數(shù)字。 最近開始用 TypeScript 來寫項目,寫起來還是挺順暢的。其實學習 TypeScript,看它的官方文檔就夠了,剩下就是 coding 了。我這里主要是我在 TypeScript 學習過程中記錄的一些...

    JeOam 評論0 收藏0
  • What's New in JavaScript

    摘要:在和中都保留了數(shù)組的強引用,所以在中簡單的清除變量內(nèi)存并沒有得到釋放,因為還存在引用計數(shù)。而在中,它的鍵是弱引用,不計入引用計數(shù)中,所以當被清除之后,數(shù)組會因為引用計數(shù)為而被回收掉。其實我們主要注意的引用是不計引用計數(shù)的,就好理解了。 showImg(https://segmentfault.com/img/remote/1460000019147368?w=900&h=383); 前...

    cgh1999520 評論0 收藏0
  • [譯文] JavaScript工作原理:V8引擎內(nèi)部+5條優(yōu)化代碼竅門

    摘要:本文將會深入分析的引擎的內(nèi)部實現(xiàn)。該引擎使用在谷歌瀏覽器內(nèi)部。同其他現(xiàn)代引擎如或所做的一樣,通過實現(xiàn)即時編譯器在執(zhí)行時將代碼編譯成機器代碼。這可使正常執(zhí)行期間只發(fā)生相當短的暫停。 原文 How JavaScript works: inside the V8 engine + 5 tips on how to write optimized code 幾周前我們開始了一個系列博文旨在深入...

    dreamans 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<