本文 AI 產出,尚未審核

JavaScript 課程 – 數學與數字處理(Math & Numbers)

主題:Math 物件


簡介

在日常的前端開發或 Node.js 後端程式中,數值運算隨機產生、以及角度、時間的轉換都是常見需求。
雖然 JavaScript 內建的算術運算子(+、-、*、/、%)足以處理簡單的加減乘除,但面對更複雜的需求時,我們就需要依賴 全域的 Math 物件

Math 提供了一組 靜態方法(不需要實例化)與 常數,涵蓋了三角函數、指數與對數、四捨五入、隨機數產生等功能。掌握它不僅能讓程式碼更簡潔,也能提升計算的正確性與效能,是每位 JavaScript 開發者的必備工具。


核心概念

1. Math 常數

常數 說明 範例
Math.PI 圓周率 π(約 3.14159) Math.PI * radius ** 2 計算圓面積
Math.E 自然常數 e(約 2.71828) Math.pow(Math.E, x) 計算 e 的 x 次方
Math.LN2Math.LN10Math.LOG2EMath.LOG10E 各種對數基底的常數 Math.log2(8) === Math.LOG2E * Math.log(8)

小技巧:直接使用常數比手寫數值更安全,避免因四捨五入誤差造成的計算偏差。

2. 基本數學函式

方法 功能 範例
Math.abs(x) 取絕對值 Math.abs(-5) // 5
Math.max(...values) 取得最大值 Math.max(3, 9, -2) // 9
Math.min(...values) 取得最小值 Math.min(3, 9, -2) // -2
Math.round(x) 四捨五入到最接近的整數 Math.round(4.6) // 5
Math.floor(x) 向下取整 Math.floor(4.9) // 4
Math.ceil(x) 向上取整 Math.ceil(4.1) // 5
Math.trunc(x) 去除小數部分(不四捨五入) Math.trunc(4.9) // 4

3. 高階函式

方法 功能 範例
Math.pow(base, exponent) 計算 baseexponent 次方 Math.pow(2, 3) // 8
Math.sqrt(x) 開根號 Math.sqrt(16) // 4
Math.cbrt(x) 立方根 Math.cbrt(27) // 3
Math.hypot(...values) 計算歐幾里得距離(向量長度) Math.hypot(3,4) // 5
Math.sin/Math.cos/Math.tan(x) 三角函數(參數必為弧度) Math.sin(Math.PI/2) // 1
Math.asin/Math.acos/Math.atan(x) 反三角函數,回傳弧度 Math.acos(0) // Math.PI/2
Math.log(x) 自然對數(底 e) Math.log(Math.E) // 1
Math.log10(x)Math.log2(x) 常用底 10、2 的對數 Math.log10(100) // 2

4. 隨機數

  • Math.random() 會回傳 0(含)到 1(不含) 之間的浮點數。
  • 常見的「產生區間隨機整數」寫法如下:
/**
 * 產生 min ~ max(含)之間的隨機整數
 * @param {number} min 最小值(含)
 * @param {number} max 最大值(含)
 * @returns {number}
 */
function randInt(min, max) {
  // 先確保 min <= max,若傳入相反值則自動交換
  if (min > max) [min, max] = [max, min];
  // Math.random() * (max - min + 1) 產生 [0, max-min+1) 的浮點數
  // 再加上 min,最後取整數
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

// 範例:產生 1~100 的隨機整數
console.log(randInt(1, 100));

程式碼範例

下面提供 5 個實務上常用的範例,每個範例都附有說明與註解,讓你快速上手 Math 物件的各種功能。

範例 1:計算圓的面積與周長

/**
 * 計算圓的面積與周長
 * @param {number} radius 半徑
 * @returns {{area:number, circumference:number}}
 */
function circle(radius) {
  // 使用 Math.PI 取得更精確的圓周率
  const area = Math.PI * Math.pow(radius, 2);          // πr²
  const circumference = 2 * Math.PI * radius;         // 2πr
  return { area, circumference };
}

console.log(circle(5));
// => { area: 78.53981633974483, circumference: 31.41592653589793 }

為什麼使用 Math.pow 而不是 radius ** 2
兩者在 ES6+ 都可以,但在舊版瀏覽器(IE)仍需 Math.pow,同時可保持語意一致。


範例 2:將角度 (Degree) 轉為弧度 (Radian) 並計算 sin、cos

/**
 * 角度轉弧度
 * @param {number} deg 角度值
 * @returns {number} 弧度值
 */
function degToRad(deg) {
  return deg * (Math.PI / 180);
}

/**
 * 計算 sin、cos、tan(接受角度參數)
 * @param {number} deg 角度
 * @returns {{sin:number, cos:number, tan:number}}
 */
function trigFromDegree(deg) {
  const rad = degToRad(deg);
  return {
    sin: Math.sin(rad),
    cos: Math.cos(rad),
    tan: Math.tan(rad)
  };
}

console.log(trigFromDegree(45));
// => { sin: 0.7071067811865475, cos: 0.7071067811865476, tan: 0.9999999999999999 }

小技巧Math.tan(90°) 會因為弧度值無法精確表示而回傳極大數值,實務上若需要判斷垂直,可先檢查 Math.abs(cos) < Number.EPSILON


範例 3:四捨五入到指定小數位

/**
 * 四捨五入到 n 位小數
 * @param {number} value 原始數值
 * @param {number} digits 保留的小數位數
 * @returns {number}
 */
function roundTo(value, digits) {
  const factor = Math.pow(10, digits);
  // 先乘以 factor,四捨五入後再除回去
  return Math.round(value * factor) / factor;
}

console.log(roundTo(3.1415926, 2)); // 3.14
console.log(roundTo(1.005, 2));    // 1.01 (避免浮點誤差)

為什麼要使用 Math.pow(10, digits)
直接寫 10 ** digits 也行,但 Math.pow 在舊環境相容性更好。


範例 4:找出一組數字中的最大公因數 (GCD)

/**
 * 計算兩個正整數的最大公因數(Euclidean algorithm)
 * @param {number} a
 * @param {number} b
 * @returns {number}
 */
function gcd(a, b) {
  // 確保 a、b 為正整數
  a = Math.abs(a);
  b = Math.abs(b);
  while (b !== 0) {
    const temp = b;
    b = a % b;   // 取餘數
    a = temp;
  }
  return a;
}

/**
 * 計算任意長度陣列的 GCD
 * @param {number[]} nums
 * @returns {number}
 */
function arrayGCD(nums) {
  return nums.reduce((prev, cur) => gcd(prev, cur));
}

console.log(arrayGCD([48, 64, 80])); // 16

說明%(取餘)是唯一需要「手動」使用的算術運算子;其餘的邏輯全部由 Math 協助完成。


範例 5:產生隨機顏色(HEX)

/**
 * 產生隨機 HEX 顏色字串,例如 "#3FA9C4"
 * @returns {string}
 */
function randomHexColor() {
  // Math.random() 產生 0~1,* 0xFFFFFF 取得 0~16777215
  const num = Math.floor(Math.random() * 0xFFFFFF);
  // 轉成 16 進位字串,padStart 確保六位
  const hex = num.toString(16).padStart(6, '0');
  return `#${hex}`;
}

console.log(randomHexColor()); // 例: "#a1b2c3"

實務應用:在圖表、遊戲或 UI 主題切換時,快速產生不重複的色彩。


常見陷阱與最佳實踐

陷阱 說明 最佳做法
浮點數精度問題 例如 0.1 + 0.2 !== 0.3 使用 Number.EPSILON 或先乘除整數後再除回來(如範例 3)
角度與弧度混用 Math.sin(90) 會把 90 當作弧度,結果錯誤 統一使用弧度或建立 degToRad/radToDeg 輔助函式
Math.random() 的分布不均 直接取 Math.random()*NMath.floor 會產生 [0,N-1] 的均勻分布,但 不適用於加密 若需安全隨機,使用 crypto.getRandomValues(瀏覽器)或 crypto.randomInt(Node)
忘記 Math 是靜態物件 不能 new Math(),也不會有 this 相關概念 直接以 Math.xxx 調用
NaNInfinity 的處理 Math.max(NaN, 5) => NaN 使用 Number.isNaN 檢查或先過濾陣列

其他最佳實踐

  1. 封裝常用計算:將常見的「角度轉弧度」或「四捨五入」寫成工具函式,提升可讀性。
  2. 避免硬編碼常數:如 3.14159 改用 Math.PI,避免因精度差異產生 bug。
  3. 使用 Number.isFinite 保障輸入:在接受外部數值(例如 API 回傳)時,先檢查是否為有限數字。
  4. 對大數運算考慮 BigIntMath 不支援 BigInt,若需要超過 Number.MAX_SAFE_INTEGER,改用自訂演算法或第三方函式庫。

實際應用場景

場景 需求 使用的 Math 方法
資料視覺化(Chart.js、D3) 計算座標、縮放比例、角度 Math.max/min, Math.sin/cos, Math.round
遊戲開發(Canvas、WebGL) 產生隨機敵人位置、碰撞檢測 Math.random, Math.hypot, Math.floor
金融系統 四捨五入到分(2 位小數)或千分位 Math.round, Number.EPSILON
密碼學相關 UI 產生隨機驗證碼顏色 Math.random, toString(16)
科學計算(統計、機器學習) 計算標準差、指數衰減 Math.sqrt, Math.expMath.pow(Math.E, x)

案例說明:假設我們在一個線上投票系統,需要根據投票比例即時顯示圓形圖的扇形角度。利用 Math.PI * 2 * (voteCount / total) 計算弧度,再配合 Math.sin/Math.cos 產生座標,即可在 Canvas 上繪製正確的扇形。


總結

Math 物件是 JavaScript 標準庫中最常被使用、也是最基礎的工具之一。掌握它的 常數、基本函式與高階函式,不僅能讓你在日常開發中寫出更簡潔、正確的程式碼,還能避免常見的浮點誤差與角度混淆等陷阱。

  • 常數Math.PI、Math.E)提供精確的基礎值。
  • 基本函式abs、max、min、round)是日常四則運算的好幫手。
  • 高階函式sin、cos、log、hypot)讓複雜的科學計算變得輕鬆。
  • 隨機數Math.random)配合簡單的區間函式,可快速產生測試資料或 UI 效果。

在實務開發中,建議 將常用的 Math 包裝成工具函式,並遵守「避免硬編碼、檢查輸入、注意浮點精度」的最佳實踐。如此一來,無論是前端圖表、後端統計模型,或是遊戲畫面渲染,都能夠以最少的程式碼達成正確且高效的數學運算。

祝你在 JavaScript 的數學世界中玩得開心,寫出更穩定、更易讀的程式碼! 🚀