Trunc関数について

解決


たなか  2011-04-01 14:41:44  No: 40380  IP: 192.*.*.*

単純な質問なのですが
var
  iSuryoKei: Integer;
  dblSuryoKei: Double;
begin
  iSuryoKei := Trunc(dblSuryoKei);
  dblSuryoKeiが1の場合は、iSuryoKeiも1になりますよね。

デバックしているとiSuryoKei = 0 になってしまいます。
これってどういうことでしょうか?

編集 削除
monaa  2011-04-01 16:14:37  No: 40381  IP: 192.*.*.*

デバッグは詳しくありませんが、
変数というのは不要になれば破棄されますし、
そもそも使われていなければコンパイラに無視されます。
結果が間違ってなければ気にする問題ではないです。

編集 削除
たなか  2011-04-01 16:22:36  No: 40382  IP: 192.*.*.*

下記のようなに実際に使っています

Edit1.Text := 5;
Edit2.Text := 1;
Edit3.Text := 1;
Edit4.Text := 1;
Edit5.Text := 1;
Edit6.Text := 1;
この場合は、Edit7.Text := 0;

Edit1.Text := 1;
Edit2.Text := 1;
Edit3.Text := 1;
Edit4.Text := 1;
Edit5.Text := 1;
Edit6.Text := 5;
この場合は、Edit7.Text := 1;
いったいどういう事なんでしょうか?


[検証ソース]
var
  i: Real;
begin
  i := StrToInt(Edit1.Text) * 0.1;
  i := i + StrToInt(Edit2.Text) * 0.1;
  i := i + StrToInt(Edit3.Text) * 0.1;
  i := i + StrToInt(Edit4.Text) * 0.1;
  i := i + StrToInt(Edit5.Text) * 0.1;
  i := i + StrToInt(Edit6.Text) * 0.1;
  Edit7.Text := IntToStr(Trunc(i));

編集 削除
monaa  2011-04-01 18:20:01  No: 40383  IP: 192.*.*.*

浮動小数の誤差です。
その用途だとRound()を使ってください。
どうしてもTrunc()を使いたい場合があると思いますが、そういう時は
r := r + 0.000000000001;
と自分の扱う計算精度の限界より小さい値を変換直前に加えるという手もあります。

浮動小数の計算精度については色々なところで解説されてますのでググッてください。
http://www.cc.kyoto-su.ac.jp/~yamada/programming/float.html
ちなみに、変数iは通常、整数(Integer)のiですんで他の人が読むと混乱します。

編集 削除
たなか  2011-04-06 13:54:27  No: 40384  IP: 192.*.*.*

どうしても誤差がでるようなので
小数は10倍し整数で処理するようにします。

編集 削除
tor  2011-04-06 16:28:51  No: 40385  IP: 192.*.*.*

小数点以下4桁までの精度しか必要としないなら、Currency型を使えば誤差は出ませんよ。

編集 削除