SheepDev

數值、單位與位元

大型 ID 需要多少位元?也用十六進位查看

使用工具

訂單 ID 貼進表格後,末位變成 0;另一個頁面又把兩個相鄰 ID 顯示成同一個數字。能顯示大整數與能完整保留每一位是兩回事,小數值正常的處理也可能在越界時出錯。

以下使用容易觀察邊界的範例整數,不使用真實 ID。先檢查型別能否容納,再轉換進位並轉回。藉此考慮資料庫、API、瀏覽器、試算表軟體整個傳遞過程的表示方式。

255 的下一個數,還能放進 8 位元嗎?

在整數範圍工具選擇範圍模式、8 位元、無號,得到 0 到 255,共 256 種值,但最大值不是 256。值的數量與最大值相差一,這個關係在更大位元寬度下仍成立。

跨越邊界的三個值
254 = 11111110₂
255 = 11111111₂
256 = 100000000₂

切換到所需位元數模式,以無號分別檢查 255 與 256,結果為 8 位元與 9 位元。只增加 1,也可能需要多一位。依預計用量選擇型別時,還應考慮未來成長與保留值,而不只是目前數值。

同為 64 位元,範圍也不同

把位元寬度改成 64,比較有號與無號。有號還要表示負數,正數上限較小:9,223,372,036,854,775,807;無號上限是 18,446,744,073,709,551,615。只憑「64 位元欄位」無法判斷能否相容傳遞。

8 位元有號的最大值也只有 127。正數 128 需要 8 位元無號或 9 位元有號。即使 ID 不用負數,接收端若宣告為有號型別,仍須遵守其範圍;ID 不會自動變成無號。

將 20 位十進位整數轉成十六進位再轉回

十進位輸入:不加分組逗號
18446744073709551615

選擇十進位轉十六進位,得到 ffffffffffffffff,共 16 個 f。再以十六進位轉十進位輸入此結果,應還原原來的 20 位。核對全部數字,確認表示變化未改變整數。途中維持文字,不要先經過其他計算機的數值輸入。

一個十六進位數字可表示 4bit,因此此值對應 64 個二進位 1。但由字元數推算最小位元寬度時,要考慮前導零與首位。0f 雖有兩個字元,值 15 仍只需 4 位元無號。固定儲存寬度與最小表示寬度不同。

能放進整數型別,不代表 Number 能精確保留

JavaScript 的 Number 不是 64 位元整數型別,其安全整數上限為 9,007,199,254,740,991。更大的某些整數仍可表示,但無法保證所有相鄰整數都可區分。某個大值顯示正常,不代表同位數的所有 ID 都安全。

精度檢查範例
9007199254740993

直接輸入進位轉換,十進位轉十六進位得到 20000000000001,再檢查反向轉換。如果經過其他步驟後已經變成 9007199254740992,原來的位數已經遺失,之後轉 BigInt 也無法推斷還原原整數。

ID 應該是數字還是字串?

編號 00123 的數值是 123,但文字表示不同。進位轉換處理數值,不適合保留前導零數量。先確定是參與運算的數量,還是精確比對的識別碼,不要只因郵遞區號或會員號只含數字就轉成數值。

API 用字串傳 ID,需要與接收型別共同約定,不能擅自加引號就當解決。如果約定原本是字串,途中卻轉 Number,那一步就可能遺失精度。排查時應涵蓋顯示、搜尋、CSV 匯出,而不只看儲存。

將完整位數一致作為傳遞測試

測試應涵蓋邊界前、邊界上、邊界後,而不只選安全小值。8 位元無號可用 254、255、256,Number 則用安全邊界附近連續整數。區分明確拒絕與自動捨入,不能靠縮小數值讓驗證通過。

報告時應寫明位置與表示,例如「可放入 64 位元無號儲存,瀏覽器中保留為字串」,而不是籠統說「64 位元沒問題」。所需位元數只是型別選擇依據,不保證實際資料庫欄位或協定支援,仍需檢查規範並做原路徑往返測試。

同一位元模式,有無號會改變意義

八位 11111111 無號時是 255,按有號二補數讀則是 -1。把十進位 255 轉成二進位不等於自動解釋為 -1。進位是表示方法,符號和位元寬度是固定長度欄位的解釋規則;日誌裡看到 ff,應先查欄位是否有號。

前導零也一樣:數值 0010 與 10 相等,但商品編碼可能不同。進位工具不負責保留識別碼寬度,CSV 使用端也可能把文字編碼當數字。應先判斷這是用於運算的數量還是用於比對的名稱;不僅大整數,小值轉換也會丟掉重要資訊。

重現時測試邊界及相鄰值:八位元無號用 254、255、256,JavaScript 安全整數邊界用 9007199254740991 附近。檢查 JSON 解析和 API 傳遞前後何處從文字變數字。上游已經丟失的尾數,高精度工具無法還原;保留原始文字並找到首次變化的位置。

參考資料

使用工具

指南 →