Обработка исключений fpu на windows - PullRequest
2 голосов
/ 22 февраля 2009

Я хотел бы обработать исключение fpu в Windows, что-то вроде:

#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;
}

Но на окнах. Я пытался прочитать MSDN, но документ не совсем ясно. Я хочу сделать это с компиляторами Visual Studio, как для x86, так и для amd64.

Я не заинтересован в переводе исключения в 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 ]

2 голосов
/ 22 февраля 2009

Если это Visual Studio, попробуйте ввести следующую строку:

#pragma   float_control (except, on)

Подробнее об этом здесь и здесь .

EDIT:

Если вы хотите сделать это в простом C, вам нужно взглянуть на структурированную обработку исключений ( SEH ).

2 голосов
/ 22 февраля 2009

Вы можете использовать _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;
}
0 голосов
/ 22 февраля 2009

Эти функции предписаны стандартом, поэтому у вас не должно возникнуть проблем при портировании. Какую именно ошибку вы совершаете?

...