2012-03-04 96 views
6

Python的「float」類型和PostgreSQL的基於相同C實現的「雙精度」類型?這可能不是真正的潛在的問題在這裏,但無論如何,這裏就是我得到的,當我嘗試在兩種環境下操縱小的數字:Python「float」和PostgreSQL「雙精度」的浮點數

關於Python(2.7.2 GCC 4.2.1,如果是相關的):

>>> float('1e-310') 
1e-310 

在PostgreSQL上(9.1.1):

postgres# select 1e-310::double precision; 
ERROR: "0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001" is out of range for type double precision 

我的理解是,Python的浮子式 「處理」 1E-310,而PostgreSQL的雙精度型則沒有。 PythonPostgreSQL文檔分別是「float」和「double precision」類型,指的是IEEE 754標準,它應該在「大多數平臺」上實現(我在OS X Lion 10.7.3上) 。

任何人都可以解釋這裏發生了什麼?並給我一個解決方案,我想例如「減少」Python精度,以便我可以通過Django FloatField在我的數據庫中插入浮點數。 (完整的用例是我正在讀取文件中的數字,然後插入它們)。

一些(也許是有趣)的更多信息,在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 

我真的不明白的第二個。

+0

我推測,Postgres的被拒絕給它,因爲.1不能完全用二進制表示(尾數)。 – bdares 2012-03-04 16:27:46

+0

@bdares我不知道我的理解。 「select 1e-100 :: double precision;」在Postgres中工作正常;我不認爲這是一個正確的問題,而是一個精確的問題 – Arthur 2012-03-04 16:51:51

回答

8

值浮子(「1E-310」)是一個denormal number這是通常的範圍爲指數53位浮點(308至-308)的外部,以便它被存儲精度較低,以實現漸進下溢。

看來PostgreSQL有與非規格化一些懸而未決的問題:http://archives.postgresql.org/pgsql-hackers/2011-06/msg00885.php

對於接近零值,考慮之前存儲在數據庫中的舍入他們:

>>> round(float('1e-302'), 308) 
1e-302 
>>> round(float('1e-310'), 308) 
0.0 
+3

謝謝!冷靜無人的土地。但是,您的解決方案無法工作的地區更窄: round(float('1e-308'),308)給出了postgres不接受的1e-308。我只是選擇了:如果abs(ff) Arthur 2012-03-04 17:27:18