在Win7中运行x86目标程序集出现问题

本文关键字:程序集 问题 目标程序 目标 Win7 运行 x86 | 更新日期: 2023-09-27 18:07:53

我有一个为x86平台目标配置的c#项目。该应用程序在WinXP中运行良好,但在Win7中出现问题。我用的是VS2008。

请参阅下面的测试代码(问题:WinXP打印0,Win7打印1)。
注意:如果在调试模式下运行或添加一行跟踪,代码在Win7中也可以正常工作。

请告知,谢谢!

using System;
using System.Windows.Forms;
namespace Hello
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            //The problem: it shows "0" in WinXP, and shows "1" in Win7
            MessageBox.Show(Test.GetValue().ToString());
            Environment.Exit(0);
        }
    }
    public class Test
    {
        static int a = 0;
        static public float GetValue()
        {
            float b = 0.8149883f;
            float x = (696f / b + a);
            //Note: it returns 0 if uncomments the line below, otherwise it returns 1 
            //MessageBox.Show("hello");
            return (x - (int)x);
        }
    }
}

在Win7中运行x86目标程序集出现问题

除了@CodeInChaos所指出的这一点之外,浮点计算在不同的硬件架构上也是不同的。这就是浮点单位的本质。即使两个FP单元都遵循IEEE754,也会产生不同的结果。显然,这些差异将会微乎其微。因此,即使没有JIT差异,您也可能在不同的机器上看到不同的结果。

在您的情况下,您只需要以不同的方式比较浮点值。与其检验是否完全相等,不如检验是否在一个很小的公差范围内相等,例如abs(a-b)<epsilon,其中epsilon是一个很小的数字。

JIT编译器可以自由地优化浮点数,即使这稍微改变了结果。你不能指望所有平台的结果都是一样的。

有时它将您的853.9999...解释为854.0有时它将其保留为853.9999...。这是因为在某些平台上,中间结果的计算精度更高。在什么时候分解为float是不同的。在您的示例中,看起来消息框强制编译器将值存储在FPU之外,此时它被转换为32位浮点数。

相关问题:浮点数学在c#中是一致的吗?可能吗?

如果性能不太重要,您可以简单地使用Decimal并获得确定性结果。

请注意,如果使用double,结果会像预期的那样工作。

如果您取除法的结果并查看IEEE-754中浮点数和双精度表示的表示,您就会明白为什么:

853.99998993850586566702859415282

As float: 854.00000

As double: 853.99998993850590

从http://babbage.cs.qc.edu/courses/cs341/ieee

(html) - 754.

为什么你在调试和发布之间看到不同的结果,我不确定-我在VS2010中没有看到。