【问题标题】:A Double divided by zero is returning a Divide by Zero errorDouble 除以零返回除以零错误
【发布时间】:2011-04-19 16:33:14
【问题描述】:

我遇到了意外的行为,希望有人能提供一些指导,帮助我了解重点调查的领域。

我有两种方法,一种是对双精度执行除以零测试,第二种为非托管 dll 调用 extern 方法。

注意:在 .Net 运行时,将 Double 除以零应该返回一个 Infinity 值(有趣的是正面或负面的味道)。

我正在做的伪代码看起来像这样:

InfinityTest(); // Returns an Infinity value as expected
DllCall();
InfinityTest(); // Divide by zero error on second call.

InfinityTest() 的第一次调用按预期返回值Infinity。对 InfinityTest() 的第二次调用引发了一个除零异常,这是我没有预料到的。

更新

下面的有效InfinityTest() 代码。为简洁起见,我删除了 try/catch 元素等。我无权详细了解DllCall() 伪代码元素,抱歉。

private double InfinityTest()
{
    double a = 1.0;
    int b = 0;
    return a / b;
}

【问题讨论】:

  • 哎哟!看起来 DLL 调用更改了一些 FP 标志并且没有将它们放回原处。 :(
  • 我们能得到这两种方法的代码吗?更重要的是infinityTest();
  • 你能从“InfinityTest();”中发布代码吗?你能告诉我们 DllCall 是做什么的吗?是否有任何引用传递给 DllCall?
  • DLL 是不是用 Delphi 编写的?多年前,我在开发 VBScript 解释器时遇到了同样的问题。 VBScript 假设浮点错误在 FP 芯片上静默设置错误位; Delphi 假定浮点错误会导致异常,并将重置芯片的行为以满足其预期。
  • 前几天我遇到了这个问题,我在 .NET 分析器中从 QueryPerformanceCounter 更改为 QueryThreadCycleTime 并开始在分析的应用程序中出现奇怪的 DivideByZero 异常。

标签: c# .net double divide-by-zero


【解决方案1】:

由于听起来您的 DLL 正在更改您身上的 FP 状态字,您唯一的选择可能是将其更改回来。我建议将 P/Invoke 发送给 _clearfp_fpreset。以下是他们的 P/Invoke 签名:

    [DllImport("msvcrt.dll")]
    static extern UInt32 _clearfp();
    [DllImport("msvcrt.dll")]
    static extern void _fpreset();

这可能不会将事情重置回原来的样子,但希望它会足够接近。

【讨论】:

  • 在我们研究 dll 更改浮点标志的原因/方式时,这个问题暂时可以解决,非常感谢!
  • 第三方已经确认他们的dll确实在改变FP状态字。在他们最后审查后发现这不是必需的,并且 dll 已更新为可以在没有 FP 状态字更改的情况下工作。感谢您的帮助。
猜你喜欢
  • 2021-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多