【问题标题】:Double precision to varchar postgresql双精度到 varchar postgresql
【发布时间】:2019-04-16 01:39:08
【问题描述】:

我必须将数据类型为双精度字段的表修改为 varchar,alter 已成功执行,但是数据发生了变化,我无法理解 postgres 在进行双向转换时做了什么。

Postgres 版本:PostgreSQL 10.4,由 Visual C++ build 1800 编译,64 位

ALTER TABLE my_table ALTER COLUMN field_double_precision TYPE varchar;

--After the change this is my problem, new value is very different to old value

id     |old_value  |new_value              |
-------|-----------|-----------------------|
9009   |0.06       | 0.059999999999999998  |
9010   |0.56       | 0.56000000000000005   |
9011   |0.068      | 0.068000000000000005  |
9012   |0.568      | 0.56799999999999995   |

我知道数值是近似变化的,但我必须不惜一切代价避免这种情况。

我的测试:

SELECT  CAST (0.059999999999999998 AS DOUBLE PRECISION) old_value;

old_value |
----------|
0.06      |

-----------------------------------------------------------------------
SELECT  CAST (0.059999999999999998 AS double PRECISION)::VARCHAR new_value;

new_value            |
---------------------|
0.059999999999999998 |

我可以保持我的旧值和新值相等吗?当 postgres 将双精度格式化为 varchar 时会发生什么?

【问题讨论】:

  • 在 x86_64-apple-darwin17.5.0 上的 PostgreSQL 10.4 上,由 Apple LLVM 版本 9.1.0 (clang-902.0.39.1) 编译,64 位,你的最后一条语句给了我 0.06。
  • 我无法在 10.7 中重现您的问题。粘贴重现您的问题的 create tableinsert 语句。
  • 在 x86_64-pc-linux-gnu 上的 PostgreSQL 10.7 (Ubuntu 10.7-0ubuntu0.18.04.1),由 gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0 编译,64 位,您的最后一条语句也给出了 0.06 select cast(0.059999999999999998 AS double PRECISION)::VARCHAR new_value
  • 在由 Visual C++ build 1800 编译的 Windows 10 PostgreSQL 10.7 上,64 位的最后一条语句也显示 0.06。
  • 在第一种情况下,psql 正在格式化数字的显示。在第二种情况下,Postgres(服务器)在将数字转换为 varchar 之前对其进行格式化

标签: postgresql casting precision


【解决方案1】:

在运行将数据类型更改为character varyingALTER TABLE 语句之前,请确保运行以下语句:

SET @987654321@ = 0;

这将导致 PostgreSQL 在将浮点数呈现为字符串时抑制无关紧要的十进制数字。

【讨论】:

  • 如果我set extra_float_digits=1;,我可以重现 OP 的 kind 行为,如果不是相同的行为。但是在set extra_float_digits=0;(我的服务器上的默认值)之后,PostgreSQL 的行为就像 OP 想要的那样。 OP 可能还想在进行任何更改之前运行 show extra_float_digits; 以查看当前设置。
  • 这就是我说的,不是吗?有一些驱动程序,如 JDBC,将extra_float_digits 设置为远离其默认值 0。
  • 感谢@LaurenzAlbe 这对我有用,我得到了想要的结果,当执行 show extra_float_digits;这返回 3,因此根据文档包含部分有效数字,通过将参数设置为 0,数据保持输入,我开始认为这是我的客户的问题(DBeaver 版本 4.1.2 以查看以前的答案)。问候
【解决方案2】:

根据 Postgresql 文档here Double Precision 有以下行为..

数据类型实数和双精度是不精确的, 可变精度数值类型。在实践中,这些类型通常是 二进制浮点的 IEEE 标准 754 的实现 算术(分别为单精度和双精度),在某种程度上 底层处理器、操作系统和编译器支持 它。

不精确意味着某些值不能精确地转换为 内部格式并存储为近似值,因此存储和 检索值可能会显示出细微的差异。管理这些 错误以及它们如何通过计算传播是 数学和计算机科学的整个分支,并且不会 此处讨论,但以下几点除外:

  • 如果您需要精确的存储和计算(例如货币金额),请改用数字类型。
  • 如果您想针对任何重要的事情使用这些类型进行复杂的计算,尤其是当您依赖于
    中的某些行为时 边界情况(无穷大、下溢),您应该评估
    认真执行。
  • 比较两个浮点值是否相等可能并不总是按预期工作。

如何将双精度转换为数字,然后将该数字转换为 varchar?

【讨论】:

    猜你喜欢
    • 2016-08-17
    • 1970-01-01
    • 2018-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-15
    • 1970-01-01
    相关资源
    最近更新 更多