[英]Floating point number in JavaScript (IEEE 754)
這意味着它使用 52 位作為小數有效數。 但是在上圖中,二進制中的 0.57 似乎使用了 54 位。
JavaScript 的Number
類型本質上是 IEEE 754 基本 64 位二進制浮點數,具有 53 位有效數。 52 位編碼在“尾隨有效數”字段中。 前導位通過指數字段編碼(1-2046 的指數字段表示前導位為 1,指數字段 0 表示前導位為零,2047 的指數字段用於無窮大或 NaN)。
您看到的 0.57 的值有 53 個有效位。 領先的“0”。 由toString
操作產生; 它不是數字編碼的一部分。
但是為什么 0.55 + 1 = 1.55(沒有損失)和 0.57 + 1 = 1.5699999999999998。
當 JavaScript 格式化一些Number
x以使用其默認規則顯示時,這些規則說產生最短的十進制數字(在其有效數字中,不計算像前導“0”這樣的裝飾。)當轉換回Number
格式時,產生x 。 此規則的目的包括 (a) 始終確保顯示唯一標識哪個確切的Number
值是源值,以及 (b) 不使用超過完成 (a) 所需的數字。
因此,如果您以十進制數字(如 .57)開始並將其轉換為Number
,您將得到一些值x ,這是轉換必須四舍五入為可以用Number
格式表示的Number
。 然后,當x被格式化以供顯示時,您將獲得原始數字,因為產生最短數字並轉換回x 的規則自然會產生您開始使用的數字。
(但那個x並不完全代表 0.57。最接近 0.57 的double
精度略低於它; 在 IEEE double
精度計算器上查看它的十進制和二進制 64 表示)。
另一方面,當您執行諸如.57 + 1
類的某些操作時,您正在執行一些算術運算,該算術生成的數字y並非以簡單的十進制數字開頭。 因此,在格式化此類數字以供顯示時,規則可能需要使用更多數字。 換句話說。 當您將.57
和1
相加時, Number
格式的結果與您從1.57
得到的數字不同。 因此,要格式化.57 + 1
的結果,JavaScript 必須使用更多數字來區分該數字與您從1.57
獲得的數字——它們是不同的,必須以不同的方式顯示。
如果 0.57 完全可以表示為double
,則總和的預舍入結果將正好是 1.57,因此1 + 0.57
將舍入為與1.57
相同的double
。
但事實並非如此,實際上是1 + nearest_double(0.57)
=
1.569999999999999951150186916493
(四舍五入,不是double
1.569999999999999951150186916493
),四舍五入為
1.56999999999999984012788445398
。 這些數字的十進制表示比我們需要區分有效數的 1ulp(最后一位單位),甚至 0.5 ulp 最大舍入誤差所需的位數多得多。
1.57
舍入到 ~ 1.57000000000000006217248937901 ,因此這不是打印1 + 0.57
的結果的選項。 十進制字符串需要將數字與相鄰的 binary64 值區分開來。
碰巧發生在.55 + 1
中的舍入產生與從1.55
轉換為Number
相同的數字,因此顯示.55 + 1
的結果會產生“1.55”。
toString(2)
字符串打印到最后一個非零數字。
1.57 與 1 + 0.57 具有不同的位表示(但得到結果 1.57 並非不可能),
但是二進制中的 1 + 0.55 等於 1.55,如下面的代碼片段所示:
console.log(1.57) console.log(1.57.toString(2)) console.log((1+.57).toString(2)) console.log("1.32 + 0.25 = ",1.32 + .25) console.log((1.32 + .25).toString(2)) console.log(1.55) console.log(1.55.toString(2)) console.log((1+.55).toString(2))
請記住,計算機對二進制數執行操作, 1.57
或1.55
只是人類可讀的輸出
Number.prototype.toString
大致實現了 ES262 規范的以下部分:
7.1.12.1 NumberToString(m)
令 n、k 和 s 是整數,使得 k ≥ 1, 10 ** k-1 ≤ s < 10 ** k,
s × 10 ** nk 的數值是 m,
並且 k 盡可能小。
因此toString
只是估計值,它不返回存儲的確切字節。
您在控制台中看到的也不是准確的表示。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.