bignumber.js というライブラリを知ったので調査
JavaScriptの数値はIEEE 754 倍精度浮動小数点数(double)のため、数を表現するために使えるビット数に限りがあり、少数の計算が正しくできない
double は、例えば 1 / 10の結果(0.1) 2進数への変換で無限に続く循環小数になってしまうため、丸め誤差が発生してしまう
そのため、JavaScriptでより正確な計算をする場合、外部ライブラリを用いなければならず、 bignumber.js はその少数計算ライブラリの1つである
主な特徴
- 整数と小数に対応
- シンプルなAPIながらフル機能
- JavaのBigDecimalをJavaScriptで実現したものより、高速かつ軽量で扱いやすい
- サイズが小さい(gzip圧縮後で8 KB)
- JavaScriptのNumber型のtoExponential、toFixed、toPrecision、toStringメソッドを再現
- toFractionメソッドと正確に丸められるsquareRootメソッドを含む
- 暗号学的に安全な疑似乱数生成をサポート
- 依存関係なし
- 幅広いプラットフォーム互換性:JavaScript 1.5(ECMAScript 3)のみを使用
- 包括的なドキュメントとテストセット
基本的な使い方
bignumber.js は、Number、String、BigNumber型の値を受け入れる単一のコンストラクタ関数をエクスポートしている
初期化
// 文字列から初期化 const a = new BigNumber("123.4567"); // 数値から初期化(ただし、0.1などそもそも丸め誤差になっているものは注意が必要) const b = new BigNumber(123.4567); // 他の BigNumber から初期化 const c = new BigNumber(a);
基本演算
const x = new BigNumber('0.1'); const y = new BigNumber('0.2'); // 加算 console.log(x.plus(y).toString()); // '0.3' // 減算 console.log(x.minus(y).toString()); // '-0.1' // 乗算 console.log(x.multipliedBy(y).toString()); // '0.02' // 除算 console.log(x.dividedBy(y).toString()); // '0.5' // べき乗 console.log(x.pow(2).toString()); // '0.01'
除算を含む演算 (除算、平方根、基数変換、負の累乗演算など) の結果の小数点以下の最大桁数は、コンストラクタのsetメソッドを使用して設定できる
BigNumber.set({ DECIMAL_PLACES: 2, ROUNDING_MODE: BigNumber.ROUND_HALF_UP }); const z = new BigNumber('1.005'); console.log(z.toFixed()); // '1.01'
あとは比較など
const p = new BigNumber('10'); const q = new BigNumber('20'); console.log(p.isLessThan(q)); // true console.log(p.isEqualTo(q)); // false console.log(p.isGreaterThan(q)); // false