2

ダブルの逆平方根を見つけるとき、0.0またはMIN_DBLで無効な非正の入力をクランプする方が良いですか? (以下の私の例でdouble bは、浮動小数点の丸め誤差と、ゲーム内で物理法則がわずかに曖昧であるために、負になる可能性があります。)

0.0による除算とMIN_DBLはどちらも、ゲームで同じ結果を生成します。これは1/0.0、と1/DBL_MINが事実上無限であるためです。私の直感では、MIN_DBLの方が適していると言われていますが、0.0を使用する場合はありますか?おそらくのようsqrt(0.0)に、そしてそれらは特殊なケースであるため1/0.0、乗算はより速く実行されます。1.#INF000000000000

double b = 1 - v.length_squared()/(c*c);

#ifdef CLAMP_BY_0
if (b < 0.0) b = 0.0;
#endif

#ifdef CLAMP_BY_DBL_MIN
if (b <= 0.0) b = DBL_MIN;
#endif

double lorentz_factor = 1/sqrt(b);

MSVCでの二重除算:

1 / 0.0 = 1.#INF000000000000
1 / DBL_MIN = 4.4942328371557898e + 307
4

2 に答える 2

2

浮動小数点演算を扱う場合、「無限大」と「事実上無限大」はまったく異なります。数が有限でなくなると、その状態が続く傾向があります。したがって、の値はlorentz_factor両方の方法で「効果的に」同じですが、その値の使用方法に応じて、後の計算は根本的に異なる可能性があります。 sqrt(lorentz_factor)たとえば、0にクランプすると無限になりますが、非常に小さい数にクランプすると実際に計算されます。

したがって、答えは、クランプした後でその値を使用して何を計画しているかに大きく依存します。

于 2010-05-25T07:37:30.297 に答える
0

呼び出しと分割の両方を避けINFlorentz_factor、直接割り当てるのはなぜですか?sqrt

double lorentz_factor;
if (b <= 0.0) 
    lorentz_factor = std::numeric_limits<double>::infinity();
else
    lorentz_factor = 1/sqrt(b);
  • これを行う必要があります#include <limits>
  • ::max()必要に応じて、の代わりに使用することもでき::infinity()ます。
于 2010-05-25T07:25:38.487 に答える