Il tipo "float" di Python e il tipo "doppia precisione" di PostgreSQL sono basati sulla stessa implementazione C? Che non può essere il vero problema di fondo qui, ma in ogni caso, ecco cosa ottengo quando provo a manipolare i piccoli numeri in entrambi gli ambienti:Numeri in virgola mobile di Python "float" e PostgreSQL "doppia precisione"
su Python (2.7.2 GCC 4.2.1, se questo è rilevante):
>>> float('1e-310')
1e-310
su PostgreSQL (9.1.1):
postgres# select 1e-310::double precision;
ERROR: "0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001" is out of range for type double precision
quello che ho capito è che Python tipo float "gestisce" 1e-310, mentre PostgreSQL tipo double precision non lo fa. Entrambi i documenti Python e PostgreSQL su, rispettivamente, tipi "float" e "doppia precisione", si riferiscono allo standard IEEE 754, che dovrebbe essere implementato su "la maggior parte delle piattaforme" (sono su OS X Lion 10.7.3) .
Qualcuno potrebbe spiegare cosa sta succedendo qui? E dammi una soluzione, mi piacerebbe ad esempio "ridurre" la precisione di Python così posso inserire float nel mio database attraverso un Django FloatField. (Il caso di utilizzo completo è che sto leggendo le figure da un file e quindi inserendole).
Alcuni (forse interessante) informazioni aggiuntive, in Python:
>>> sys.float_info
sys.float_info(max=1.7976931348623157e+308, max_exp=1024, max_10_exp=308, min=2.2250738585072014e-308, min_exp=-1021, min_10_exp=-307, dig=15, mant_dig=53, epsilon=2.220446049250313e-16, radix=2, rounds=1)
>>> 1e-320.__sizeof__()
24
Io davvero non si ottiene il secondo.
avrei speculare che Postgres si rifiuta di dammelo perché .1 non può essere rappresentato esattamente in binario (per la mantissa). – bdares
@bdares Non sono sicuro di aver capito. msgstr "seleziona 1e-100 :: doppia precisione;" funziona bene a Postgres; e non penso che questo sia un problema di esattezza, ma piuttosto uno di precisione – Arthur