Decimal 是什麼
想必大家在用js 處理 數字的 加減乘除的時候,或許都有遇到過 精度不夠的問題
還有那些經典的面試題 02+0.1 == 0.3
至於原因,那就是 js 計算底層用的 是 IEEE 754 ,精度上有限制
那麼,Decimal.js
就是幫助我們解決 js
中的精度失準的問題。
原理
- 它的原理就是將數字用字符串表示,字符串在計算機中可以說是無限的。
- 並使用基於字符串的算術運算,以避免浮點數運算中的精度丟失。它使用了一種叫做十進制浮點數算術(Decimal Floating Point Arithmetic)的算法來進行精確計算。
- 具體來說,decimal.js庫將數字表示爲一個字符串,其中包含整數部分、小數部分和一些其他的元數據。它提供了一系列的方法和運算符,用於執行精確的加減乘除、取模、冪運算等操作。
Decimal 的引入 與 加減乘除
-
如何引入
npm install --save decimal.js // 安裝 import Decimal from "decimal.js" // 具體文件中引入
- 加
let a = 1 let b = 6 // a 與 b 可以是 任何類型,Decimal 內部會自己處理兼容 // 下面兩種都可以 可以帶 new 也不可以不帶 new let res = new Decimal(a).add(new Decimal(b)) let res = Decimal(a).add(Decimal(b))
- 減
let a = "4" let b = "8" // a 與 b 可以是 任何類型,Decimal 內部會自己處理兼容 // 下面兩種都可以 可以帶 new 也不可以不帶 new let res = new Decimal(a).sub(new Decimal(b)) let res = Decimal(a).sub(Decimal(b))
- 乘
let a = 1 let b = 6 // a 與 b 可以是 任何類型,Decimal 內部會自己處理兼容 // 下面兩種都可以 可以帶 new 也不可以不帶 new let res = new Decimal(a).mul(new Decimal(b)) let res = Decimal(a).mul(Decimal(b))
- 除
let a = 1 let b = 6 // a 與 b 可以是 任何類型,Decimal 內部會自己處理兼容 // 下面兩種都可以 可以帶 new 也不可以不帶 new let res = new Decimal(a).div(new Decimal(b)) let res = Decimal(a).div(Decimal(b))
注意
上面的結果是 一個 Decimal 對象,你可以轉換成 Number 或則 String
let res = Decimal(a).div(Decimal(b)).toNumber() // 結果轉換成 Number let res = Decimal(a).div(Decimal(b)).toString() // 結果轉換成 String
關於保存幾位小數相關
//查看有幾位小數 (注意不計算 小數點 最後 末尾 的 0) y = new Decimal(987000.000) y.sd() // '3' 有效位數 y.sd(true) // '6' 總共位數 // 保留 多少個位數 (小數位 會補0) x = 45.6 x.toPrecision(5) // '45.600' // 保留 多少位有效位數(小數位 不會補0,是計算的有效位數) x = new Decimal(9876.5) x.toSignificantDigits(6) // '9876.5' 不會補0 只是針對有效位數 // 保留幾位小數 , 跟 js 中的 number 一樣 toFixed x = 3.456 // 向下取整 x.toFixed(2, Decimal.ROUND_DOWN) // '3.45' (舍入模式 向上0 向下1 四捨五入 4,7) // 向上取整 Decimal.ROUND_UP //四捨五入 ROUND_HALF_UP
超過 javascript 允許的數字
如果使用超過 javascript 允許的數字的值,建議傳遞字符串而不是數字,以避免潛在的精度損失。
new Decimal(1.0000000000000001); // '1' new Decimal(88259496234518.57); // '88259496234518.56' new Decimal(99999999999999999999); // '100000000000000000000' new Decimal(2e308); // 'Infinity' new Decimal(1e-324); // '0' new Decimal(0.7 + 0.1); // '0.7999999999999999'
可讀性
與 JavaScript 數字一樣,字符串可以包含下劃線作爲分隔符以提高可讀性。
x = new Decimal("2_147_483_647");
其它進制的數字
如果包含適當的前綴,則也接受二進制、十六進制或八進制表示法的字符串值。
x = new Decimal("0xff.f"); // '255.9375' y = new Decimal("0b10101100"); // '172' z = x.plus(y); // '427.9375' z.toBinary(); // '0b110101011.1111' z.toBinary(13); // '0b1.101010111111p+8' x = new Decimal( "0b1.1111111111111111111111111111111111111111111111111111p+1023" ); // '1.7976931348623157081e+308'