困ったことが起きてます・・・・
Dim 下代 as Long
Dim 上代 as Long
Dim Rate As Long
'掛率58の場合
Rate = ItemTextBox(0).Text
' 上代5700円×掛率58%の場合の下代は3306円
【1】下代 = CInt((上代 * (Rate * 1 / 100)))
【2】下代 = Fix((上代 * (Rate * 1 / 100)))
【1】の答えが3306
【2】の答えが3305 になってしまいます。
【1】はコメント行にしてて
ずーっと【2】でプログラムを運営してました。
ある日、上代が5700円の場合下代が正しく入らないことに気づきました。
fixとCintの違いを調べなおしました。
http://park5.wakwak.com/~weblab/refFixInt.html
負の数はRateに入りません。
少数になった場合は切り捨てしたいのです。
しかも、2回目このルーチンに入ると【2】は3306円になります????
Fixではなくて、Cintで、いいのでしょうか?
> 【1】下代 = CInt((上代 * (Rate * 1 / 100)))
> 【2】下代 = Fix((上代 * (Rate * 1 / 100)))
うーん。幾つか問題があるような。
# とりあえず、括弧の数が余計なのは無視するとして。
(1) 変数名について
旧 VB においては、日本語の変数名は基本的に NG です。
http://support.microsoft.com/kb/418924
現 VB においては、日本語の変数名も許可されています。
http://support.microsoft.com/kb/921451
とりあえず今回は、.NET 開発であるものと仮定して回答します。
(2) 演算処理とデータ型について
除算演算子「/」による計算結果は、「浮動小数点型」の値となります。
(結果が浮動小数とならない唯一の例外は、Decimal 型を対象にした場合です)
浮動小数点型はその特性上、誤差を含みやすい型であり、金額計算には向きません。
たとえば、0.1 や 0.3 といった値の保持には、僅かな誤差を生じますので御注意を。
# 内部 2 進数で保持される関係上、0.5 や 0.25 などといった値ならば問題が無いのですが。
(3) 使用している関数とデータ型について
Rate変数(Long型)に、Textプロパティ(String型)を入れている点には目を瞑るにしても…。
【1】の CInt は「型変換関数」であり、結果を Integer 型にします。
しかし、変数[下代]は Long 型です。両者の型が一致しないので、適切なコードとはいえないでしょう。
CLng を使うか、[下代]を Integer にするべきかと。
ちなみに、Int 関数や Fix 関数は、型の変換は行いません。
先の(2)にも書いたように、今回の演算式は Double 型の値を返しますので、
【2】の場合、Fix しても、その結果は Double 型のままとなっています。
> ずーっと【2】でプログラムを運営してました。
運営 → 運用、かな。
> 負の数はRateに入りません。
……?
もしかして、Int 関数と CInt 関数を混同していたりはしませんか?
> Fixではなくて、Cintで、いいのでしょうか?
どちらも NG です。
そもそも、演算途中で Double 型が使われてしまっているため、
計算結果自体が、ごく僅かな誤差を含んだ値になっています。(この時点で既に手遅れです)
誤差を含んだ値に対して丸め/切捨てを行ったところで、1円程度の誤差が
含まれてしまう可能性は出てきてしまいます。
この場合は、誤差を含まないよう、演算値をすべて Decimal 型に統一するとか、あるいは、
数式を見直して、除算無しの整数演算だけで済ませるなどの対策が必要です。
丸めの問題はその後の話。
お世話になります。
私、基本がなってないような・・・魔界の仮面弁士 さまのカキコミを
1行1行理解していきたいと思います。
ちなみにVB6.0 SP?←最新 です。
ツイート | ![]() |