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 使用不精确的精度。最好使用 DECIMAL
或 NUMERIC
,它们支持精确的用户指定精度。
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
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 使用不精确的精度。最好使用 DECIMAL
或 NUMERIC
,它们支持精确的用户指定精度。
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