━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
■第20回 消費税計算
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
皆さんもご存知のとおり、現在の消費税率は5%(0.05)です。
なので、消費税額 = 税抜き額 × 0.05
になるのですが、コンピュータの場合には問題が起こる場合があります。
今回は、そんなお話です。
●実数の形式
コンピュータが実数(整数+小数)を扱うときは2つの形式があります。
「固定小数」と「浮動小数」です。
「固定小数」は、整数と小数の桁数を固定で表記します。
桁数が固定なので、精度を超えた桁数のデータを入れると、切り捨てられた
り、丸められたりすることがあります。
多くのプログラミング言語では、Decimalという型で使うことができます。
「浮動小数」は、仮数部と指数部で表記します。
例えば、1.5 に 1000 を掛けたとすると、1.5 × 10^3 というように指数部
が増えていきます。
固定小数とは違い、桁数は固定ではありません。
指数部を増やすことで桁が変わってくるので、扱える数値の範囲が大きいの
が特徴です。
プログラミング言語では、Real、Single、Float、Doubleなどの型になりま
す。
●小数を2進数にすると
第7回で説明したとおり、2進数では位が上がると数が倍に増えていきます。
(10進数では10倍になりますよね)
1 の位 → 2 の 0 乗の位
2 の位 → 2 の 1 乗の位
4 の位 → 2 の 2 乗の位
8 の位 → 2 の 3 乗の位
16 の位 → 2 の 4 乗の位
ですね。
では、1の位より下はどうでしょうか。
1 の位 → 2 の 0 乗の位
0.5 の位 → 2 の -1 乗の位
0.25 の位 → 2 の -2 乗の位
0.125 の位 → 2 の -3 乗の位
0.0625 の位 → 2 の -4 乗の位
ということになります。
位が下がると数が半分になっていく訳です。
分かりやすいように、0.1という数を2進数にしてみます。
1 の位 → 0
0.5 の位 → 0
0.25 の位 → 0
0.125 の位 → 0
0.0625 の位 → 1 (合計:0.0625)
0.03125 の位 → 1 (合計:0.09375)
0.015625 の位 → 0
0.0078125 の位 → 0
0.00390625 の位 → 1 (合計:0.09765625)
のように、0.1を超えないように位をどんどん下げていきます。
上の例では、2の-8乗まで書いていますが、0.1になる気配はありませんね。
実は、0.1はどこまで計算しても終わりが無いため、2進数では正確に表記す
ることができません。
このような小数を無限小数と言います。
0.1は無限小数なので、2進数では0.1に限りなく近づきますが、0.1ではあり
ません。
そのため、再び10進数に変換すると、0.999999999999… となってします。
プログラミング言語にもよりますが、0.1を10回足しても 1 にならないこと
を知っておいてください。
●消費税計算
消費税は 0.05 ですが、この数値は 0.1 の半分です。
つまり、0.1の結果を右に1桁シフトしたものと同じになりますので、0.05も
無限小数になります。
0.05が無限小数ということは、10進数に戻すと0.04999999… となるという
ことですね。
100円の商品を買ったとすると、
100 × 0.04999999… = 4.999999… 円となり、切捨てすると 4円になりま
す。1円足りなくなってしまいましたね。
このようなケースに対する対応策は2つあります。
1つ目は、計算式を工夫することです。
原因が0.05という小数値を使っていることが原因ですので、0.05を5÷100と
置き換えます。
100 × 5 ÷ 100 = 5 円となり、小数計算を使わなくなりますので、正常
な結果が求められます。
2つ目は、固定小数を使うことです。
Decimal型は、「2進化10進数」という形式を使っています。
「2進化10進数」は、それぞれの桁を10進数で表記しています。
つまり、各位に4ビット使い、「0000(0)」から「1001(9)」で表します。
こうすることで、10進数を扱うことができます。
10進数ですから、誤差が無く計算できるのですが、浮動小数よりも計算速度
が遅くなりますので、大量の計算を行う場合は不向きなこともあります。
(小さな誤差を無視できる場合ですが)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━