🕌

JavaScriptの小数の計算誤差にtoFixedを使う

2021/05/15に公開

DBは小数点で保存、ページ表示はパーセントで出したかったのですが、JavaScriptは特定の値で小数の計算がバグりますね😅

90.1 / 100 -> 0.9009999999999999
0.14 * 100 -> 14.000000000000002

参考: JavaScriptでの小数点の計算の誤差について

そこで以下のようなコードを書いてみました。

// % -> 小数
export const percentToDecimal = (value: number): number =>
  Number((value / 100).toFixed(5)); 
// 小数 -> %
export const decimalToPercent = (value: number): number =>
  Number((value * 100).toFixed(5));

(90 / 100).toFixed(5)だと"0.90000"で余分な0が入ってしまうため、Numberにして0.9にしてます。
toFixed(5)にしてるのはパーセントも小数点第3位まで想定のためです(99.123%とか)
小数点第3位の考慮がなければ、toFixed(2)とかでよいかも

テストコードもこの通り、想定した値になりました。めでたしめでたし😆

describe('percentToDecimal', () => {
   it('percentToDecimal(100.0) should be 1', () => {
     expect(percentToDecimal(100.0)).toBe(1);
   });
   it('percentToDecimal(99.1) should be 0.991', () => {
     expect(percentToDecimal(99.1)).toBe(0.991);
   });
   it('percentToDecimal(99.01) should be 0.9901', () => {
     expect(percentToDecimal(99.01)).toBe(0.9901);
   });
   it('percentToDecimal(90.123) should be 0.90123', () => {
     expect(percentToDecimal(90.123)).toBe(0.90123);
   });
 });
 describe('decimalToPercent', () => {
   it('decimalToPercent(1) should be 100', () => {
     expect(decimalToPercent(1)).toBe(100);
   });
   it('decimalToPercent(0.991) should be 99.1', () => {
     expect(decimalToPercent(0.991)).toBe(99.1);
   });
   it('decimalToPercent(0.9901) should be 99.01', () => {
     expect(decimalToPercent(0.9901)).toBe(99.01);
   });
   it('decimalToPercent(0.90123) should be 90.123', () => {
     expect(decimalToPercent(0.90123)).toBe(90.123);
   });
 });

Discussion