IronPython / C # Float Сравнение данных - PullRequest
2 голосов
/ 30 декабря 2010

У нас есть приложение на основе 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 оператор вызывает ошибку подтверждения

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 ]

3 голосов
/ 30 декабря 2010

IronPython float на самом деле является двойником .NET.Кроме того, вы не должны сравнивать значения с плавающей точкой на равенство в любом случае .

3 голосов
/ 30 декабря 2010

12.345 в C # является двойным, если вы явно не используете 12.345f

0 голосов
/ 30 декабря 2010

Я не знаком с 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;
}

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

...