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

Другие вопросы по тегам