Domanda

Quando trovare la radice quadrata inversa di un doppio, è meglio bloccare ingressi validi non positivi a 0,0 o MIN_DBL? (Nell'esempio qui sotto double b può finire per essere negativo dovuto al punto di errori di arrotondamento e perché le leggi della fisica sono leggermente un po 'eluso nel gioco mobile.)

Sia divisione per 0,0 e MIN_DBL producono lo stesso risultato in gioco perché 1/0.0 e 1/DBL_MIN sono effettivamente infinito. Il mio intuito dice MIN_DBL è la scelta migliore, ma ci sarebbe comunque per uso 0.0? Come forse sqrt(0.0), 1/0.0 e moltiplicazione per 1.#INF000000000000 eseguiti più velocemente perché sono casi speciali.

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);

doppia divisione in MSVC:

1/0.0     = 1.#INF000000000000
1/DBL_MIN = 4.4942328371557898e+307
È stato utile?

Soluzione

Quando si tratta di matematica in virgola mobile, "infinito" e "in modo efficace l'infinito" sono molto diverse. Una volta che un numero smette di essere finito, tende a rimanere tale. Così, mentre il valore di lorentz_factor è "efficace" lo stesso per entrambi i metodi, a seconda di come si utilizza questo valore, i calcoli successivi possono essere radicalmente diverso. sqrt(lorentz_factor) per esempio resti infinito se si morsetto per 0, ma sarà effettivamente calcolato se si morsetto per alcuni molto molto piccolo numero.

Quindi la risposta dipenderà in larga misura ciò che si pensa di fare con quel valore una volta che hai bloccato esso.

Altri suggerimenti

Perché non basta INF assegnare a lorentz_factor direttamente, evitando sia la chiamata sqrt e la divisione?

double lorentz_factor;
if (b <= 0.0) 
    lorentz_factor = std::numeric_limits<double>::infinity();
else
    lorentz_factor = 1/sqrt(b);
  • Avrai bisogno di #include <limits> per questo.
  • È inoltre possibile utilizzare ::max() invece di ::infinity(), se è questo quello che vi serve.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top