📑
JavaScriptで小数点付きの計算をしよう
はじめに
記事の修正や追加等はコメントまたはGitHubの編集リクエストをお待ちしております。
また、この記事の内容は私が個人的に開発しているモジュールのコードを抜き出した物です。
特別な処理がいる理由
JavaScriptは計算の際暗黙的に2進数で計算しています。
例えば0.1を2進数にすると0.000110011001100…となります。
> 0.1 * 0.1
0.010000000000000002
これは小数点がなくなるように 10のn乗
すると解決します
(n=小数点以下の桁数
)
小数点以下の桁数を求める
.
以下の桁数さえ分かればいいので split
で切り出します。
const getDecimalLength = (value: number) => {
let x = (value + '').split('.')[1];//splitで分割して小数点以下を取得
if (typeof x !== 'undefined' && x.length > 0) {
return x.length;
}
return 0;
};
実際に計算してみる
掛け算
import getDecimalLength from './getDecimalLength';
const multiplication = (x: number, y: number) => {
const n = 10 ** (getDecimalLength(x) + getDecimalLength(y));
x = +(x + '').replace('.', '');
y = +(y + '').replace('.', '');
return (x * y) / n;
};
足し算
import getDecimalLength from './getDecimalLength';
import max from './max';
import multiplication from './multiplication';
const addition = (x: number, y: number) => {
const z = Math.pow(
10,
max([getDecimalLength(x), getDecimalLength(y)]),
);
return (multiplication(x, z) + multiplication(y, z)) / z;
};
割り算
import { getDecimalLength } from './getDecimalLength';
import { valueSwap } from './valueSwap';
export const division = ((
x: number,
y: number,
) => {
const [decimalLengthX, decimalLengthY] = valueSwap(
getDecimalLength(x),
getDecimalLength(y),
);
const n =
decimalLengthX == decimalLengthY
? 1
: Math.pow(10, decimalLengthY - decimalLengthX);
x = +(x + '').replace('.', '');
y = +(y + '').replace('.', '');
return x > y
? x / y / n
: (x / y) * n
}
引き算は逆のことをやればいいので省略。
まとめ
覚えておいて損はないと思います。
いつの日か小数点がらみの誤作動に出逢ったら是非この記事へ。
宣伝
今回コードの説明はGitHub Copilotにやってもらいました。
詳しくはこちら
ブログやってます。
Discussion