开发者

IronPython/C# Float data comparison

We have WPF based application using Prism Framework. We have embedded IronPython and using Python Unit Test framework to automate our application GUI testing.

It works very well. We have difficulties in comparing two float numbers.

Example C#

class MyClass
{
   public object Value { get; set;}
   public MyClass()
   {
        Value = (float) 12.345;
   } 
}

In IronPython When I compare the MyClass Instance's Value property with python float value(12.345), it says it doesn't equal

This Python statement raises assert error

self.assertEqual(myClassInstance.Value, 12.345)

This Python statement works fine.

self.assertEqual(float(myClassInstance.Value.ToString()), 12.345) 

When I check the type of the type(myClassInstance.Value), it returns Single in Python where as type(12.345) returns float. How to handle the C# float to Python comparison without explicit c开发者_Python百科onversions?


12.345 in C# is a double, unless you explicitly use 12.345f


IronPython float is actually a .NET double. Besides, you shouldn't be comparing floating point values for equality anyway.


I'm not familiar with Python but I'm taking a stab at an answer based on what I know about the CLR and C#.

In your example, the float value is "boxed" when it's assigned to the Value property. Boxing is a way of storing a value type (such as a float, int, etc) in an object-typed variable. If the assert method takes two object parameters, it might be doing reference equality in which case the two would not be "equal". You would need to "unbox" the Value property to get a value comparison. In C# this is done by simply casting the object-typed variable back to its original type.

To demonstrate, see the following code. Note that it prints False for the first and True for the second.

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;
}

However, I have to agree with Ignacio that you should never compare two floating point numbers for equality. You should always use a method that includes a tolerance since floating point operations can sometimes result in tiny differences.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜