2016-04-26 22 views
5

Ho il seguente programma:Qual è il risultato del confronto tra doppio e NaN?

#include <iostream> 
#include <cmath> 

int main() { 
    double a = 1; 
    double b = nan(""); 

    std::cout << (a > b) << std::endl; 
    std::cout << (b > a) << std::endl; 

    return 0; 
} 

uscita:

0 
0 

In generale dal significato di nan-not a number è chiaro che qualsiasi operazione con nan è essenzialmente inutile. Da IEEE-754 che ho trovato in Internet ho trovato che se in FPU almeno uno degli operandi è nan il risultato è anche nan, ma non ho trovato nulla sul confronto tra il valore normale e nan come nell'esempio sopra.

Che cosa dice lo standard al riguardo?

+1

Le funzioni della FPU e il risultato logico di un confronto sono probabilmente due cose diverse. Cosa dice il tuo smontaggio? – tadman

+0

Il tuo codice potrebbe (o potrebbe non) mancare un confronto '=='. Hai controllato per '<' and '>' ma non per '=='. Forse intendevi usare '<' and '> =' o '<=' and '>'. – jotik

risposta

7

Che cosa dice lo standard al riguardo?

Lo standard C++ non indica come si comportano le operazioni sui NaN. Non è specificato. Quindi, per quanto riguarda il C++, qualsiasi risultato è possibile e permesso.

ANSI/IEEE Std 754-1985 dice:

5,7. Confronto

... Ogni NaN deve comparare non ordinato con tutto, incluso se stesso. ...

Nei ordinata mezzi esattamente è mostrato nella tabella 4 nella stessa sezione. Ma in breve, ciò significa che il confronto deve restituire falso, se uno qualsiasi degli operandi è NaN, eccetto != deve restituire true.

+0

Probabilmente non l'ho letto abbastanza bene. Grazie! – Alex

1

0 qui significa falso. Nan non è uguale o paragonabile a nessun valore, quindi il risultato dell'operazione è falso (0).

+0

Quello che dici è piuttosto logico, ma puoi dare qualsiasi riferimento dove è definito. – Alex

2

Lo 0 che stai vedendo significa false in questo caso poiché è quello che lo stream mostra falso per impostazione predefinita. Se volete vedere come true o false uso std::boolalpha:

std::cout << std::boolalpha << (a > b) << std::endl; 

siero di confrontare i valori a virgola mobile in cui uno dei valori è nan poi x<y, x>y, x<=y, x>=y e x==y saranno tutti valutare false, mentre x!=y sarà sempre vero. Andrew Koenig ha un buon articolo su questo sul sito web Dr Dobbs.

Quando ci si pensa, il risultato non può essere nan poiché gli operatori di confronto devono restituire un valore booleano che può avere solo 2 stati.

+0

Potete fornire qualsiasi riferimento dove questo comportamento è definito (intendo operazione di confronto tra NaN e qualsiasi altro valore normale)? – Alex

+0

@Alex - Ho fornito un collegamento a un articolo – Sean

0

Bene, sopra @ user2079303 risposta abbastanza buona, ci sono due NaN: NaN silenzioso e segnalazione NaN. È possibile controllare std::numeric_limits<T>::has_signaling_NaN sulla propria piattaforma e segnalare che NaN è disponibile.Se è vero e valore contiene std::numeric_limits<T>::signaling_NaN, quindi

Quando una segnalazione NaN viene utilizzato come argomento un'espressione aritmetica, l'eccezione a virgola mobile appropriata può essere sollevato e la NaN è "acquietato", cioè, l'espressione restituisce un NaN silenzioso.

Per ottenere veramente un'eccezione FP è possibile impostare la parola di controllo FPU (per unità x87) o il registro MXCSR (per unità SSE2 +). Questo è vero per la piattaforma x86/x64, controlla i documenti della tua piattaforma per funzionalità simili

Problemi correlati