探秘 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}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章