Сравнение значений с плавающей запятой - PullRequest
6 голосов
/ 07 октября 2009

Я только что прочитал заявление о сравнении значений с плавающей запятой

Значения с плавающей точкой не должны сравниваться с использованием == или! = операторы. Большинство значений с плавающей запятой не имеют точного двоичного представления и имеют ограниченная точность.

Если да, то каков наилучший метод сравнения двух значений с плавающей запятой?

Ответы [ 3 ]

7 голосов
/ 07 октября 2009

Следующие методы расширения могут быть полезны для реализации предложения Кевина:

public static bool IsEqualTo(this double a, double b, double margin)
{
    return Math.Abs(a - b) < margin;
}

public static bool IsEqualTo(this double a, double b)
{
    return Math.Abs(a - b) < double.Epsilon;
}

Так что теперь вы можете просто сделать:

if(x1.IsEqualTo(x2)) ...
if(x1.IsEqualTo(x2, 0.01)) ...

Просто измените IsEqualTo на более подходящее имя или измените поле по умолчанию на что-то лучше, чем double.Epsilon, если необходимо.

3 голосов
/ 07 октября 2009

Как правило, числа с плавающей запятой должны сравниваться с использованием такой конструкции, как

if( abs((x1 - x2) < 0.001) )

Причиной предупреждения, которое вы процитировали, является то, что у вас может быть два метода вычисления чего-либо, и они могут быть равны, если у вас не было ошибки округления, но ошибка округления делает их немного другими.

2 голосов
/ 28 мая 2012

«Лучший метод» зависит от того, почему вы хотите сравнить цифры. В общем, если вы думаете, что хотите проверить, равны ли 2 числа с плавающей запятой, вы делаете что-то не так.

Предполагается, что числа с плавающей точкой используются для представления реальных значений в обоих смыслах этого слова. Является ли этот объект такой же длины, как этот другой объект? Ну, они могут выглядеть одинаковой длины, но если вы получите достаточно хорошее измерительное устройство, вы всегда можете найти разницу. Точно так же два числа с плавающей запятой никогда не равны, если они не измеряют одно и то же и обрабатываются одинаково. Кроме этого, это просто ошибка округления где-то в системе.

Возможно, вы захотите проверить, что они близки (ближе, чем определенный порог), как предлагали другие ответы, но не равны.

...