Python"float"和PostgreSQL"双精度"的浮点数

Art*_*hur 6 python django postgresql floating-point

Python的"浮点"类型和PostgreSQL的"双精度"类型是否基于相同的C实现?这可能不是真正的潜在问题,但无论如何,这是我在两个环境中尝试操作小数字时得到的结果:

在Python(2.7.2 GCC 4.2.1,如果相关):

>>> float('1e-310')
1e-310
Run Code Online (Sandbox Code Playgroud)

在PostgreSQL(9.1.1)上:

postgres# select 1e-310::double precision;
ERROR:  "0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001" is out of range for type double precision
Run Code Online (Sandbox Code Playgroud)

据我所知,Python float类型"处理"1e-310而PostgreSQL双精度类型则不然.双方的PythonPostgreSQL的文档上,分别是"浮动"和"双精度"类型,请参阅IEEE 754标准,这是应该的"大多数平台"实现的(我在OS X狮子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
Run Code Online (Sandbox Code Playgroud)

我真的没有得到第二个.

Ray*_*ger 8

值浮子("1E-310")是反规范数,其是通常的范围为指数53位浮点(308至-308)的外部,以便它被存储精度较低,以实现渐进下溢.

似乎PostgreSQL有一些未解决的非正规问题:http://archives.postgresql.org/pgsql-hackers/2011-06/msg00885.php

对于接近零的值,请考虑在DB中存储之前对它们进行舍入:

>>> round(float('1e-302'), 308)
1e-302
>>> round(float('1e-310'), 308)
0.0
Run Code Online (Sandbox Code Playgroud)

  • 谢谢!酷无人的土地.然而,在你的解决方案不起作用的地方甚至更窄:例如round(float('1e-308'),308)给出1e-308,而postgres不接受.我只是选择这样做:if abs(ff)<sys.float_info.min:ff = 0.我很惊讶我似乎是SO上第一个落入该区域的django-postgres用户. (3认同)