При работе с числами с плавающей запятой (одинарной или двойной точности) точное сравнение бесполезно в 99% случаев.Это верно не только для PostgreSQL, но и для всех компьютерных языков, использующих арифметику FP.
Три причины заключаются в том, что внутреннее представление двойного числа может содержать намного больше цифр, чем отображается, и в то же время многие числа не могут быть точно выражены с использованием FP (часто цитируемый пример - 0,1), и поэтомувсе «отображаемые» значения усекаются до чего-то, что человек может понять (т.е. ничего подобного «0,099999999999999999999999999» вместо «0,1»).
Поэтому необходимо избегать прямого сравнения, как только одно из чиселсравнение было вычислено (ошибки округления) или было преобразовано из строки.Вместо этого должен быть допущен некоторый «диапазон», например
where x between 3.69334468807004 and 3.69334468807006 -- note the different numbers
. Единственные допустимые случаи для прямого сравнения - это случаи, когда значение было только что скопировано ранее.Примером может быть:
SELECT x, y, f1(x,y), f2(x,y), ... INTO TEMP temp_xy FROM points;
SELECT * FROM points p JOIN temp_xy t on p.x = t.x and p.y = t.y;
x и y только что скопированы, поэтому их можно использовать в качестве критерия соединения.
Редактировать Хороший стартер дляЭта и некоторые другие неинтуитивные проблемы с плавающей точкой Эта статья .