簡體   English   中英

JavaScript toFixed()無法按預期工作

[英]Javascript toFixed() is not working as expected

我正在使用toFixed但是該方法無法按預期運行

parseFloat(19373.315).toFixed(2);

//19373.31   Chrome 

預期產量:19373.32

parseFloat(9373.315).toFixed(2);
// 9373.32  Working fine

為什么第一個示例向下取整,而第二個示例向上取整?

問題在於大多數小數部分的二進制浮點表示形式不准確。 19373.315的內部表示實際上可能類似於19373.314999999,因此toFixed向下取整,而19373.315可能為19373.315000001,向上取整。

為什么第一個示例向下取整,而第二個示例向上取整?

查看內存中兩個值的二進制表示形式。

 const farr = new Float64Array(2); farr[0] = 19373.315; farr[1] = 9373.315; const uarr = new Uint32Array(farr.buffer); console.log(farr[0], uarr[1].toString(2).padStart(32, 0) + uarr[0].toString(2).padStart(32, 0)); console.log(farr[1], uarr[3].toString(2).padStart(32, 0) + uarr[2].toString(2).padStart(32, 0)); 

在不深入細節的情況下,我們可以看到第二個值的末尾有一個額外的“ 1”,當它適合64位時,會在第一個較大的值中丟失。

假設固定轉換為32位浮點型; 檢查此實用程序...

19373.315以32位浮點格式存儲為19373.314453125(錯誤-0.000546875)。

盡管(19373.315).toFixed(4)結果為19373.3150

即使這是“預期的”或“預期的”,我仍將其報告為錯誤。

在四舍五入檢查期間應使用雙精度,因此在轉換為固定字符串期間應進行適當的四舍五入。

我認為規范甚至是這樣說的。 :\\

在V8 javascript引擎源代碼中, Number.prototype.toFixed函數在此文件中調用DoubleToFixedCString ...

那里可能有一些不適當的優化...(正在研究它。)

我建議為V8額外提交一個測試案例,具體 19373.315。

(19373.3150).toFixed(39)得出19373.314999999998690327629446983337402343750。

舍入一次會使其達到19373.315(這是正確的),但是舍入到兩位數時不會出現在正確的數字上。

我認為這里應該進行第二次四舍五入,以捕獲像這樣的邊緣情況。 我想可能有舍入到n+1再次數字,然后n數字。 也許還有其他一些聰明的方法可以解決它。

 function toFixedFixed(a,n) { return (a|0) + parseFloat((a % 1).toFixed(n+1)).toFixed(n).substr(1); } console.log(toFixedFixed(19373.315,2)); // "19373.32" console.log(toFixedFixed(19373.315,3)); // "19373.315" console.log(toFixedFixed(19373.315,4)); // "19373.3150" console.log(toFixedFixed(19373.315,37)); // "19373.3149999999986903276294469833374023438" console.log(toFixedFixed(19373.315,38)); // "19373.31499999999869032762944698333740234375" console.log(toFixedFixed(19373.315,39)); // "19373.314999999998690327629446983337402343750" 

(摘自我對Vahid Rahmani的回答的評論,誰是正確的。)

其他答案也解釋了為什么,我建議使用像numeric.js這樣的庫,它將按您期望的那樣處理。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM