2浮点值的求和给出了不正确的结果,而精度更高

发布于 2025-01-30 13:36:47 字数 634 浏览 3 评论 0 原文

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

在这里,我通过找到存在问题的两个数字来减少问题陈述。 实际问题是,当我在整个桌子上这样做时,结果将很大,而更高的精确度(取决于值,我对精确射击的准确值/类型的值都没有解释),我们必须在应用程序级别处理规模。 示例查询

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

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

The sum of 2 floating values in postgres gives the result with higher precision.
Expected:

669.05 + 1.64 = 670.69

Actual:

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

The result is having higher precision than expected.

The same operation with different set of inputs behaves differently.

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

Here I have reduced the problem statement by finding the 2 numbers for which the issue exists.
The actual problem is when I do this on a whole table the result would be very big with higher precisions (depending on the values, and I do not have an explanation for exactly what/kind of values the precision shoots up) and we had to handle the scale in the application level.
Example query

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

Note: The behaviour is same for FLOAT(53) as well.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

逆夏时光 2025-02-06 13:36:47

根据PostgreSQL文档,Float使用不精确的精度。最好使用十进制数字,该数字支持精确的用户指定的精度。

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

postgresql 中的浮点

数据类型真实和双重精度是不精确的,
可变精确数字类型。目前支持的所有
平台,这些类型是IEEE标准754的实现
二进制浮点算术(单精度和双重精度,
分别为基础处理器运行的范围)
系统,编译器支持它。

数字类型

名称 存储尺寸 描述 范围
2个小 范围整数 -32768至+32767
整数 4个bytes 整数的典型选择 -2147483648至+2147483647
BIGING 8 BIGING 8 BIGINT 8
BINE 可变 用户指定的精度, ; 小数点之前最多可达131072位数 在小数点
数字 变量 用户指定的精度之后,最多可达16383位数字,精确 到小数点之前的数字高达131072位; 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 BYTE 大型自动启动整数 1至9223372036854775807

DB提议:在这里尝试

As per postgresql documentation, float uses inexact precision. Better to use DECIMAL or NUMERIC, which supports exact user specified precision.

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.

Numeric Types

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文