【问题标题】:Handling fpu exception on windows处理windows上的fpu异常
【发布时间】:2009-02-22 12:52:42
【问题描述】:

我想在 Windows 上处理 fpu 异常,例如:

#include <math.h>
#include <fenv.h>
#include <stdio.h>

int main()
{
    double b = 0;
    int raised;
    feclearexcept (FE_ALL_EXCEPT);
    b /= 0;
    raised = fetestexcept (FE_OVERFLOW | FE_INVALID);
    if (raised & FE_OVERFLOW) { printf("over\n");}
    if (raised & FE_INVALID)  { printf("invalid\n");}

    return 0;
}

但在 Windows 上。我尝试阅读 MSDN,但文件根本不清楚。我想在 x86 和 amd64 架构上使用 Visual Studio 编译器来做到这一点。

我对在 C++ 中翻译异常不感兴趣 - 实际上,我什至对 FPU 异常都不感兴趣,只对经过一些计算后知道 FPU 状态感兴趣,就像上面的示例一样。

== 编辑 ==

好吧,看起来它实际上要简单得多:使用 _clearfp 就足够了:

#include <math.h>
#include <float.h>
#include <stdio.h>

int main()
{
    double b = 0;
    int raised;
    raised = _clearfp();
    b /= 0;
    raised = _clearfp();
    if (raised & SW_INVALID)  { printf("invalid\n");}

    return 0;
}

比处理异常、SEH 和其他不可移植的东西要好得多:)

【问题讨论】:

  • 在Windows下用G++工作,好像是编译错误。
  • 是的,处理“在 Windows 上”并不精确:我的意思是使用 Visual Studio。

标签: c windows exception fpu


【解决方案1】:

您可以使用 _statusfp2() 检索浮点状态。注意 32 位同时使用 FPU 和 SSE 指令。一些示例代码:

#include "stdafx.h"
#include <float.h>
#include <math.h>
#include <assert.h>


int _tmain(int argc, _TCHAR* argv[])
{
  unsigned x86;
  unsigned sse;
  // Test zero-divide
  double d = 0;
  double v = 1 / d;
  _statusfp2(&x86, &sse);
  assert(x86 & _EM_ZERODIVIDE);
  // Test overflow
  v = pow(10, 310.0);
  _statusfp2(&x86, &sse);
  assert(sse & _EM_OVERFLOW);
  return 0;
}

【讨论】:

    【解决方案2】:

    如果是 Visual Studio,请尝试输入这一行:

    #pragma   float_control (except, on)
    

    更多关于 herehere 的信息。

    编辑:

    如果您想在纯 C 中执行此操作,则需要查看 structured exception handling (SEH).

    【讨论】:

    • 这两个链接非常不清楚,很遗憾;我不明白 float_control 应该做什么:将错误转换为 C++ 异常?我想要一个纯 C 的解决方案。
    【解决方案3】:

    这些功能是标准规定的,所以移植应该没有问题。你到底遇到了什么错误?

    【讨论】:

    • 它甚至不编译 - AFAIK,MS 编译器没有 fenv.h,但有自己的机制。
    • 对于 VS,您必须依赖提到的 pragma arul。
    猜你喜欢
    • 2011-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-16
    • 2019-06-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多