in generale, operazioni in virgola mobile si tradurrà in qualche errore ULP. IEEE 754 richiede che i risultati per la maggior parte delle operazioni siano corretti entro 0,5 ULP, ma gli errori possono accumularsi, il che significa che un risultato potrebbe non essere compreso in un ULP del risultato esatto. Ci sono anche dei limiti alla precisione, quindi a seconda del numero di cifre che ci sono nei valori risultanti, potresti anche non lavorare con valori della stessa magnitudine. Anche le funzioni trascendentali sono un po 'notorious per introdurre errori nei calcoli.
Tuttavia, se si sta utilizzando GNU glibc, sqrt sarà corretto entro 0,5 ULP (arrotondato), in modo da essere esempio specifico avrebbe funzionato (trascurando NaN
, +/-0
, +/-Inf
). Sebbene sia probabilmente meglio definire un epsilon come tolleranza di errore e utilizzarlo come limite. Per exmaple,
bool gt(double a, double b, double eps) {
return (a > b - eps);
}
A seconda del livello di precisione è necessario nei calcoli, si può anche voler usare long double
invece.
Quindi, per rispondere alle vostre domande ...
a) è y * y> = x garantita usando il compilatore GCC?
Supponendo di utilizzare GNU glibc o SSE2 intrinseci, sì.
b) Funzionerà per altre operazioni come + - */o anche std :: cos() e std :: acos()?
Supponendo di utilizzare GNU glibc e una operazione, sì. Sebbene alcuni trascendentali non siano garantiti correttamente arrotondati.
c) Ci sono modi migliori per ottenere limiti superiori/inferiori?
È necessario sapere qual è la tolleranza di errore nei calcoli e utilizzarlo come epsilon (che può essere maggiore di un ULP).
Stai chiedendo questo caso specifico, o in generale per qualsiasi numero in virgola mobile? NaN rompe qualsiasi tipo di logica immediatamente. –
Per quanto posso dire lo standard non fornisce alcuna garanzia sull'implementazione '' std :: sqrt'', quindi penso che la risposta a questo dipenderà dall'implementazione. –
@ MarkB Intendo qualsiasi numero (positivo) in virgola mobile, 42 è solo un esempio. – Lux