ITサポート

セミナー

会員特典

その他

過去のコラム等

Twitter

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ■第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進数ですから、誤差が無く計算できるのですが、浮動小数よりも計算速度  が遅くなりますので、大量の計算を行う場合は不向きなこともあります。  (小さな誤差を無視できる場合ですが) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━