2 个浮点值的总和给出了精度更高的不正确结果

Summation of 2 floating point values gives incorrect result with higher precision

postgres 中 2 个浮点值的总和给出了更高精度的结果。 预计:

669.05 + 1.64 = 670.69

实际:

SELECT CAST(669.05 AS FLOAT) + CAST(1.64 AS FLOAT)
------------------
670.6899999999999

结果比预期的精度更高。

具有不同输入集的相同操作表现不同。

SELECT CAST(669.05 AS FLOAT) + CAST(1.63 AS FLOAT)
------------------
670.68

在这里,我通过找到存在问题的 2 个数字减少了问题陈述。 实际问题是,当我在整个 table 上执行此操作时,结果会非常大且精度更高(取决于值,而且我没有准确解释精度拍摄的值 what/kind向上),我们必须处理应用程序级别的规模。 示例查询

SELECT numeric_column_1/ CAST(numeric_column_2 AS FLOAT) FROM input_table;

注意:FLOAT(53) 的行为也相同。

根据 postgresql 文档,float 使用不精确的精度。最好使用 DECIMALNUMERIC,它们支持精确的用户指定精度。

SELECT CAST(669.05 AS numeric) + CAST(1.64 AS numeric)

Floating-Point Types in PostgreSQL

The data types real and double precision are inexact, variable-precision numeric types. On all currently supported platforms, these types are implementations of IEEE Standard 754 for Binary Floating-Point Arithmetic (single and double precision, respectively), to the extent that the underlying processor, operating system, and compiler support it.

数值类型

Name Storage Size Description Range
smallint 2 bytes small-range integer -32768 to +32767
integer 4 bytes typical choice for integer -2147483648 to +2147483647
bigint 8 bytes large-range integer -9223372036854775808 to +9223372036854775807
decimal variable user-specified precision, exact up to 131072 digits before the decimal point; up to 16383 digits after the decimal point
numeric variable user-specified precision, exact up to 131072 digits before the decimal point; up to 16383 digits after the decimal point
real 4 bytes variable-precision, inexact 6 decimal digits precision
double precision 8 bytes variable-precision, inexact 15 decimal digits precision
smallserial 2 bytes small autoincrementing integer 1 to 32767
serial 4 bytes autoincrementing integer 1 to 2147483647
bigserial 8 bytes large autoincrementing integer 1 to 9223372036854775807

DB Fiddle: Try it here