<HOME  <お願い事項   <Access2002 TOP   <Access97 TOP   <サイト内検索
 MS-Access2000超入門部屋--「関数」ってなんだ?四捨五入



■切り捨てと四捨五入と小数点以下の数値の扱い

部屋とワイシャツとわたし〜♪(寒)

と、冗談は置いといて、結構これって難しいのです。
難しいっていうのは、「四捨五入」っていうのがわたしたちの都合により発生するリクエストであるということと、まずコンピュータというものの中で数値の精度を保つってことがすごく難しいっていうことなんです。
コンピュータは・・・切り捨てしてくれいって思うんじゃないですかねぇ・・・。
四捨五入をするためのRound関数という関数もあるにはあるんですが・・・実は使ったことないんです。そういう関数があるならその方がいい、という方は、ヘルプでRound関数の使い方探してみてください。ここではそれ以外の方法をお話しますね。


まず、MS-Accessで扱うことのできる数値の種類についてちょっとだけ・・・。
こんなテーブルを作ったとします↓。
3行目の「タイム」というフィールドを数値型にして、フィールドプロパティ欄の「フィールドサイズ」というところを見てください。



多分、Accessの設定等を変えてなければデフォルトは「長整数型(Long)」になっていると思います。
で、この他に、「バイト型(Byte)」「整数型(Integer)」「通貨型(Currency)」「単精度浮動小数点型(Single)」「倍精度浮動小数点型(Double)」があります。「レプリケーションID型」と「十進型」っていうのもありますけど、これはちょっと特殊かもしれないですね。
で、それぞれのデータ型をヘルプで見てみましょう。「フィールドサイズ」という欄のところにカーソルを置いて、F1キーを押してください。「フィールドサイズ」というプロパティに関するヘルプが出てきます。

あ、よけいなお話かもわかんないですが、たまに「小数点以下の数字が表示されないんです」っていう質問もらうこともあるんですけど・・・。
多分、ふつうに数値型のフィールド設けただけだと、通常は「長整数型」というフィールドサイズになってると思います。
長整数型は、小数点以下の値持たないデータ型ですので(下の表参照)、小数点以下の値を持つことができるタイプのフィールドサイズに変更する必要がありますよ。

で、その「フィールドサイズ」ってやつですが、ヘルプから丸写ししてきました。

 
設定値 内容 小数の精度 記憶領域サイズ
Byte バイト型 0 〜 255 の範囲の数値が設定できます。ただし、小数は設定できません。 なし 1 バイト
Decimal 十進型 -10^38 -1 〜 10^38 -1 の範囲の数値が設定できます。(.adp)
-10^28 -1 〜 10^28 -1 の範囲の数値が設定できます。(.mdb)
28 12 バイト
Integer 整数型 -32,768 〜 32,767 の範囲の数値が設定できます。ただし、小数は設定できません。 なし 2 バイト
Long 長整数型 -2,147,483,648 〜 2,147,483,647 の範囲の数値が設定できます。ただし、小数は設定できません。(既定値) なし 4 バイト
Single 単精度浮動小数点型 負数については、-3.402823E38 〜 -1.401298E-45 の範囲の数値が設定できます。正数については、1.401298E-45 〜 3.402823E38 の範囲の数値が設定できます。 7 4 バイト
Double 倍精度浮動小数点型 負数については、-1.79769313486231E308 〜 -4.94065645841247E-324 の範囲の数値が設定できます。正数については、1.79769313486231E308 〜4.94065645841247E-324 の範囲の数値が設定できます。 15 8 バイト
ReplicationID
レプリケーション ID 型
GUID (Globally Unique Identifier) なし 16 バイト

この他に、「通貨型」というデータ型もあります。

Currency 通貨型 小数点以下 1 桁から 4 m:桁までのデータを含む、数値計算で使用される通貨の値および数値データが格納されます。小数点以上が 15 桁、以下は 4 桁の精度です。 8 バイト。

「小数の精度」っていうのがありますが・・・。
Access だけの問題ではないんですが、コンピュータ業界の永遠のテーマ・・・小数点以下の桁を複雑に持つ場合、「誤差が生じる」ことがあるのです。
これは・・・いわゆる、コンピュータの頭脳「CPU」の能力に関係してきます。

コンピュータの中って、全部「2進数」っていう方法で情報がやり取りされるんです。それをいっぱいがんばって10進数っていう形にして画面に出してくれてます。でも、悲しいかな、いっぱいがんばってもちょっぴり誤差が生じちゃったりするんです。
割り算とか引き算とか掛け算とか繰り返しているうちに、ほんとうは1なのに0.999になっちゃったり・・・。そんなことがおこらないように、小数点以下の数値が発生しても注意するようAccessに気をつけてもらいます。これを「少数の精度」といいます。数値型のフィールドにはそれぞれ、小数点以下何桁まで気をつけるのか、という「有効桁数」が定められていて、その範囲での数値の正確さを保つよう努力をするんです。あ、でも、有効桁数を超えたからって急に間違えるわけじゃないんですよ。それに、普通に入力する分にはぜんぜんオッケーなんです。割ったり掛けたり計算した結果、値に誤差が生じるって可能性が少しある、っていう感じです。

小数点以下の桁数って、表現しようと思えば何百桁だって取れますよね。でも、小数点以下の数値は発生しないかも・・・。100m走の結果を記録するとき、全員が5秒とか6秒とかどんぴしゃりなタイムを出すかもしれないし、12.05487秒とか11.054900157秒とか1.09秒とか、小数点以下の桁数がばらばらに発生する可能性もある。こういうのを「浮動小数点」っていいます。かなり自由に数値を扱うことができる代わりに、精度を保つのが大変なんですね。

「小数点の位置でそろえて書いてみると、右側の桁数が一定ではなく、右端がそろわない」ようなタイプの数値型、というわけです。

同じ数値型でも、長整数型(Long)とか、あるいは通貨型(Currency)だと、小数点以下の桁数は決まってますけど、その分あらかじめコンピュータが心積もりしておくことができるので、誤差が生じない、ということなのかもしれないですね。

「誤差が出る」とえらそうに言われてもむかつくんですけど、こればかりはどうしようもないみたい。

まあ、多分、日ごろちょっと扱うような数字どうしの計算とかなら、誤差が生じるなんてことはないかもしれませんけれど、必要もないのにDouble型のフィールドを設けるのは、あまり望ましいことではないかもしれませんね。
小数点以下の桁数は3桁くらいまであればいいな、という場合は、「通貨型(Currency)」になさるのがよいかもしれませんね。こういうのは数値型のフィールドの扱いに慣れてらっしゃれば問題ないかもしれないんですが、Currency の方が安心かもしれません。

Accessのヘルプの中にも、
小数点以下1 〜4桁のデータを何度も計算するようなフィールドは、通貨型(Currency) を使用してください。単精度浮動小数点型および倍精度浮動小数点型のフィールドに対しては、浮動小数点演算が行われます。通貨型フィールドの場合は、固定小数点演算が行われ処理速度が向上します。
という記述がありますので・・・。内部的にも、ケースバイケースでデータの型を使い分けることが望ましいみたいです。

数値ってね、扱いがいろいろ難しいんですよ・・・クエリとかテーブルとかの中で扱ってるだけならたいして気にすることもないと思うんですけど、VBA でコードを書いて処理を作るとかそういう場合は、データ型についていろいろ承知しておかないとならないかもしれないですね。。。

と、横道にそれてしまいましたが、Double型を率先して使うとその辺心配なさる方もいらっしゃいます。いちおう頭の中に入れておいてください。



さて、数値型にもいろいろあるんだ、ということをちょっと頭に入れていただいて・・・。
こんな感じのテーブルがあったとします。

で、このテーブルを基にしたクエリを作って、ピンクの四角のところに、四捨五入をする式を作ってみようと思います。



MS-Accessには、Int関数とFix関数という関数があります。
ちょっとヘルプ見てみましょうか。どっちも、小数点以下を取り除く(切り捨てる)という意味合いの関数になります。

違いは、負の数(マイナスの値)のときですね。
使用例を見ると載ってますけど、


 Int(99.8)   99 を返します。
 Fix(99.2)   99 を返します。

 Int(-99.8)   -100 を返します。
 Fix(-99.8)   -99 を返します。

 Int(-99.2)   -100 を返します。
 Fix(-99.2)   -99 を返します。

となります。



んじゃ、こんなふうに入力してみると・・・。

整数部分だけ残って、あとは切り捨てられます。



んじゃ、四捨五入はどうしたら・・・???
Int関数するまえに0.5足しといたらどうでしょう???0.5足してから切り捨てれば、

0.1 + 0.5 = 0.6 ←答えをInt  0
0.4 + 0.5 = 0.9 ←答えをInt  0
0.5 + 0.5 = 1.0 ←答えをInt  1
0.9 + 0.5 = 1.4 ←答えをInt  1

なんか、いけそうじゃないですか?

どうでしょう。それっぽいでしょ。



んじゃあ、「小数点以下2桁めで四捨五入」とかする場合はどうしたらいいんでしょう・・・。

もし、見てくれだけの問題なら、書式で整えちゃうって手もあります。
Format関数を使って

としてやると、

と、まあ、何とかなります。これでもいいと思いますよ。

書式のパターンで、「0」を指定すると、数字をうまく丸めて四捨五入してくれます。”#.00”だと、小数点以下3桁の数字を四捨五入して小数点以下2桁までを表示するってことになります。正確には捨てられてはいないんですけどね。
でも・・・左に寄ってるんでおわかりになると思いますが・・・文字扱いですね。これじゃ後々いろいろ支障が・・・という場合もありますかねぇ。



さっきのIntまたはFix関数をうまく使ってできないもんでしょうかね。

ためしに100掛けてみましょうか。



式1: [タイム]*100

と、こうなります。この状態で0.5足してからIntすれば・・・。


式1: Int(([タイム]*100)+0.5)

小数点以下の部分で四捨五入されますよね。

で、割ったらどうでしょう。


式1: Int(([タイム]*100)+0.5)/100

なんか、いけそうじゃないですか???

小数点以下3桁で四捨五入、っていうことなら

式1: Int(([タイム]*1000)+0.5)/1000

ってやれば

どうでしょう。いけそうでしょうか???

あと、最初にちょっとだけお話したFormat関数を使った方法で、例えば、

式2: Format([タイム],"0.000")

で出してみると・・・。

でも、式2の列を見ると・・・数字、左によってますよね。
これはなぜかというと、Format関数というのは、単に「書式を整える」ための関数ですので、返ってくる答えは「文字扱い」になるのです。
まあ、この後計算したり、この値を元に検索したりとか、そういうことをせず、単に「結果が表示されればよい」だけなら、ツールバーの「右揃え」ボタンで右へ寄せれば数字っぽく見えますのでそれでもよいかもしれません。
もし、「数値」としての扱いをする必要がある場合は・・・。

式2: Val(Format([タイム],"0.000"))

という感じで、Val関数という関数で囲み、妥当なデータ型に変換してもらいましょう。


単に「四捨五入」といっても、どういうふうに四捨五入するかによってやりかたも考え方もいろいろなんです。
なので、数値の扱いがどうなっているのかなど、そうしたことを少し把握しておいた方がよいかもしれないですよね。
あとは、数値を扱う関数をいくつか知っておくこと・・・そのあたりが、四捨五入を実現する鍵になりそうです。



(オシマイ)