Это нормально?
double doubleVariable=0.0;
if (doubleVariable==0) {
...
}
Или этот код будет страдать от потенциальных проблем округления?
Это нормально?
double doubleVariable=0.0;
if (doubleVariable==0) {
...
}
Или этот код будет страдать от потенциальных проблем округления?
Нет, это совершенно законно, если вы собираетесь сравнивать только с 0, так как правая часть сравнения будет автоматически заменена на двойную. С другой стороны, это даст все ошибки округления, если вы где сравнить с == 0.10000001
Вы лучше или читаете обсуждение float для сравнения 0 здесь: Безопасно ли проверять значения с плавающей запятой на равенство 0?
Также эта дискуссия очень информативна в отношении странных проблем точности при поплавках: Почему результат отличается от этой проблемы?
то есть. ниже будет выдано false:
double d1 = 1.000001; double d2 =0.000001;
Console.WriteLine((d1-d2)==1.0);
У вас есть 0
, который является целым литералом. Он неявно преобразуется в double, который вы можете представить с помощью двойного литерала 0.0
(неявное преобразование). Тогда есть сравнение между двумя двойниками. Ошибка округления может привести к тому, что doubleVariable
не будет равно 0.0
(по какой-либо другой математике, которую вы могли бы сделать, а не только по ее установке), но при преобразовании целого числа 0 в double не может быть ошибки округления. Код, который у вас есть, абсолютно безопасен, но я бы предпочел == 0.0
.
Try:
if (double.Equals(doubleValue, 0.0)){}
Если вы просто сравниваете двойную переменную с 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;
hmm... Я думаю, что если число имеет точное представление двоичной дробной части (например, 0), сравнение вполне допустимо.
Вы не должны использовать double для такого сравнения. double создает проблему.
например double n1=0.55
double n2=100
, тогда double ans=n1*n2
должно быть 55.0
но при отладке ans 55.000000000000007
.
if(ans==55.0)
не удастся. в этом случае вы можете столкнуться с проблемой.