Числа с плавающей точкой Python "float" и PostgreSQL "двойная точность" - PullRequest
6 голосов
/ 04 марта 2012

Являются ли тип Python "float" и тип PostgreSQL "двойной точности" основанными на одной и той же реализации C?Это может быть не настоящей проблемой, но в любом случае вот что я получаю, когда пытаюсь манипулировать небольшими числами в обеих средах:

На 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 с двойной точностью - нет.Документы Python и PostgreSQL для соответственно типов "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

Я действительно надеваюне получаю второй.

1 Ответ

8 голосов
/ 04 марта 2012

Значение с плавающей запятой ('1e-310') представляет собой ненормальное число , которое выходит за пределы обычного диапазона показателей для 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...