IronPython/C# 浮点数据比较

发布于 2024-10-09 12:57:03 字数 760 浏览 0 评论 0原文

我们有使用 Prism 框架的基于 WPF 的应用程序。我们嵌入了 IronPython 并使用 Python 单元测试框架来自动化我们的应用程序 GUI 测试。

它运作得很好。我们在比较两个浮点数时遇到困难。

IronPython 中的示例 C#

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

当我将 MyClass 实例的 Value 属性与 python float 值 (12.345) 进行比较时,它说它不等于此

Python 语句引发断言错误

self.assertEqual(myClassInstance.Value, 12.345)

Python 语句工作正常。

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

当我检查 type(myClassInstance.Value) 的类型时,它在 Python 中返回 Single,而 type(12.345) 返回 float。如何在没有显式转换的情况下处理 C# float 与 Python 的比较?

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 conversions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

千年*琉璃梦 2024-10-16 12:57:03

C# 中的 12.345 是双精度数,除非您显式使用 12.345f

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

生生不灭 2024-10-16 12:57:03

IronPython float 实际上是 .NET double。此外,无论如何你都不应该比较浮点值是否相等

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

追我者格杀勿论 2024-10-16 12:57:03

我不熟悉 Python,但我正在根据我对 CLR 和 C# 的了解来尝试回答。

在您的示例中,浮点值在分配给 Value 属性时被“装箱”。装箱是一种在对象类型变量中存储值类型(例如 float、int 等)的方法。如果断言方法采用两个对象参数,则它可能会执行引用相等,在这种情况下,两者将不“相等”。您需要“取消装箱” 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;
}

但是,我必须同意 Ignacio 的观点,即永远不应该比较两个浮点数是否相等。您应该始终使用包含容差的方法,因为浮点运算有时会导致微小的差异。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文