1. 程式人生 > >js 長整型精度問題-那些年踩過的坑

js 長整型精度問題-那些年踩過的坑

決定整理一些踩過的坑,就叫那些年踩過的坑吧,今天要說的是最近發生的JS 問題。
這是由於一系列修改而引發出來的,先是運營妹子跑過來說客戶購匯訂單支付不成功,果斷檢視日誌,是“ID 重複” 導致入庫失敗,看了下id 生成規則。結果是最後四位導致的,最後四位竟然是截取了序列sequence 的前四位那當10001/10002/10003… 這樣的序列時豈不是生成的id 都相同了,不懂之前的人處於什麼考慮,果斷修改放開擷取直接用全部的序列號,檢查過資料庫的長度也夠。但是問題出現了:不擷取sequence 後 重複問題是沒有了,但是出現了長整型。導致那一天連續十多單的訂單資料 客戶都對不上了。真是嚇的不輕。例如:明明訂單號是9992018012210063 可從頁面上傳到後臺就成了9992018012210064,這就導致後臺查資料又按照9992018012210064 的訂單來購匯。
最後排查就是js 長整型惹的禍。先貼一段簡單的頁面程式碼讓大家驗證一下:

<!DOCTYPE html>
<script type="text/javascript">
    var m = 9992018012210063;
    function alertFun(){
        alert(m);
    }

</script>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <button
onclick="alertFun()">
測試</button> </body> </html>

你會發現當m 的值大於15位之後,彈出來的m 值最後一位經常是錯誤的, 這也就在實際開發過程中埋雷了。
對於我們的系統裡的解決方法是之後採用了字串型別加了引號來解決。
之後查了網上資料說是
大整數的精度丟失和浮點數本質上是一樣的,尾數位最大是 52 位,因此 JS 中能精準表示的最大整數是 Math.pow(2, 53),十進位制即 9007199254740992

大於 9007199254740992 的可能會丟失精度