Следующий код в С# не работает:
int iValue = 0;
double dValue = 0.0;
bool isEqual = iValue.Equals(dValue);
Итак, вопрос: какой лучший способ сравнить Double и Int?
Следующий код в С# не работает:
int iValue = 0;
double dValue = 0.0;
bool isEqual = iValue.Equals(dValue);
Итак, вопрос: какой лучший способ сравнить Double и Int?
Вы действительно не можете сравнить с плавающей точкой и интегральные значения наивным образом; в частности, поскольку существуют классические с плавающей точкой проблемы с представлением. То, что вы можете сделать, это вычесть одно из другого и посмотреть, не меньше ли разница между ними, например:
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
.
Это очень плохая идея сравнить целые числа и числа с плавающей запятой для равенства на любом языке. Он работает для очень простых случаев, но после того, как вы вообще делаете какую-либо математику, вероятность того, что программа сделает то, что вы хотите, резко уменьшится.
Это связано с тем, как числа с плавающей запятой хранятся в двоичной цифровой системе.
Если вы уверены, что хотите использовать это, создайте класс, чтобы сделать свой собственный номер с дробями. используйте один int для поддержания целого числа, а другой int - для сохранения фракции.
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.
Это действительно зависит от того, что вы считаете "равным". Если вы хотите, чтобы ваше сравнение возвращало true тогда и только тогда, когда double точно соответствует целочисленному значению (т.е. Не имеет дробного компонента), вы должны сделать свой int двойным, чтобы выполнить сравнение:
bool isEqual = (double)iValue == dValue;
Если что-то вроде 1.1 будет считаться равным 1, вы можете либо перевести double в int (если вы хотите вообще игнорировать дробный компонент), либо вокруг двойника, если вы хотите сказать 1.9 равным 2.
В настоящее время почти единственный раз, когда нужно сравнивать значения типов double
и либо integer
, либо long
для строгого равенства, когда по какой-то причине один задерживает сохранение или передачу интегральных величин как плавающих, и позже необходимо их вернуть. Такое преобразование в большинстве случаев может быть легко достигнуто путем литья интегрального типа до double
, а затем сравнения результата этого литья. Обратите внимание, что преобразование с long
в double
может быть неточным, если число находится вне диапазона ± 2 52. Тем не менее, за несколько дней до появления 64-битного long
double
был удобным типом хранения для целочисленных величин, которые были слишком большими для 32-битного int
, но достаточно маленького, чтобы обрабатываться double
.
Обратите внимание, что преобразование a long
в double
, а затем выполнение сравнения даст "равный" результат, если номинальное значение double
не точно соответствует значению long
, но представляет собой ближайший возможно double
к этому значению. Такое поведение имеет смысл, если распознавать, что типы с плавающей точкой фактически не представляют единственное точное значение, а скорее диапазон значений.