Подтвердить что ты не робот

Какой лучший способ сравнить Double и Int?

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

int iValue = 0;
double dValue = 0.0;

bool isEqual = iValue.Equals(dValue);

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

4b9b3361

Ответ 1

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

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. Все зависит от того, что вы "пытаюсь добиться".

EDIT: Обратите внимание, что я выбрал 0,0000001 в качестве примерного порогового значения... вам нужно решить, какая точность достаточна для сравнения. Просто убедитесь, что вы должны находиться в пределах нормальных репрезентативных границ double, которые, как мне кажется, определены как Double.Espilon.

Ответ 2

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

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

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

Ответ 3

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.

Ответ 4

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

bool isEqual = (double)iValue == dValue;

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

Ответ 5

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

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