Какой лучший способ сравнить Double и Int? - PullRequest
23 голосов
/ 30 октября 2009

Следующий код в C # не работает:

int iValue = 0;
double dValue = 0.0;

bool isEqual = iValue.Equals(dValue);

Итак, вопрос: как лучше сравнить Double и Int?

Ответы [ 5 ]

48 голосов
/ 30 октября 2009

Вы действительно не можете сравнивать значения с плавающей запятой и интегральные значения наивным способом; в частности, поскольку есть классические задачи с плавающей точкой для представления . То, что вы можете сделать, это вычесть одно из другого и посмотреть, меньше ли разница между ними, чем некоторая точность, которая вас волнует, например:

int iValue = 0;
double dValue = 0.0;

var diff = Math.Abs(dvalue - iValue);
if( diff < 0.0000001 ) // need some min threshold to compare floating points
   return true; // items equal

Вы действительно должны определить для себя, что equality означает для вас. Например, вы можете захотеть, чтобы значение с плавающей запятой округлялось до ближайшего целого числа, так что 3.999999981 будет «равно» 4. Или вы можете захотеть усечь значение, чтобы оно было равно 3. Все зависит от того, что вы Пытаешься достичь.

РЕДАКТИРОВАТЬ: Обратите внимание, что я выбрал 0,0000001 в качестве порогового значения в качестве примера ... вам нужно решить для себя, какая точность является достаточной для сравнения. Просто поймите, что вы должны находиться в пределах нормальных репрезентативных границ double, которые, как я считаю, определены как Double.Epsilon.

4 голосов
/ 30 октября 2009

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

Это связано с тем, как числа с плавающей запятой хранятся в двоичной цифровой системе.

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

1 голос
/ 25 июня 2012
double val1 = 0;
double val2 = 0.0;
if((val1 - Double.Epsilon) < 0)
{
    // Put your code here
}

      OR

if((val2 - Double.Epsilon) < 0)
{
    // Put your code here
}

где Double.Epsilon - наименьшее возможное значение для Double.

1 голос
/ 30 октября 2009

Это действительно зависит от того, что вы считаете "равным". Если вы хотите, чтобы ваше сравнение возвращало true тогда и только тогда, когда double точно соответствует целочисленному значению (то есть не имеет дробного компонента), вы должны привести int к double, чтобы выполнить сравнение:

bool isEqual = (double)iValue == dValue;

Если что-то вроде 1.1 будет считаться равным 1, вы можете либо привести двойное к целому (если вы хотите полностью игнорировать дробный компонент), либо округлить двойное, если хотите, чтобы 1.9 было равно 2.

0 голосов
/ 27 марта 2012

В настоящее время, практически единственный раз, когда нужно сравнивать значения типов double и integer или long для строгого равенства, это когда по какой-то причине кто-то застревает, сохраняя или передавая целочисленные величины как плавающие значения точек, а затем необходимо преобразовать их обратно. Такое преобразование в большинстве случаев легче всего выполнить, приведя целочисленный тип к double, а затем сравнив результат этого приведения. Обратите внимание, что преобразование из long в double может быть неточным, если число выходит за пределы диапазона ± 2 52 . Тем не менее, за несколько дней до того, как стал доступен 64-битный long, double был удобным типом хранения для целочисленных величин, которые были слишком велики для 32-битного int, но достаточно малы для обработки double.

Обратите внимание, что преобразование long в double и последующее сравнение приведут к "равному" результату, если номинальное значение double не точно совпадает со значением long, но представляет ближайший возможно double до этого значения. Такое поведение имеет смысл, если признать, что типы с плавающей точкой на самом деле представляют не одно точное значение, а диапазон значений.

...