IronPython/C# Float Сравнение данных
У нас есть приложение на основе WPF с использованием Prism Framework. Мы внедрили IronPython и используем Python Unit Test Framework для автоматизации тестирования нашего приложения.
Это работает очень хорошо. У нас есть трудности в сравнении двух чисел с плавающей точкой.
Пример C#
class MyClass
{
public object Value { get; set;}
public MyClass()
{
Value = (float) 12.345;
}
}
В IronPython Когда я сравниваю свойство Value экземпляра MyClass со значением с плавающей запятой Python (12.345), оно говорит, что оно не равно
Это утверждение Python вызывает ошибку assert
self.assertEqual(myClassInstance.Value, 12.345)
Это утверждение Python отлично работает.
self.assertEqual(float(myClassInstance.Value.ToString()), 12.345)
Когда я проверяю тип типа (myClassInstance.Value), он возвращает Single в Python, где тип (12.345) возвращает float. Как обработать сравнение C# float с Python без явных преобразований?
3 ответа
Я не знаком с Python, но я пытаюсь ответить на вопрос, основываясь на том, что я знаю о CLR и C#.
В вашем примере значение с плавающей запятой "упаковано", когда оно присваивается свойству Value. Упаковка - это способ хранения типа значения (такого как float, int и т. Д.) В типизированной переменной. Если метод assert принимает два параметра объекта, он может выполнять ссылочное равенство, и в этом случае они не будут "равными". Вам необходимо "распаковать" свойство Value, чтобы получить сравнение значений. В C# это делается простым приведением объектной переменной к ее первоначальному типу.
Чтобы продемонстрировать, смотрите следующий код. Обратите внимание, что он печатает False для первого и True для второго.
void Main()
{
object value1 = 1234.5F;
object value2 = 1234.5F;
Console.WriteLine(AreEqual(value1, value2));
Console.WriteLine(AreEqual((float)value1, (float)value2));
}
bool AreEqual(object value1, object value2) {
return value1 == value2;
}
bool AreEqual(float value1, float value2) {
return value1 == value2;
}
Однако я должен согласиться с Игнасио, что вы никогда не должны сравнивать два числа с плавающей точкой на равенство. Вы всегда должны использовать метод, который включает допуск, поскольку операции с плавающей запятой иногда могут привести к небольшим различиям.
12.345
в C# является двойным, если вы явно не используете 12.345f
IronPython float
на самом деле.NET двойной. Кроме того, вы все равно не должны сравнивать значения с плавающей точкой на равенство.