探祕 JavaScript 世界的神祕數字 1.7976931348623157e+308

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"1.7976931348623157e+308","attrs":{}}],"attrs":{}},{"type":"text","text":",這個神祕數字是 JavaScript 能夠表示的最大數字。今天我們從這個神祕數字出發,從 ","attrs":{}},{"type":"link","attrs":{"href":"https://en.wikipedia.org/wiki/IEEE_754","title":"","type":null},"content":[{"type":"text","text":"IEEE 754","attrs":{}}]},{"type":"text","text":" 標準推導這些神祕數字是如何計算的。今天出現的神祕數字有 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"1.7976931348623157e+308","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"5e-324","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"9007199254740991","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"2.220446049250313e-16","attrs":{}}],"attrs":{}},{"type":"text","text":" 和 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"0.30000000000000004","attrs":{}}],"attrs":{}},{"type":"text","text":"。","attrs":{}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#3db243","name":"user"}}],"text":"Number.MAX_VALUE","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"JavaScript 的 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Number","attrs":{}}],"attrs":{}},{"type":"text","text":" 對象中存儲了很多常量,神祕數字 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"1.7976931348623157e+308","attrs":{}}],"attrs":{}},{"type":"text","text":" 就在其中,打開瀏覽器 Console,輸入 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Number.MAX_VALUE","attrs":{}}],"attrs":{}},{"type":"text","text":",就會得到這個數字:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/1a/1aae4a8c71aae6edc7a7112c6e3125fd.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"1.7976931348623157e+308","attrs":{}}],"attrs":{}},{"type":"text","text":" 也就是 ","attrs":{}},{"type":"katexinline","attrs":{"mathString":"1.7976931348623157 * 10^{308}"}},{"type":"text","text":"。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們今天就來探究這個數字到底是怎麼來的。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"JavaScript 使用的是 ","attrs":{}},{"type":"link","attrs":{"href":"https://en.wikipedia.org/wiki/IEEE_754","title":"","type":null},"content":[{"type":"text","text":"IEEE 754","attrs":{}}]},{"type":"text","text":" 標準定義的 64 位浮點數,也叫做雙精度浮點數。IEEE 754 的 64 位,由三部分組成,分別是:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"numberedlist","attrs":{"start":1,"normalizeStart":1},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"符號位(sign bit):1 bit","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"指數部分(exponent bias):11 bit","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","text":"尾數部分(fraction): 52 bit","attrs":{}}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/db/db7f43476906d315497a008bc381ecca.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/e0/e0ada29bf5a349c8c6eea659b44774b8.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們先看看指數部分,指數一共是 11 位,如果全部爲 1,則最大能夠表示 ","attrs":{}},{"type":"katexinline","attrs":{"mathString":"2^{11} - 1 = 2047"}},{"type":"text","text":"。所以指數的範圍是 [0, 2047]。但是指數部分有負數,所以定義了一個","attrs":{}},{"type":"link","attrs":{"href":"https://en.wikipedia.org/wiki/Exponent_bias","title":"","type":null},"content":[{"type":"text","text":"偏移量","attrs":{}}]},{"type":"text","text":",在 64 位浮點數中,偏移量爲 1023( ","attrs":{}},{"type":"katexinline","attrs":{"mathString":"2^e - 1"}},{"type":"text","text":",","attrs":{}},{"type":"katexinline","attrs":{"mathString":"e"}},{"type":"text","text":" 爲 ","attrs":{}},{"type":"katexinline","attrs":{"mathString":"11"}},{"type":"text","text":")。減去偏移量之後,指數的範圍變成了 ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"[-1023, 1024]","attrs":{}},{"type":"text","text":"。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但是指數全爲 1 和全爲 0 有特殊作用,所以我們可用的指數少了 -1023(對應指數全 0)和 1024(對應指數全 1),範圍變成了 [-1022, 1023]。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"指數不全爲 1 且指數不全爲 0 的浮點數稱作","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"規約化浮點數","attrs":{}},{"type":"text","text":"。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們知道 10 進制的","attrs":{}},{"type":"link","attrs":{"href":"https://zh.wikipedia.org/wiki/%E7%A7%91%E5%AD%A6%E8%AE%B0%E6%95%B0%E6%B3%95","title":"","type":null},"content":[{"type":"text","text":"科學計數法","attrs":{}}]},{"type":"text","text":"中,如 ","attrs":{}},{"type":"katexinline","attrs":{"mathString":"1.7976931348623157 * 10^{308}"}},{"type":"text","text":",小數點前的數字一定是大於 0 的。對於二進制而言也一樣,二進制小數點前數字必須大於 0,而二進制世界只有 0 和 1,所以","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"二進制的科學技術法小數點前的數字一定是1","attrs":{}},{"type":"text","text":",這樣我們就可以節省 1 位,52 位尾數部分可以全部用來表示小數點後面數字。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"綜上,64 位","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"規約化浮點數","attrs":{}},{"type":"text","text":"的公式是這樣的:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"katexblock","attrs":{"mathString":"-1^{sign} \\times (1.F)_{2} \\times 2^{E-1023}"}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"目前已知的條件就可以求出咱們的神祕數字了,想要最大值,指數部分取最大值 1023,尾數全是 1 的話最大,所以我們最大的數字應該是這樣的:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/d1/d1bb48d763aa411439744c1d4afc059f.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們代入公式,其中 sign 爲 0,F 全爲 1,E 爲 2046:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"katexblock","attrs":{"mathString":"-1^{sign} \\times (1.F)_{2} \\times 2^{E-1023}"}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/f8/f86703fe5ab609e7423e35ac458d6b2f.png","alt":null,"title":"","style":[{"key":"width","value":"50%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們用 JavaScript 來驗證一下這個值:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"(2 ** 53 - 1) * (2 ** 971) // 1.7976931348623157e+308\nNumber.MAX_VALUE === (2 ** 53 - 1) * (2 ** 971) // true\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/94/94f5fe65da87105972ed6f11ddf9ca74.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"沒問題,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"1.7976931348623157e+308","attrs":{}}],"attrs":{}},{"type":"text","text":" 這個神祕數字我們終於計算了出來。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"剛纔沒有提符號位,符號位非常簡單,0 表示正數,1 表示負數。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#3db243","name":"user"}}],"text":"特殊值 0,Infinity,NaN","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"剛纔提到了,指數部分全爲 1 或者全爲 0 會有特殊作用,我們先來看看 3 組特殊值。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"0","attrs":{}},{"type":"text","text":":指數位","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"全 0","attrs":{}},{"type":"text","text":",尾數位也","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"全是0","attrs":{}},{"type":"text","text":",則表示 ±0","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/fe/fe7f14870280488487febefba27c5dee.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"∞","attrs":{}},{"type":"text","text":":指數","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"全 1","attrs":{}},{"type":"text","text":",尾數","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"全 0","attrs":{}},{"type":"text","text":",則表示 ±∞,也就是 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Number.POSITIVE_INFINITY","attrs":{}}],"attrs":{}},{"type":"text","text":" 和 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Number.NEGATIVE_INFINITY","attrs":{}}],"attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/98/98fff8eca6f1914ae14db5c6723326c2.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"NaN:指數","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"全1","attrs":{}},{"type":"text","text":",尾數","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"不全爲 0","attrs":{}},{"type":"text","text":",則表示非數字 NaN","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/a8/a84c6e41a570d3d3d5c03129ad16c8c8.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#3db243","name":"user"}}],"text":"Number.MIN_VALUE 和非規約數","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們來看一個相對正常的數字 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"5e-324","attrs":{}}],"attrs":{}},{"type":"text","text":",這是 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Number.MIN_VALUE","attrs":{}}],"attrs":{}},{"type":"text","text":" 的值:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/5c/5c494050a3c42146393a6ba1d73d31ba.png","alt":null,"title":"","style":[{"key":"width","value":"50%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"按照上文規約化浮點數的公式,","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"katexblock","attrs":{"mathString":"-1^{sign} \\times (1.F)_{2} \\times 2^{E-1023}"}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"規約化浮點數,指數部分範圍 [-1022, 1023]。最小值 E = 1,指數部分爲 -1022,尾數部分全爲0最小,此時最小值爲:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/24/2462654ae0c8785207d57dc226afb4a5.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們用 JavaScript 來驗證一下這個值:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"2**(-1022) // 2.2250738585072014e-308\nNumber.MIN_VALUE < 2**(-1022) // true\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"顯然,規約化浮點數的最小值 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"2.2250738585072014e-308","attrs":{}}],"attrs":{}},{"type":"text","text":" 遠大於 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"5e-324","attrs":{}}],"attrs":{}},{"type":"text","text":",從已知的信息,我們是無論如何也推導不出 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"5e-324","attrs":{}}],"attrs":{}},{"type":"text","text":" 的,因爲 IEEE 754 還定義了一種特殊的類型,非規約數(denormalized number),這類數字","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"指數部分全爲 0","attrs":{}},{"type":"text","text":",尾數部分不全爲 0。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"需要特別注意的是,非規約數中,","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"偏移量比規約數偏移量小 1","attrs":{}},{"type":"text","text":",64 位非規約浮點數偏移量爲 ","attrs":{}},{"type":"katexinline","attrs":{"mathString":"1023 - 1 = 1022"}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"公式如下:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"katexblock","attrs":{"mathString":"-1^{sign} \\times (0.F)_{2} \\times 2^{E-1022}"}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"由於指數部分全爲 0,E 爲 0,所以指數部分爲 -1022,上述公式簡化爲:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"katexblock","attrs":{"mathString":"-1^{sign} \\times (0.F)_{2} \\times 2^{-1022}"}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"從公式可以看出,我們可以","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"用非規約數表示更接近 0 的數字","attrs":{}},{"type":"text","text":"。那麼我們來看看最小值:指數始終爲 -1022,若想要最小,則尾數部分末尾只有 1 個 1 是最小的,如下圖所示:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/eb/eb88cbb0f90b1f8339804be15f8317b5.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們代入公式","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/13/132c3e28896486f1ed018ef2c799ebfa.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"再來用 JavaScript 來驗證一下這個值:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"2**(-1074) // 5e-324\nNumber.MIN_VALUE === 2**(-1074) // true\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/61/61bfe9328647eb64b85f150a41a17295.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"終於,這個看似正常的 5e-324 是通過不那麼正常的公式推導出來的。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#3db243","name":"user"}}],"text":"小結","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上文從求 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"1.7976931348623157e+308","attrs":{}}],"attrs":{}},{"type":"text","text":" 的思路出發,對 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Number.MAX_VALUE","attrs":{}}],"attrs":{}},{"type":"text","text":" 和 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Number.MIN_VALUE","attrs":{}}],"attrs":{}},{"type":"text","text":" 進行推導,總結如下:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們可以把 64 位浮點數分爲 3 類:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"1、特殊值","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"0:指數位全 0,尾數位也全是 0,則表示 ±0","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"∞:指數全 1,尾數全 0,則表示 ±∞","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"NaN:指數全 1,尾數不全爲 0,則表示非數字 NaN","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"2、規約形式的浮點數","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"指數位不全爲 0,且不全爲 1,此時偏移量爲 1023,指數範圍 [-1022, 1023]","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"katexblock","attrs":{"mathString":"-1^{sign} \\times (1.F)_{2} \\times 2^{E-1023}"}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"3、非規約形式的浮點數","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"指數位全 0,尾數不全爲 0,此時偏移量爲 1022,指數部分只爲 -1022","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"katexblock","attrs":{"mathString":"-1^{sign} \\times (0.F)_{2} \\times 2^{-1022}"}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#3db243","name":"user"}}],"text":"還有誰","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"其實還有幾個神祕數字,有了上面的公式,我們都能夠推導出來,我們一個個看:","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#3db243","name":"user"}}],"text":"最大安全整數 Number.MAX_SAFE_INTEGER","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Number.MAX_SAFE_INTEGER","attrs":{}}],"attrs":{}},{"type":"text","text":" 的值是 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"9007199254740991","attrs":{}}],"attrs":{}},{"type":"text","text":",我們分析一下,規約化浮點數,尾數部分有 52 位,最大安全整數應該是小數部分全爲 1,指數部分爲 52:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/4d/4d8671e8a332199351fa82d885f51e3e.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"用 JavaScript 來驗證一下","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"2**53 - 1 // 9007199254740991\nNumber.MAX_SAFE_INTEGER === 2**53 - 1 // true\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"沒問題,這個神祕數字 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"9007199254740991","attrs":{}}],"attrs":{}},{"type":"text","text":" 就是 ","attrs":{}},{"type":"katexinline","attrs":{"mathString":"2^{53} -1"}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"來看看爲什麼這個數字是最大安全整數,因爲如果比這個數更大,尾數位已經全部是 1 了,只能增大指數,所以比 Number.MAX_SAFE_INTEGER 更大的整數是:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/3d/3dde45fcfb10eb56b419f02fd1949792.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"是 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Number.MAX_SAFE_INTEGER","attrs":{}}],"attrs":{}},{"type":"text","text":" 的 2 倍,所以最大安全整數只能是 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"9007199254740991","attrs":{}}],"attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"還有一個數字 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Number.MIN_SAFE_INTEGER","attrs":{}}],"attrs":{}},{"type":"text","text":",值爲 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"-9007199254740991","attrs":{}}],"attrs":{}},{"type":"text","text":",這個就很簡單,符號位變爲 1,也就是:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"Number.MIN_SAFE_INTEGER === - Number.MAX_SAFE_INTEGER // true\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#3db243","name":"user"}}],"text":"最小精度 Number.EPSILON","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們來看看最後一個神祕數字 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Number.EPSILON","attrs":{}}],"attrs":{}},{"type":"text","text":",","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"2.220446049250313e-16","attrs":{}}],"attrs":{}},{"type":"text","text":" 是如何來的。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Number.EPSILON","attrs":{}},{"type":"text","text":" 屬性表示 1 與 ","attrs":{}},{"type":"link","attrs":{"href":"https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Number","title":"","type":null},"content":[{"type":"text","text":"Number","attrs":{}}]},{"type":"text","text":" 可表示的大於 1 的最小的浮點數之間的差值。可表示大於 1 的最小浮點數是這樣的:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/01/018e35e6bf782247c7cf09bfbf864cf0.png","alt":null,"title":"","style":[{"key":"width","value":"50%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"那麼根據定義, Number.EPSILON 就是:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/35/359df36e9dc1529267446b8ca8a57d6a.png","alt":null,"title":"","style":[{"key":"width","value":"50%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"用 JavaScript 來驗證一下:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"2**-52 // 2.220446049250313e-16\nNumber.EPSILON === 2**-52 // true\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"沒問題,最後一個神祕數字搞定, ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"2.220446049250313e-16","attrs":{}}],"attrs":{}},{"type":"text","text":" 就是 ","attrs":{}},{"type":"katexinline","attrs":{"mathString":"2^{-52}"}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#3db243","name":"user"}}],"text":"回到那道經典題目 “0.1 + 0.2 爲什麼等於 0.30000000000000004”","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#3db243","name":"user"}}],"text":"十進制小數轉二進制","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"先回顧一下十進制小數轉 2 進制方法:“乘2取整,順序排列”法:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"0.1 轉換二進制:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/85/85682e9cce7f50bcdda934c69094d348.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"0.2 轉換二進制:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/a8/a8ac18098ebc2297b39ebd9c7e8b6454.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可以看到,0.1 和 0.2 轉爲二進制都是無限循環小數,轉爲 64 位浮點數會有精度損失,我們來轉換一下:","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#3db243","name":"user"}}],"text":"0.1 在 64 位浮點數中的存儲","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/90/905e80768b08cf8712b01392c83d09d5.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"(1019).toString(2)","attrs":{}}],"attrs":{}},{"type":"text","text":" 可以算出 1019 的二進制爲 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"1111111011","attrs":{}}],"attrs":{}},{"type":"text","text":" :","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/0d/0d7807fb94ba9ad45dae03a96ab43971.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"共 10 位,頭部補 0 得到 11 位指數 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"01111111011","attrs":{}}],"attrs":{}},{"type":"text","text":":","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/f6/f64fda7b0ad734c7939d03315e7a487a.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"再來看尾數部分:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/80/80c92c6b9d8d9cc8248d819427405a99.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1 開始,0111 循環,到了第 52 位爲 1,但是需要額外注意,第 53 位仍然是 1,捨去需要進 1,尾數部分變爲了(爲了方便閱讀,使用了 ES2021 的","attrs":{}},{"type":"link","attrs":{"href":"https://github.com/tc39/proposal-numeric-separator","title":"","type":null},"content":[{"type":"text","text":"數值分隔符","attrs":{}}]},{"type":"text","text":") ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"1_0011_0011_0011_0011_0011_0011_0011_0011_0011_0011_0011_0011_010","attrs":{}}],"attrs":{}},{"type":"text","text":":","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/c3/c3d1574e89f47e70a50e3c0082b66375.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"因此,0.1 在 64 位浮點數上存儲如下:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/69/69d4bf421e618394bd85f4af8c2772c5.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#3db243","name":"user"}}],"text":"0.2 在 64 位浮點數中的存儲","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/27/2718c9e490b409a1be000c135ed368c3.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"(1020).toString(2)","attrs":{}}],"attrs":{}},{"type":"text","text":" 可以算出 1020 的二進制爲 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"1111111100","attrs":{}}],"attrs":{}},{"type":"text","text":" :","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/fd/fde4e1e2580f779a2a729f46a37f83cc.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"共 10 位,頭部補 0 得到 11 位指數 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"01111111100","attrs":{}}],"attrs":{}},{"type":"text","text":":","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/51/5195a1c77724241e220225978714f79c.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"尾數部分和 0.1 完全一致,也需要進 1,尾數部分爲 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"1_0011_0011_0011_0011_0011_0011_0011_0011_0011_0011_0011_0011_010","attrs":{}}],"attrs":{}},{"type":"text","text":"。因此 0.2 在 64 位浮點數上存儲如下:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/f1/f119f431160b8ffe5e36550b35113e8f.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#3db243","name":"user"}}],"text":"浮點數加法","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"現在需要這兩個數字相加,但是指數不一致,沒有辦法直接相加,需要轉換,這次轉換帶來了","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"第二次精度損失","attrs":{}},{"type":"text","text":":","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"指數不一致,需要將較小的指數調整和較大的指數一致,在本例中,需要將 0.1 指數位調整到 1020,因此尾數位需要右移,注意規約數小數點前的 1 也要右移,變爲尾數部分變爲 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"11_0011_0011_0011_0011_0011_0011_0011_0011_0011_0011_0011_0011_01","attrs":{}}],"attrs":{}},{"type":"text","text":":","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/90/901911e4aaa7ad46a6f771ce2ed082cf.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"現在指數部分相同,我們把尾數部分相加:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"(0b1_0011_0011_0011_0011_0011_0011_0011_0011_0011_0011_0011_0011_010 \n+ 0b11_0011_0011_0011_0011_0011_0011_0011_0011_0011_0011_0011_0011_01\n).toString(2)\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"得到結果 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"10110011001100110011001100110011001100110011001100111","attrs":{}}],"attrs":{}},{"type":"text","text":" ,共 53 位。這塊需要特別注意,規約數小數點左側默認爲 1,現在加法之後多出一位,小數點左側 +1,變爲了 ","attrs":{}},{"type":"katexinline","attrs":{"mathString":"(10)_2"}},{"type":"text","text":",可以理解爲 ","attrs":{}},{"type":"katexinline","attrs":{"mathString":"(10.0110011001100110011001100110011001100110011001100111)_2"}},{"type":"text","text":" 這個數字。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"小數點需要左移動,指數 +1,變爲 1021,尾數需要捨去 1 位,由於尾數爲 1,需要進 1,代入公式:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"katexblock","attrs":{"mathString":"1.0011001100110011001100110011001100110011001100110100 * 2^{1021 - 1023}\n\n\\\\= 10011001100110011001100110011001100110011001100110100* 2^{-2 - 52}\n\n\\\\= 10011001100110011001100110011001100110011001100110100* 2^{-54}"}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"用 JavaScript 驗證:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"0b10011001100110011001100110011001100110011001100110100 * (2**-54) // 0.30000000000000004\n0b10011001100110011001100110011001100110011001100110100 * (2**-54) === 0.1 + 0.2 // true\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/82/82ebda0bf15204795e238d653dd89963.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"沒問題,驗證結束。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#3db243","name":"user"}}],"text":"參考資料","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://zh.wikipedia.org/wiki/IEEE_754","title":"","type":null},"content":[{"type":"text","text":"IEEE 754 - 維基百科,自由的百科全書","attrs":{}}]}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://en.wikipedia.org/wiki/IEEE_754-1985","title":"","type":null},"content":[{"type":"text","text":"IEEE 754-1985 - Wikipedia","attrs":{}}]}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://www.boatsky.com/blog/26","title":"","type":null},"content":[{"type":"text","text":"深入理解IEEE754的64位雙精度 - 太空船博客","attrs":{}}]}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://blog.csdn.net/abcdu1/article/details/75095781","title":"","type":null},"content":[{"type":"text","text":"IEEE754標準 單精度(32位)/雙精度(64位)浮點數解碼_Do-CSDN博客","attrs":{}}]}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://www.javascriptc.com/books/nodejs-roadmap/javascript/floating-point-number-0.1-0.2.html","title":"","type":null},"content":[{"type":"text","text":"JavaScript 浮點數之迷:0.1 + 0.2 爲什麼不等於 0.3?","attrs":{}}]}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"horizontalrule","attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章