Int関数の返り値について

解決


 2005-02-14 17:03:54  No: 119614  IP: [192.*.*.*]

Text1.Text = Int(0.1 * -50)
Text2.Text= Int(-5.0)

を実行すると

Text1.Text=-6, 
Text2.Text=-5 となります

求められる結果が違うのはなぜなのでしょうか?

編集 削除
いな  2005-02-14 17:17:38  No: 119615  IP: [192.*.*.*]

余剰加算によって生じた演算誤差が、
Intのレベルまで丸められた結果です。

演算誤差については、ネット上で調べれば見つかるかと思います。

編集 削除
ガッ…  2005-02-14 17:28:32  No: 119616  IP: [192.*.*.*]

丸め誤差だと思うから…下のような計算をしてみた。

IEEEの浮動小数点って、符号は1ビットでどこかに格納してたハズ。
よって、補数計算は必要ないと思われる。
(0.1)10進=(0.0[0011]...)2進
-(50)10進=-(110010)2進
-(5)10進=-(101)2進

-(50*0.1)10進=-(110010*0.0[0011]..)2進
 1100100
  110010
100.10110
=-(100.10110....)2進←多分

で、intは負の無限大に丸めるはずだから…どうなるんだ?
( ゜Д゜)マンドクセ…
※計算が違うかもしれない

編集 削除
id_rsa++  2005-02-15 06:26:03  No: 119617  IP: [192.*.*.*]

ただのバグだと思うが・・・・(@o@)

編集 削除
ガッ  2005-02-15 07:30:50  No: 119618  IP: [192.*.*.*]

思いつきだが、
debug.? (-5.0)\1,(-50*0.1)\1
で上手く計算される。
…この二つに関しては(ぇ

編集 削除
ひろ  2005-02-15 10:23:00  No: 119619  IP: [192.*.*.*]

数学の世界では
 (A + B) + C = A + (B + C) = (A + C) + B
 (A - B) + C = A + (C - B) = (A + C) - B
 (A * B) / C = A * (B / C) = (A / C) * B (ただし C は 0 ではない)

は必ず成り立ちますが、コンピュータ内での実数演算では、丸めの関係で、これらの法則が成立しない場合があります。

数値計算の世界では丸め誤差を最小限に抑え込む計算順序を考えるのもテクニックの内です。

編集 削除
Dental  2005-02-15 10:53:09  No: 119620  IP: [192.*.*.*]

浮動小数点演算誤差を避けるには、固定小数点演算を使いましょう。
  Text1.Text = CStr(Int(0.1@ * -50@))
  Text2.Text = CStr(Int(CDec("0.1") * CDec("-50")))
などであれば、誤差が発生しません。

浮動小数点型の場合、コンパイルモードによって結果が変わる事もあります。
    Text1.Text = CStr(Int(0.1 * -50))
ってコードで実行したら、
  P-Codeコンパイル時       → 「-6」
  最適化無しコンパイル時   → 「-6」
  速度最適化コンパイル時   → 「-5」
  サイズ最適化コンパイル時 → 「-5」
という結果になりました。


なお、一度変数に入れると(今回の場合は)大丈夫みたい。

Debug.Print TypeName(0.1 * -50)    '→ "Double"

D = 0.1 * -50
Debug.Print Int(D)                 '→ "-5"
Debug.Print Int(0.1 * -50)         '→ "-6"
Debug.Print Int(CDbl(0.1 * -50))   '→ "-5"

編集 削除
 2005-02-16 09:18:22  No: 119621  IP: [192.*.*.*]

コンピュータで少数を扱う場合、必然的に誤差を生じる。
基本的な事が分かっていませんでした。。。。
誤差が生じる事を前提に書くことをしないといけませんね。

編集 削除