2012-03-04 98 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