2015-04-17 16 views
8

Cosa restituisce sys.float_info.epsilon?Python epsilon non è il numero più piccolo

Sul mio sistema ottengo:

>>> sys.float_info.epsilon 
2.220446049250313e-16 
>>> sys.float_info.epsilon/2 
1.1102230246251565e-16 
>>> 0 < sys.float_info.epsilon/2 < sys.float_info.epsilon 
True 

Come è possibile?

EDIT:

stai bene, ho pensato epsilon fa quello che fa min. Quindi in realtà intendevo dire sys.float_info.min.

EDIT2

tutti e soprattutto John Kugelman, grazie per le vostre risposte!

Alcuni suonare in giro che ho fatto a chiarire le cose a me stesso:

>>> float.hex(sys.float_info.epsilon) 
'0x1.0000000000000p-52' 
>>> float.hex(sys.float_info.min) 
'0x1.0000000000000p-1022' 
>>> float.hex(1 + a) 
'0x1.0000000000001p+0' 
>>> float.fromhex('0x0.0000000000001p+0') == sys.float_info.epsilon 
True 
>>> float.hex(sys.float_info.epsilon * sys.float_info.min) 
'0x0.0000000000001p-1022' 

Così epsilon * min dà il numero con il più piccolo significando positivo (o mantissa) e il più piccolo esponente.

risposta

3

epsilon è la differenza tra 1 e il successivo float rappresentabile. Non è la stessa cosa del float più piccolo, che sarebbe il numero più vicino a 0, non 1.

Ci sono due carri più piccoli, a seconda dei criteri. min è il più piccolo float normalized. Il più piccolo float subnormal è min * epsilon.

>>> sys.float_info.min 
2.2250738585072014e-308 
>>> sys.float_info.min * sys.float_info.epsilon 
5e-324 

nota la distinzione tra carri normalizzati e subnormali: min non è in realtà il più piccolo galleggiante, è solo il più piccolo con piena precisione. I numeri subnormali coprono il range compreso tra 0 e min, ma perdono molta precisione. Si noti che 5e-324 ha solo una cifra significativa. I subnormali sono anche molto più lenti con cui lavorare, fino a 100 volte più lenti dei galleggianti normalizzati.

>>> (sys.float_info.min * sys.float_info.epsilon)/2 
0.0 
>>> 4e-324 
5e-324 
>>> 5e-325 
0.0 

Questi test confermano che 5e-324 è veramente il più piccolo galleggiante. Dividendo per due underflow a 0.

Vedere anche: What is the range of values a float can have in Python?

+0

Il mio esempio funziona allo stesso modo per sys.float_info.min invece di sys.float_info.epsilon ovunque. Come lo spieghi? –

+0

Qualunque cosa più piccola di 'min' è subnormale. 'min * epsilon' è il vero float più piccolo. Se lo dividi per 2, porta a 0. –

0

L'ultima espressione è possibile, perché per qualsiasi numero reale, positivo, 0 < num/2 < num.

Da the docs:

differenza tra 1 ed il minimo valore maggiore di 1, che è rappresentabile come float

0

sys.float_info è definito come

differenza tra 1 e il valore minimo maggiore di 1 è rappresentabile come float

su this page.

1

In realtà si desidera sys.float_info.min ("minimo positivo normalizzato float"), che sulla macchina mi dà .2250738585072014e-308.

epsilon è:

differenza tra 1 ed il minimo valore maggiore di 1, che è rappresentabile come float

Vedere la docs per maggiori informazioni sui campi di sys.float_info.

+0

'min' still non è ancora il più piccolo float positivo; ci sono ancora delle subnormali sotto di esso. – user2357112

+0

Grazie, hai ragione, ma come spieghi cosa ha detto @ user2357112? –

+1

I float dei subnormali significano che il numero ha zeri nel suo significato e; Penso che @John Kugelman abbia la risposta migliore a questo punto: lo accetterei se funzioni per te, altrimenti posso aggiornarlo se non lo fa. – Isaac

0

I documentation definisce sys.float_info.epsilon come differenza

tra 1 ed il minimo valore maggiore di 1, che è rappresentabile come float

Tuttavia, il divario tra galleggianti successive è più grande per carri grandi , quindi il divario tra epsilon e il successivo float più piccolo è molto più piccolo di epsilon. In particolare, il successivo float più piccolo non è 0.

0

Come ogni risposta dice, è la differenza tra 1 e il successivo valore più grande che può essere rappresentato, se si è tentato di aggiungere la metà di esso a 1, si otterrà 1 torna

>>> (1 + (sys.float_info.epsilon/2)) == 1 
True 

Inoltre, se si tenta di aggiungere due terzi di essa per 1, si otterrà lo stesso valore:

>>> (1 + sys.float_info.epsilon) == (1 + (sys.float_info.epsilon * (2./3))) 
True 
Problemi correlati