Не правильно ли сравнивать double с 0 следующим образом: doubleVariable == 0? - PullRequest
12 голосов
/ 14 апреля 2011

Это нормально делать?

double doubleVariable=0.0;
if (doubleVariable==0) {
   ...
}

Или этот код будет страдать от потенциальных проблем с округлением?

Ответы [ 6 ]

7 голосов
/ 14 апреля 2011

Нет, это совершенно законно, если вы собираетесь сравнивать только с 0, так как правая сторона сравнения будет автоматически приведена к удвоению.С другой стороны, это приведет к ошибкам округления, если вы будете сравнивать с == 0.10000001

. Вы лучше или читаете обсуждение сравнения с плавающей запятой здесь: Безопасно липроверить значения с плавающей запятой на равенство 0?

Также это обсуждение очень информативно о странных проблемах точности с плавающей точкой: Почему результат для этой задачи отличается?

то есть ниже приведет к ложному:

double d1 = 1.000001; double d2 =0.000001;
Console.WriteLine((d1-d2)==1.0);
3 голосов
/ 14 апреля 2011

То, что у вас есть, это 0, что является целочисленным литералом.Он неявно преобразуется в double, который вы можете представить с помощью двойного литерала 0.0 ( неявного преобразования ).Тогда есть сравнение между двумя двойниками.Ошибка округления может привести к тому, что doubleVariable не будет равняться 0.0 (по какой-то другой причине, которую вы можете сделать, а не просто установить ее), но никогда не может быть ошибки округления при преобразовании целого числа 0 в удвоение.Код, который у вас есть, абсолютно безопасен, но я бы предпочел == 0.0.

2 голосов
/ 05 сентября 2014

Попробуйте:

if (double.Equals(doubleValue, 0.0)){}
1 голос
/ 14 апреля 2011

хмм ... Я думаю, что пока число имеет точное представление двоичной дроби (например, 0), сравнение вполне допустимо

1 голос
/ 14 апреля 2011

Если вы просто сравниваете двойную переменную с 0.0 (или 0), я считаю, что это безопасно, потому что я думаю, что 0 может быть представлено точно с плавающей запятой, но я не уверен на 100%.

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

double first = 1.234;
double second = 1.2345;
double difference = Math.Abs(first - second);

double threshold = 0.000001; // doubles are equal if their difference is less than this value - you choose this value based on your needs
bool areEqual = difference < threshold;
0 голосов
/ 14 апреля 2011

Вы не должны использовать double для такого сравнения. double создает проблему.
например, double n1=0.55 double n2=100, тогда double ans=n1*n2 должно быть 55.0
но когда вы отлаживаете ANS 55.000000000000007. if(ans==55.0)
не удастся. в таком случае вы можете столкнуться с проблемой.

...