BigNumber.jsの丸め処理のタイミング
背景
TypeScriptの実装中、BigNumber.jsで丸め処理を行おうとしたが上手く作用しなかった。
↓コード例
// typescript
// 小数点5位以下を切り捨て
const roundDown4: typeof BigNumber = BigNumber.clone({
ROUNDING_MODE: BigNumber.ROUND_DOWN,
DECIMAL_PLACES: 4
});
const A: number = 100;
const B: number = 3;
const C: number = 20;
// A÷B×Cの結果を小数点5位以下を切り捨てしたい
// 期待値 = 100÷3×20 = 666.6666666~ ⇒ 666.6666
const result: BigNumber = roundDown4(A).div(B).times(C);
console.log(result.toString());
// 出力結果: 666.666
// 期待値と異なる
原因
BigNumber.jsの仕様
ROUNDING_MODEとDECIMAL_PLACESの設定に間違いはなかった。
しかし、ROUNDING_MODEとDECIMAL_PLACESの設定が適用されるのは
①roundDown4(X) と宣言したタイミング
②.div(Y) と割り算が行われたタイミング
である。
したがって、コード例では
A÷B×Cの結果を小数点5位以下で切り捨てしようとしているが、
実際の結果はA÷Bの結果を小数点5位以下で切り捨てた後に×Cが行われている。
対応内容
A÷B×C = A×C÷Bなので処理の順番を入れ替えた。
// × const result: BigNumber = roundDown4(A).div(B).times(C);
// ○ const result: BigNumber = roundDown4(A).times(C).div(B);
const result: BigNumber = roundDown4(A).times(C).div(B);
console.log(result.toString());
// 出力結果: 666.6666
// 期待の結果を得られた
今後への学び
除算は最後に付けよう!!!!!!
でないと除算のタイミングで丸め処理が行われる。