1

高さ 1:高さ 2 の比率 0.98 を使用して、単純な振り子のスイング減衰を計算する単純な再帰関数があります。

この関数の基本ケースは 0.0 ですが、何らかの理由で無限の自己呼び出しになります!

誰かが私が欠けているものを見つけることができますか?

コード:

float swingDecay (float value) {


     if ( value == 0.00 ) {
          return value;
     }

     else { 
          return swingDecay (value * 0.98);  }     
}

mIL3S www.milkdrinkingcow.com

4

8 に答える 8

6

浮動小数点計算では常に「概算」比較を使用する必要があります。たとえば、if (abs(value) < EPS)代わりにif ( value == 0.00 ). EPSこれは小さな定数です (要件とデータ型によって異なります)。

これが実際に起こっていることだと思います。1 * 2^(-10000)(10000 は私の頭のてっぺんから来る) のように、データ型で可能な最小の正の値に到達し、 now value * 0.98 = value. たとえば、 に0または に丸める必要がtotalあり、0.98*total明らかに に近くなりtotalます。
しかし、それは憶測にすぎません。浮動小数点計算では、確信が持てません:)

于 2011-01-07T18:32:22.447 に答える
4

浮動小数点演算では浮動小数点計算が正確ではないため、値 == 0.00 になることはありません。value < 0.0000001 のようなものを試して、それが機能する場所で微調整したい場合があります。

于 2011-01-07T18:32:27.140 に答える
2

浮動小数点数を直接比較しないでください。あなたの「値」はおそらく実際には 0.0 (ゼロ) にはなりません。

次のようなことをしてください:

float smallNumber = 0.00001;
if ( value < smallNumber )
{
...
}
于 2011-01-07T18:32:51.100 に答える
2

(値 == 0.00)

真実になることはありません。または、関数を何度も実行する必要があるため、スタックオーバーフローが発生します:P 関数の作成方法をもう一度確認する必要があります。今のところ、それは役に立ちません。0 しか返せません。

于 2011-01-07T18:33:58.620 に答える
1

if (value * 0.98 == value)の代わりに確認できif (value == 0)ます。この条件は、 が非常に小さい (非正規) 場合に正確に満たされ、異なる結果を得るvalueために乗算する精度のビットが少なすぎます。0.98

于 2011-01-07T19:05:04.027 に答える
0

うわー、みんなクイックアンサーありがとう!

どうやら私のクラスではその小さな浮動小数点の詳細がスキップされたようです...だから誰もがほとんど同じことを言っているので(浮動小数点は実際には正確ではないので平等と比較しないでください)、私が使用した場合も同じことが当てはまりますintsまたはdoubles?

もともと私は(値<= 0.0)のようにテストをしましたが、それでも同じことがわかりました。

テストを<=0.005として実行しただけで、問題ないように見えました。

皆さんありがとう!

mIL3S

www.milkdrinkingcow.com

于 2011-01-07T18:52:49.407 に答える
0

これを使用します(2桁の精度を目指しているようです。

if (value < 0.001 )

浮動小数点値には等値を使用しないでください。

于 2011-01-07T18:33:48.247 に答える
0

浮動小数点値を定数と比較しないでください。それらが下限を下回っているかどうかを常に確認してください。たとえば、値 == 0.00 を値 <= 0.0001 に変更します

于 2011-01-07T18:35:28.337 に答える