实型值比较不正确 [英] Value of real type incorrectly compares

查看:93
本文介绍了实型值比较不正确的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在数据库中具有 REAL 类型的字段。我使用PostgreSQL。和查询

I have field of REAL type in db. I use PostgreSQL. And the query

SELECT * FROM my_table WHERE my_field = 0.15

不返回 my_field 的值为 0.15

但是例如查询

SELECT * FROM my_table WHERE my_field > 0.15

正常工作。

如何我解决了这个问题,并获得了 my_field = 0.15 的行?

How can I solve this problem and get the rows with my_field = 0.15 ?

推荐答案

解决,请使用数据类型 数字 ,它不是浮点类型,而是任意精度类型。

To solve your problem use the data type numeric instead, which is not a floating point type, but an arbitrary precision type.

如果输入数字文字 0.15 转换为数字(同一词,不同含义)列,即精确的金额被存储-与 real float8 列不同,在列中该值被强制为下一个可能的二进制近似。这可能是正确的,也可能不是确切的,具体取决于数量和实现的细节。十进制数字0.15恰好介于可能的二进制表示形式之间,并且以很小的错误存储。

If you enter the numeric literal 0.15 into a numeric (same word, different meaning) column, the exact amount is stored - unlike with a real or float8 column, where the value is coerced to next possible binary approximation. This may or may not be exact, depending on the number and implementation details. The decimal number 0.15 happens to fall between possible binary representations and is stored with a tiny error.

请注意,计算结果本身可能不精确,因此请务必谨慎在这种情况下 = 运算符。

Note that the result of a calculation can be inexact itself, so be still wary of the = operator in such cases.

这还取决于您测试的方式。比较时,Postgres强制将各种数字类型转换为最能容纳结果的类型。
考虑以下 demo

It also depends how you test. When comparing, Postgres coerces diverging numeric types to a type that can best hold the result. Consider this demo:

CREATE TABLE t(num_r real, num_n numeric);
INSERT INTO t VALUES (0.15, 0.15);

SELECT num_r, num_n  
      ,num_r = num_n       AS test1  --> FALSE!
      ,num_r = num_n::real AS test2  --> TRUE!
      ,num_r - num_n       AS result_nonzero  --> float8
      ,num_r - num_n::real AS result_zero     --> real
FROM  t;

SQL小提琴。

SQL Fiddle.

因此,如果您输入了 0.15 作为数据类型为 real 的列中的数字文字,您可以使用以下命令找到所有此类行:

Therefore, if you have entered 0.15 as numeric literal into your column of data type real, you can find all such rows with:

SELECT * FROM my_table WHERE my_field = real '0.15'

如果需要精确存储小数位数,请使用数字列。

Use numeric columns if you need to store fractional digits exactly.

这篇关于实型值比较不正确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆