Неправильно ли сравнивать double с 0 следующим образом: doubleVariable == 0?

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

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

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

Ответ 1

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

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

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

то есть. ниже будет выдано false:

double d1 = 1.000001; double d2 =0.000001;
Console.WriteLine((d1-d2)==1.0);

Ответ 2

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

Ответ 3

Try:

if (double.Equals(doubleValue, 0.0)){}

Ответ 4

Если вы просто сравниваете двойную переменную с 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;

Ответ 5

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

Ответ 6

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