JavaScript 數學與數字處理:四捨五入、取整與亂數
簡介
在前端開發或 Node.js 後端程式中,數字的處理是最常見的需求。不管是顯示金額、計算統計資料,或是產生隨機測試資料,都離不開 JavaScript 內建的 Math 物件與數字相關的方法。
本單元將聚焦在三個核心議題:
- 四捨五入(
Math.round、Number.prototype.toFixed等) - 取整數(
Math.ceil、Math.floor、Math.trunc) - 亂數產生(
Math.random與常見的隨機範圍技巧)
掌握這些技巧後,你可以在 UI 顯示、資料分析、遊戲開發或測試自動化等多種情境中,正確且高效地處理數字。
核心概念
1. 四捨五入
1.1 Math.round
Math.round(x) 會將 x 四捨五入到最接近的整數。
- 小數點第一位 5 或以上則「進位」;
- 低於 5 則「捨去」。
console.log(Math.round(4.2)); // 4
console.log(Math.round(4.5)); // 5
console.log(Math.round(-2.7)); // -3
註:負數的四捨五入同樣遵守「靠近」的原則,
-2.5會變成-2(因為 -2 比 -3 更接近 -2.5)。
1.2 指定小數位的四捨五入
Number.prototype.toFixed(digits) 可將數字四捨五入到 指定的小數位,並回傳字串。
const price = 1234.5678;
console.log(price.toFixed(2)); // "1234.57"
console.log(price.toFixed(0)); // "1235"
⚠️ 注意:
toFixed回傳的是字串,若需再做數學運算,請使用Number()或parseFloat()轉型。
1.3 自訂四捨五入函式(避免浮點誤差)
JavaScript 的浮點運算會產生微小誤差,例如 0.1 + 0.2 !== 0.3。結合 Number.EPSILON 可以寫出更安全的四捨五入:
function roundTo(num, decimals) {
const factor = Math.pow(10, decimals);
// 加上 EPSILON 以抵消浮點誤差
return Math.round((num + Number.EPSILON) * factor) / factor;
}
console.log(roundTo(1.005, 2)); // 1.01
2. 取整數
| 方法 | 功能說明 | 例子 |
|---|---|---|
Math.ceil(x) |
向上取整(不小於 x 的最小整數) |
Math.ceil(4.2) // 5 |
Math.floor(x) |
向下取整(不大於 x 的最大整數) |
Math.floor(4.8) // 4 |
Math.trunc(x) |
直接截斷小數部份(正負號保留) | Math.trunc(4.9) // 4Math.trunc(-4.9) // -4 |
~~x (位元運算) |
快速截斷(只對 32 位元整數有效) | ~~4.9 // 4 |
2.1 Math.ceil 與 Math.floor 的差異
console.log(Math.ceil(3.1)); // 4
console.log(Math.floor(3.9)); // 3
console.log(Math.ceil(-3.1)); // -3 // 向上取整對負數是「更接近 0」的方向
console.log(Math.floor(-3.9)); // -4 // 向下取整對負數是「更遠離 0」的方向
2.2 Math.trunc 的使用情境
在需要 捨去小數,且不想受到正負號的「向上/向下」影響時,Math.trunc 是最直接的選擇。
// 計算時間差(秒)時,只要整數秒
function diffSeconds(start, end) {
return Math.trunc((end - start) / 1000);
}
3. 亂數產生
3.1 Math.random() 基本用法
Math.random() 會回傳 0(含)~ 1(不含) 之間的隨機浮點數。
console.log(Math.random()); // 0.374823...
3.2 產生指定範圍的整數
常見需求是「產生 最小值 ≤ n ≤ 最大值 的整數」。以下是通用函式:
function randomInt(min, max) {
// 確保 min 與 max 為整數
const _min = Math.ceil(min);
const _max = Math.floor(max);
// Math.random() * (max - min + 1) 產生 0 ~ (max-min+1) 之間的數
// 再加上 min,最後使用 Math.floor 取整
return Math.floor(Math.random() * (_max - _min + 1)) + _min;
}
// 範例:隨機產生 1~6 的骰子點數
console.log(randomInt(1, 6));
3.3 產生隨機小數(保留特定位數)
function randomFloat(min, max, decimals = 2) {
const factor = Math.pow(10, decimals);
return Math.round((Math.random() * (max - min) + min) * factor) / factor;
}
// 產生 0.00 ~ 1.00 之間,保留 3 位小數
console.log(randomFloat(0, 1, 3));
3.4 產生隨機陣列(例如測試資料)
function randomArray(length, min, max) {
return Array.from({ length }, () => randomInt(min, max));
}
// 產生 10 個 0~100 的隨機數字
console.log(randomArray(10, 0, 100));
3.5 亂數的安全性與限制
Math.random不適合 用於密碼、驗證碼或加密相關需求,因為它不是加密安全的隨機數生成器。- 若需要安全隨機數,請使用 Web Crypto API(
crypto.getRandomValues)或 Node.js 的crypto.randomInt。
// 使用 Web Crypto 產生 0~255 的安全隨機位元組
const array = new Uint8Array(1);
crypto.getRandomValues(array);
console.log(array[0]); // 0~255 的安全隨機值
常見陷阱與最佳實踐
| 陷阱 | 說明 | 最佳實踐 |
|---|---|---|
| 浮點精度誤差 | 0.1 + 0.2 !== 0.3 會出現不可預期的結果。 |
使用 Number.EPSILON 或 BigInt / Decimal.js 等套件做高精度運算。 |
toFixed 回傳字串 |
直接相加會變成字串拼接。 | 轉回數字:Number(num.toFixed(2)) 或 parseFloat(...)。 |
負數與 Math.ceil / floor 的方向 |
初學者常把 ceil 以為「永遠向上」而忽略負數情況。 |
先了解正負號的行為,或直接使用 Math.trunc。 |
Math.random 的範圍錯誤 |
常見寫法 Math.random() * max 會產生 0 ≤ n < max,但不包括 max 本身。 |
若要包含上界,使用 Math.floor(Math.random() * (max - min + 1)) + min。 |
重複呼叫 Math.random 產生相同序列 |
在大量迴圈裡,若不小心使用相同的種子(雖然 Math.random 沒有種子概念),仍會出現「模式」感。 |
若需要可預測的隨機序列,使用 seedable random 套件(如 seedrandom)。 |
| 安全性需求 | Math.random 不能保證隨機性足夠強。 |
使用 Web Crypto 或 Node.js crypto。 |
實際應用場景
金額顯示
- 使用
toFixed(2)讓金額固定兩位小數,並搭配Number()轉回數字做後續計算。
- 使用
分頁與列表排序
- 依照使用者的排序需求,使用
Math.round或Math.floor來計算總頁數、當前頁的起始索引。
- 依照使用者的排序需求,使用
遊戲開發
randomInt(1, 6)產生骰子點數;randomArray(5, 0, 10)產生怪物屬性值。
資料視覺化
- 為圖表產生隨機顏色或隨機測試資料,以
randomFloat控制透明度或亮度。
- 為圖表產生隨機顏色或隨機測試資料,以
測試自動化
- 產生大量隨機測試資料(例如表單欄位的隨機字串長度或數值範圍),確保程式在不同輸入下的穩定性。
時間計算
- 使用
Math.trunc把毫秒差距轉成「完整秒數」或「完整分鐘」的統計。
- 使用
總結
本篇文章從 四捨五入、取整數、亂數產生 三大面向,說明了 JavaScript 提供的核心 API 以及實務上常見的使用方式。透過:
Math.round、toFixed、自訂roundTo來處理精確的四捨五入;Math.ceil、Math.floor、Math.trunc針對不同需求取整;Math.random搭配通用的randomInt、randomFloat、randomArray,快速產生所需的隨機資料。
同時,我們也點出了 浮點誤差、字串回傳、負數行為與安全性 等常見陷阱,並提供相對的最佳實踐。掌握這些技巧,你將能在前端 UI、後端計算、遊戲或測試自動化等多種情境中,安全、正確且高效地處理數字與隨機需求。祝你在 JavaScript 的世界裡玩得開心、寫得順手!