2012-03-04 2 views
6

Python의 "float"유형과 PostgreSQL의 "double precision"유형은 동일한 C 구현을 기반으로합니까? 즉 여기 진짜 근본적인 문제가 될 수 있지만 어쨌든, 여기에 내가 두 환경에서 작은 숫자를 조작 할 때 내가 무엇을 얻을 수 없습니다 :Python "float"및 PostgreSQL의 부동 소수점 수

파이썬에

(2.7.2 GCC 4.2.1 그 관련의 경우) :

PostgreSQL의 (9.1.1)에
>>> float('1e-310') 
1e-310 

:

PostgreSQL을 배정 밀도 유형하지 않는 동안 파이썬 플로트 타입은 1E-310을 "처리"한다는 것입니다 내가 이해
postgres# select 1e-310::double precision; 
ERROR: "0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001" is out of range for type double precision 

. 각각 "float"및 "double precision"유형의 PythonPostgreSQL 문서는 "대부분의 플랫폼"에서 구현되는 IEEE 754 표준을 참조합니다 (필자는 OS X Lion 10.7.3을 사용 중입니다) .

아무도 여기서 무슨 일이 일어 났는지 설명 할 수 있습니까? 그리고 나에게 해결책을 주겠다. 파이썬의 정밀도를 "줄이기"때문에 Django FloatField를 통해 데이터베이스에 수레를 삽입 할 수있다. (전체 사용 사례는 파일에서 수치를 읽고 삽입하는 것입니다.) 파이썬에서

일부 (아마도 흥미) 자세한 내용은 :

>>> 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

내가 포스트 그레스가 거부되는 것을 추측 것 .1을 2 진수로 정확히 표현할 수 없기 때문에 (가수). – bdares

+0

@bdares 이해할 수 있는지 잘 모르겠습니다. "select 1e-100 :: double precision;" Postgres에서 잘 작동합니다. 그리고 이것이 정확성 문제는 아니라고 생각합니다. 오히려 정밀한 것입니다. – Arthur

답변

8

값 float ('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