LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網站管理員

JS 處理長整型數字的坑:從雪花 ID 精度丟失說起

freeflydom
2025年7月10日 9:46 本文熱度 270

在服務端使用 64 位長整型(Int64)數字,而前端通過 JavaScript 的number類型接收時,若數值超過2^53 - 1(即 9007199254740991),會出現(xiàn)數值不相等的問題。這一現(xiàn)象的核心原因是 JavaScript 中number類型的精度限制,而雪花算法生成的 ID(通常為 64 位)恰好屬于這類場景,因此需要特別處理。

一、問題根源:JavaScript 中number的精度限制

JavaScript 的number類型基于IEEE 754 雙精度浮點數標準實現(xiàn),其底層存儲結構決定了它的精度范圍:

  • 雙精度浮點數的 “尾數(mantissa)” 部分占 52 位,加上隱藏的 1 位 “整數位”,總共可表示53 位有效精度

  • 這意味著:對于整數,number類型能精確表示的范圍是[-2^53 + 1, 2^53 - 1],這個范圍外的整數無法被精確存儲,會出現(xiàn) “精度丟失”。

當服務端返回的 Int64 數值超過2^53 - 1時,JavaScript 的number會因無法精確表示該值,導致存儲的結果與實際值不一致(例如末尾幾位被截斷或四舍五入)。

二、典型場景:雪花算法 ID 的問題

雪花算法(Snowflake)生成的 ID 是 64 位整數,結構通常為:

  • 1 位符號位(固定為 0,保證正數);

  • 41 位時間戳;

  • 10 位機器 ID;

  • 12 位序列號。

顯然,64 位整數的最大值為2^63 - 1(約 9e18),遠超過2^53 - 1,因此用number接收時必然會丟失精度,導致前端存儲的 ID 與服務端實際值不匹配(例如服務端 ID 為1234567890123456789,前端接收后可能變成1234567890123456700)。

三、解決方法:如何避免精度丟失?

解決的核心思路是繞開 JavaScriptnumber類型的精度限制,常見方案如下:

1. 以字符串形式傳遞大整數

最直接的方式是服務端在返回數據時,將 Int64 類型的字段轉換為字符串,前端接收后以字符串形式存儲和使用。

  • 服務端處理:例如在 Java 中,將Long類型的雪花 ID 轉換為String后再序列化到 JSON 中;
  • 前端接收:直接使用字符串類型的 ID(無需轉換為number),避免精度丟失。

2. 前端使用BigInt類型處理大整數

BigInt是 JavaScript 中專門用于表示任意精度整數的類型,可精確存儲超過2^53 - 1的數值。

  • 服務端:保持 Int64 類型的數值(例如 JSON 中直接存儲數字);
  • 前端處理:
    • 接收時,通過BigInt()構造函數將數值轉換為BigInt類型(例如const id = BigInt(response.id));

    • 注意:BigIntnumber不能直接運算,需顯式轉換(例如BigInt(123) + 456n,其中nBigInt的字面量后綴)。

示例
服務端返回 JSON:{ "id": 1234567890123456789 }
前端處理:

javascript

// 直接用number接收會丟失精度
const numId = response.id; // 結果可能為1234567890123456700(錯誤)
// 用BigInt接收可保持精度
const bigIntId = BigInt(response.id); // 結果為1234567890123456789n(正確)

3. 框架 / 序列化工具的配置優(yōu)化

在前后端數據交互中(尤其是 JSON 序列化 / 反序列化),可通過工具配置自動處理大整數:

  • 例如,使用JSON.parse時,通過reviver函數將大整數轉換為BigInt

    javascript

    const data = JSON.parse(response, (key, value) => {
      // 假設ID字段名為"id",且數值超過2^53-1
      if (key === 'id' && typeof value === 'number' && value > 2**53 - 1) {
        return BigInt(value);
      }
      return value;
    });
    
  • 部分框架(如 Vue、React)或 HTTP 客戶端(如 Axios)可配置攔截器,自動將大整數字段轉換為BigInt或字符串。

四、注意事項

  1. 兼容性BigInt在 IE 瀏覽器中不支持,但現(xiàn)代瀏覽器(Chrome、Firefox、Edge 等)均已支持;
  2. 字符串傳遞的優(yōu)勢:若前端僅需展示或傳遞 ID(無需數值運算),字符串形式更簡單,避免BigInt的類型轉換成本;
  3. 數據庫交互:若前端需將 ID 回傳到服務端或存儲到數據庫,保持字符串或BigInt類型即可(服務端可再轉換為 Int64 處理)。

總結

當服務端的 Int64 數值超過2^53 - 1時,JavaScript 的number類型無法精確表示,導致數值不匹配。解決核心是避開number的精度限制,推薦通過 “字符串傳遞” 或 “前端BigInt處理” 兩種方式,尤其在雪花算法 ID 等 64 位整數場景中必須使用。

?轉自https://juejin.cn/post/7524645466745815059


該文章在 2025/7/10 9:46:53 編輯過
關鍵字查詢
相關文章
正在查詢...
點晴ERP是一款針對中小制造業(yè)的專業(yè)生產管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內大量中小企業(yè)的青睞。
點晴PMS碼頭管理系統(tǒng)主要針對港口碼頭集裝箱與散貨日常運作、調度、堆場、車隊、財務費用、相關報表等業(yè)務管理,結合碼頭的業(yè)務特點,圍繞調度、堆場作業(yè)而開發(fā)的。集技術的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點晴WMS倉儲管理系統(tǒng)提供了貨物產品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質期管理,貨位管理,庫位管理,生產管理,WMS管理系統(tǒng),標簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務都免費,不限功能、不限時間、不限用戶的免費OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved

黄频国产免费高清视频,久久不卡精品中文字幕一区,激情五月天AV电影在线观看,欧美国产韩国日本一区二区
中文亚洲欧美乱码在线观看 | 日本久久高清视频 | 中文字幕在线精品视频站 | 亚洲中文字幕在线观看 | 中文字幕v亚洲日本在电影 亚洲片中文字幕在线看 | 日本午夜免a费看大片中文4 |