Por que o PostGresql não armazena meu valor de flutuação inteiro (PHP)?
-
12-09-2019 - |
Pergunta
Eu tento armazenar o valor do ponto flutuante PHP 63.59072952118762 em uma coluna de precisão dupla no Postgres. O Postgres armazena o valor como 63.59073. Alguem sabe por quê? 8 byte deve ser mais do que suficiente para esse valor. Eu tentei com o tipo de dados numérico, que funciona ao especificar a precisão, mas isso não deve ser realmente necessário.
Atualizar: O mesmo problema está presente ao tentar armazenar 63.5907295; portanto, a sugestão de que algo acontece com o duplo antes de ser armazenado parece realista.
Atualização II (parcialmente resolvido): A linha em que atribuo o parâmetro duplo se parece com o seguinte:
$stmt->bindParam(4, $this->latitude);
O que eu não sabia é que o PDO padrão seu tipo de param para string. Eu mudei para PDO :: Param Int na falta de uma alternativa melhor (o param duplo não era uma opção) e obtive 10 dígitos de precisão no duplo armazenado no Postgres (algum progresso, pelo menos). Eu verifiquei se o tipo numérico funciona bem, então parece que o numérico é o caminho a percorrer ao usar PDO e duplas que precisam ter uma precisão de mais de 10 decimais.
De qualquer forma, como alguém mencionou, não sei se é essencial para mim ter esse tipo de precisão, mas acho que o problema por si só merece ser investigado.
Solução
- Como você determina o que o PostGresql está armazenando?
- Como você envia os dados para o PostgreSQL?
- Como você recupera os dados novamente?
- Como você exibe isso?
- Que tipo é a coluna no banco de dados?
Existem muitos, muitos lugares no caminho entre PHP e PostgreSQL, onde pode haver confusão sobre como representar os dados.
É importante explicar como os dados são inseridos no DBMS. O uso de um valor literal na instrução INSERT leva a um conjunto diferente de problemas do uso de parâmetros vinculados. Se você escreveu o valor no SQL:
INSERT INTO SomeTable(SomeColumn) VALUES(63.xxxxxxxxx);
E os dados foram truncados, você teria um problema no PostgreSQL. Se você vincular a variável, deve entender o que o PHP e os módulos PDO Postgressql fazem com o valor - é enviado como um duplo ou como uma string, e qual código lida com a conversão e assim por diante.
Você encontra problemas análogos com o Perl + DBI + DBD :: Yourdbms (dbd :: pg no seu caso).
Outras dicas
Considere usar o Decimal/numérico digite se precisar de tanta precisão
O PostgreSQL aceita flutuação (1) para flutuar (24) como selecionando o tipo real, enquanto flutuando (25) para flutuar (53) Selecione a dupla precisão.
Na maioria das plataformas PG, o tipo real possui um intervalo de pelo menos 1E-37 a 1E+37 com uma precisão de pelo menos 6 dígitos decimais. O tipo de precisão dupla geralmente possui um intervalo de cerca de 1e-307 a 1e+308 com uma precisão de pelo menos 15 dígitos (Ref)
Qual destes você usa?