在工作上遇到了大位數金額計算的需求,才發現 Javascript 的 number 有著先天的問題無法處理大數,於是我就找了第三方函式庫來協助我完成需求。
以下是這次的學習筆記。
問題說明
Javascript 的數字型態一律為遵守 IEEE 754 規範的 number,採用雙精度儲存(double precision),佔用 64 bit。若整體數字(整數 + 小數)的長度超過 16 ~ 17 位,就會發生數字丟失的問題。
若只是單純要在畫面上呈現大數字/浮點數,可以用 string 即可;但若需要針對大數字/浮點數進行運算(加減乘除),則需要額外處理。
解決方法
可以使用第三方套件來協助我們更簡單快速地處理大數。
decimal.js
Github : https://github.com/MikeMcl/decimal.js/
NPM : https://www.npmjs.com/package/decimal.js/v/3.0.0
API Document : http://mikemcl.github.io/decimal.js/
安裝:
npm install decimal.js
引入:
const Decimal = require('decimal.js');
import Decimal from 'decimal.js';
import {Decimal} from 'decimal.js';
以下是我整理出的基本使用介紹:
- 加法 x + y
- new Decimal(x).add(y)
- new Decimal(x).plus(y)
- 減法 x – y
- new Decimal(x).sub(y)
- new Decimal(x).minus(y)
- 乘法 x * y
- new Decimal(x).mul(y)
- new Decimal(x).times(y)
- 除法 x / y
- new Decimal(x).div(y)
- new Decimal(x).dividedBy(y)
- 四捨五入 x 至 z 位數
- new Decimal(x).toFixed(z)
- x 和 y 的型態可為 string、number 或 new Decimal()。但其中 number 型態仍然不能超過 16 位數,不然還沒被 decimal.js 計算就會先溢位。
- 注意 x 和 y 不能是空的,不然會有 error。
import { Decimal } from 'decimal.js';
x = new Decimal('1234567890123456'); // '1234567890123456'
y = new Decimal('0.1234'); // '0.1234'
= '0.1234' // '0.1234'
= 0.1234 // 0.1234(注意若要使用 number 型態不能超過 16 位數)
// 加法
x.add(y) // '1234567890123456.1234'
// 運算不會影響原變數值
x // '1234567890123456'
// 四捨五入至小數第二位
x.add(y).toFixed(2) // '1234567890123456.12'
// 減法
x.sub(y) // '1234567890123455.8766'
// 乘法
x.mul(y) // '152345677641234.4704'
// 除法
x.div(y) // '10004602026932382.496'