2012-03-04 27 views
6

Pythonの "float"型とPostgreSQLの "倍精度"型は、同じC実装に基づいていますか?それはここでの本当の根本的な問題で、とにかく、ここで私は両方の環境で小さな数字を操作しようとしたとき、私は何を得るのですしないことがあります。Python "float"とPostgreSQLの浮動小数点数 "double precision"

のPythonで(2.7.2 GCC 4.2.1、それが関連の場合):

PostgreSQLの(9.1.1)で
>>> float('1e-310') 
1e-310 

:PostgreSQLの倍精度型はそうではない

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

私が理解することは、そのPythonのfloat型 "ハンドル" 1E-310です。 "float"型と "double precision"型のPythonPostgreSQLは、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 

私は本当に秒1を得ることはありません。

+0

私はPostgresはに拒否していると推測していると思います.1はバイナリで正確に表現することができないので(あなたの仮名のために)、あなたに与えてください。 – bdares

+0

@bdares私は分かりません。 "select 1e-100 :: double precision;" Postgresでうまく動作します。これは正確さの問題ではなく、正確なものだと私は思う。 – Arthur

答えて

8

浮動小数点( '1e-310')の値は、53ビット浮動小数点(+308〜-308)の通常の指数範囲外のdenormal numberであるため、緩やかなアンダーフロー。 DBに格納する前に、それらを丸め検討し、ゼロに近い値についてhttp://archives.postgresql.org/pgsql-hackers/2011-06/msg00885.php

PostgreSQLは、いくつかの未解決のデノーマル数との問題を持っているようだ

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

ありがとう!人の土地を冷やすな。しかし、あなたのソリューションがうまくいかない領域がさらに狭くなっています。 round(float( '1e-308')、308)はポストグルに受け入れられない1e-308を与えます。私は単に次のように選んだ:if abs(ff) Arthur

関連する問題