2015-01-02 37 views
34

In Python nativo, senza usare NumPy (per cui numpy.nan != numpy.nan) non c'è NaN, quindi ho ragione nel pensare che il punto mobile di Python == è riflessivo? Poi dal momento che è simmetrica (a == b implica b == a) e transitiva (se a==b e b==c poi a==c), possiamo dire che di Python == è una relazione di equivalenza sui float s?Python == è una relazione di equivalenza sui float?

EDIT: OK, così ho imparato che ci è un NaN: float('nan') (grazie @unutbu) che si propagano attraverso varie operazioni, ma non qualsiasi metodo Python nativo restituirlo (piuttosto che aumentare un'eccezione) senza di me l'introduzione da questo incarico?

+0

Non lo sapevo: grazie. 'Nan 'è effettivamente restituito da qualsiasi operazione Python nativa (invece di un'eccezione che viene sollevata)? – xnx

+8

@xnx: '1e400/1e400' restituisce' nan'. –

+0

Vedere anche [PEP 754] (https://www.python.org/dev/peps/pep-0754/) per ulteriori informazioni su questo. –

risposta

45

== è riflessiva per tutti i numeri, pari a zero, -Zero, ininity, e -infinito, ma non per nan.

È possibile ottenere inf, -inf e nan in Python nativo solo mediante operazioni aritmetiche su valori letterali, come di seguito.

questi si comportano in modo corretto, come in IEEE 754 e senza eccezioni dominio matematica:

>>> 1e1000 == 1e1000 
True 
>>> 1e1000/1e1000 == 1e1000/1e1000 
False 

1e1000 è un numero molto grande, in modo da galleggiare e doppio rappresentarlo come un infinito.

  • infinito è uguale a infinito
  • infinito diviso per l'infinito non è un numero
  • non un numero! = Non un numero

-virgola mobile aritmetica in Python funziona anche bene per l'infinito meno infinito ecc .:

>>> x = 1e1000 
>>> x 
inf 
>>> x+x 
inf 
>>> x-x 
nan 
>>> x*2 
inf 
>>> x == x 
True 
>>> x-x == x-x 
False 
>>> 

e per il caso zero e meno di zero:

>>> inf = float("inf") 
>>> 1/inf 
0.0 
>>> -1/inf 
-0.0 
>>> -1/inf == 1/inf 
True 
>>> 
+2

Per completezza, potrebbe essere utile includere la (breve) lista di assiomi che crea una relazione di equivalenza. Inoltre, non si dice mai esplicitamente che non si tratti di una relazione di equivalenza, si dice semplicemente che non è riflessivo per 'nan'. – Logan

34

float('nan') esiste in Python nativo e float('nan') != float('nan'). Quindi no, non è un ==equivalence relation dal momento che manca riflessività:

In [40]: float('nan') == float('nan') 
Out[40]: False