🕌
JavaScriptの小数の計算誤差にtoFixedを使う
DBは小数点で保存、ページ表示はパーセントで出したかったのですが、JavaScriptは特定の値で小数の計算がバグりますね😅
90.1 / 100 -> 0.9009999999999999
0.14 * 100 -> 14.000000000000002
そこで以下のようなコードを書いてみました。
// % -> 小数
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