Decimal.js:JavaScript 中的高精度十進制運算庫

作者: Calpa Liu
字數:1515
出版:2025 年 4 月 7 日
Decimal.js 是一個為 JavaScript 和 TypeScript 設計的任意精度十進制運算庫,專為解決 JavaScript 原生數字型別在處理浮點數時所面臨的精度問題。對於需要高精度計算的金融和科學應用來說,這個庫提供了一個強大且可靠的解決方案。

浮點數運算的問題與 Decimal.js 的解決方案

在 JavaScript 中,浮點數使用 IEEE 754 雙精度格式表示,這導致了一些令人困惑的計算結果。例如,一個經典的案例是:

0.1 + 0.2; // 輸出:0.30000000000000004,而非預期的 0.3

這不僅僅是 JavaScript 特有的問題,而是幾乎所有計算機表示數字時的共同缺陷。當數字從十進制轉換為二進制時,由於位數有限,某些數字無法被精確表示,從而導致舍入誤差。

Decimal.js 通過直接以十進制方式表示數字來解決這個問題,而不需要進行二進制轉換:

const Decimal = require("decimal.js");
const a = new Decimal("0.1");
const b = new Decimal("0.2");
const result = a.plus(b);
console.log(result.toString()); // 輸出:'0.3'

這種方法確保了計算結果的準確性,特別是在金融和科學應用中,這些領域通常不能容忍任何計算誤差。

Decimal.js 的核心特性

任意精度十進制運算

Decimal.js 最顯著的特點是它能夠進行任意精度的十進制運算。這意味著它可以處理包含任意數量有效數字的數值,無論是非常大還是非常小的數字。

// 處理超大數字
const largeNumber = new Decimal("123456789e+250");
const result = largeNumber.times("10e+150");
console.log(result.toString()); // 輸出:'1.23456789e+409'

完整的數學功能支持

Decimal.js 提供了豐富的 API,複製了 JavaScript 中Number.prototypeMath對象的許多方法,同時還增加了如三角函數等其他功能。

可配置的精度與舍入模式

所有計算都會根據 Decimal 構造函數的precisionrounding屬性指定的有效數字數量和舍入模式進行舍入。

// 設置默認 Decimal 構造函數的精度和舍入方式
Decimal.set({ precision: 5, rounding: 4 });

// 創建另一個 Decimal 構造函數,可選地傳入配置對象
const Dec = Decimal.clone({ precision: 9, rounding: 1 });

const x = new Decimal(5);
const y = new Dec(5);

console.log(x.div(3)); // 輸出:'1.6667'
console.log(y.div(3)); // 輸出:'1.66666666'

使用 Decimal.js 的優勢

精確的十進制運算

使用 Decimal.js 可以避免 JavaScript 浮點數計算中常見的精度誤差。這對於需要精確計算的金融和貨幣處理至關重要。

擴展的數值範圍

Decimal.js 可以表示任意大小的數字,遠超過 JavaScript 原生 Number 類型的限制。這在需要處理極大或極小數值的科學計算中特別有用。

// JavaScript 中數值超出範圍會導致精度損失
new Decimal(2e308); // 'Infinity' 在原生 JavaScript 中
new Decimal("2e+308"); // 可以正確表示在 Decimal.js 中

可定制的精度控制

Decimal.js 允許開發者根據應用需求設置所需的精度級別,確保計算結果按照預期進行舍入。

簡單一致的 API

Decimal.js 提供了簡潔明了的 API,使其易於學習和使用。它的方法名稱直觀,功能齊全。

廣泛的平台兼容性

Decimal.js 僅使用 JavaScript 1.5(ECMAScript 3)特性,因此可以在各種平台上運行,包括較舊的瀏覽器環境。

TypeScript 支持

Decimal.js 包含 TypeScript 聲明文件,提供了完整的類型支持,有助於提高代碼質量和開發效率。

與其他類似庫的比較

市場上存在幾個類似的高精度數字庫,各有優缺點:

big.js

  • 高性能,專為速度優化
  • 簡單直觀的 API
  • 相比 Decimal.js 功能較少
  • 運算速度:1,164,624.9 Ops/sec

bignumber.js

  • 全面的數學運算功能
  • 用戶群體大,維護活躍
  • 運算速度:611,546.2 Ops/sec

decimal.js-light

  • Decimal.js 的輕量版本,不包含三角函數
  • 保持高精度但體積更小
  • 性能更好,適合對大小有嚴格限制的項目

在性能方面,這些庫都比原生 JavaScript 數字慢得多(原生操作:177,217,520.0 Ops/sec),但對於要求精確計算的應用來說,這種性能損失通常是可以接受的。

使用示例

基本算術運算

const Decimal = require("decimal.js");

const a = new Decimal("9.99");
const b = new Decimal("8.03");

// 加法
const addition = a.add(b);
console.log(addition.toString()); // '18.02'

// 減法
const subtraction = a.sub(b);
console.log(subtraction.toString()); // '1.96'

// 乘法
const multiplication = a.mul(b);
console.log(multiplication.toString()); // '80.2197'

// 除法
const division = a.div(b);
console.log(division.toString()); // '1.244084682440847'

處理金融計算

在金融應用中,Decimal.js 可以確保計算的準確性,避免因舍入誤差導致的資金損失。

// 計算貸款利息
const principal = new Decimal("10000");
const rate = new Decimal("0.05").div(12); // 月利率
const term = 60; // 60 個月

// 計算每月付款額
const monthlyPayment = principal
  .times(rate)
  .div(new Decimal(1).minus(new Decimal(1).plus(rate).pow(-term)));

console.log(monthlyPayment.toFixed(2)); // '188.71'

性能考量

雖然 Decimal.js 提供了高精度計算,但這是以性能為代價的。與原生 JavaScript 數字相比,Decimal.js 的運算速度明顯較慢(約 762,818.1 Ops/sec vs 原生的 177,217,520.0 Ops/sec)。

因此,在選擇使用 Decimal.js 時,應該考慮應用的需求:

  • 如果精確度至關重要(如金融計算),Decimal.js 是理想選擇
  • 對於性能敏感但不需要極高精度的應用,可以考慮使用原生數字或其他優化方法

結論

Decimal.js 是一個強大的 JavaScript 庫,為需要進行精確十進制計算的應用提供了可靠的解決方案。它解決了 JavaScript 原生浮點數運算中固有的精度問題,提供了豐富的數學功能和靈活的配置選項。

對於金融應用、科學計算或任何對數值精度有嚴格要求的領域,Decimal.js 提供了不可或缺的工具。雖然它可能不如原生數字運算那麼快,但在需要精確結果的場景中,這種性能損失通常是值得的。

作為一個 Web3 開發者,尤其是在處理加密貨幣相關計算時,使用像 Decimal.js 這樣的高精度庫可以確保交易金額的準確性,避免因精度問題導致的資金損失。結合 TypeScript 的類型檢查,能夠進一步提高代碼的可靠性和可維護性。

關於 Calpa

Calpa 擅長使用 TypeScriptReact.jsVue.js 建立 Responsive Website。

他積極參與開源社區,曾在 2019 年的香港開源大會上擔任講者,提供工作經驗和見解。此外,他也在 GitHub 上公開分享個人博客程式碼,已獲得超過 300 顆星星和 60 個分支的支持。

他熱愛學習新技術,並樂意分享經驗。他相信,唯有不斷學習才能跟上快速演變的技術環境。

熱門文章

最新文章

圖片管理中心
管理圖片資源
IP 查詢
快速查詢和定位 IP 地址的地理位置和相關信息
Python 運行器
無需後端、無需登入,只需打開瀏覽器即可運行 Python 代碼(由 Pyodide 提供支持)
封面圖生成器
自動創建適合各種平台的文章封面圖
原作(青山剛昌)產生器
一鍵創建原作(青山剛昌)的封面圖
日本色彩
探索和使用傳統日本色彩
部落格內容洞察儀表板
以視覺化儀表板方式追蹤文章成效、分享熱度與分類分布,協助創作者掌握內容表現。
蒙特卡羅估算 π
使用蒙特卡羅方法演示 π 值的估算過程
LLM
使用 LLM 模型進行聊天
活動圖生成器
一鍵創建活動的封面圖
Wagmi Card
一鍵創建 Wagmi 的封面圖
Facebook Quote
Facebook Quote
Music Macro Language (MML) Studio
用程式語法編寫旋律,用音符構築想像
Blurhash
一鍵創建 Blurhash
文字分類器
使用 MediaPipe TextClassifier 分類文字
前端工程師免費工具資源
前端工程師免費工具資源
後端工程師免費工具資源
後端工程師免費工具資源
全端工程師免費工具資源
全端工程師免費工具資源
Web3 工程師免費工具資源
Web3 工程師免費工具資源
紫微斗數排盤系統|結合 AI 的命盤性格與事業財務分析生成器
紫微斗數排盤工具,輸入生日與時辰,自動生成完整命盤分析提示(Prompt)。結合最專業紫微理論與 AI 助力,助你深入解析性格、事業、財務與人際課題。免費使用,適合命理師及紫微愛好者。
PixAI Prompt 組合器|快速打造可用於 AI 繪圖的語言拼圖
使用 PixAI 卻不會寫 prompt?這個工具幫你一鍵組裝角色、表情、風格語彙,輸出高品質繪圖提示語句(Prompt),可直接貼入 PixAI 使用。適合插畫師、創作者、AI 新手與 VTuber 角色開發者。