处理Windows上的fpu异常

时间:2009-02-22 12:52:43

标签: c windows exception fpu

我想在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 archs上使用Visual Studio编译器执行此操作。

我对在C ++中翻译异常不感兴趣 - 实际上,我对FPU异常不感兴趣,只是在一些计算后知道FPU状态,如上例所示。

== edit ==

好吧,看起来它实际上要简单得多:使用_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和其他非便携式东西要好得多:)

3 个答案:

答案 0 :(得分:2)

如果是Visual Studio,请尝试输入以下内容:

#pragma   float_control (except, on)

有关此herehere的更多信息。

修改

如果你想在普通C中这样做,你需要看看structured exception handling (SEH).

答案 1 :(得分:2)

您可以使用_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 :(得分:0)

这些功能是标准规定的,因此您在移植时应该没有问题。你遇到了什么确切的错误?