Обработка исключения 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;
}

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

Меня не интересует перевод исключения на 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 и другими непереносимыми вещами :)


person David Cournapeau    schedule 22.02.2009    source источник
comment
Работает на G++ под Windows, видимо ошибка компилятора.   -  person schnaader    schedule 22.02.2009
comment
Да, обработка окон не точна: я имел в виду Visual Studio.   -  person David Cournapeau    schedule 22.02.2009


Ответы (3)


Вы можете использовать _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;
}
person Hans Passant    schedule 22.02.2009

Если это Visual Studio, попробуйте вставить эту строку:

#pragma   float_control (except, on)

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

ИЗМЕНИТЬ:

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

person arul    schedule 22.02.2009
comment
Две ссылки, к сожалению, крайне неясны; Я не понимаю, что должен делать float_control: перевести ошибку в исключение C++? Я хотел бы чистый раствор C. - person David Cournapeau; 22.02.2009

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

person dirkgently    schedule 22.02.2009
comment
Он даже не компилируется - AFAIK, компиляторы MS не имеют fenv.h, но имеют свой собственный механизм. - person David Cournapeau; 22.02.2009
comment
Для VS вам придется полагаться на упомянутую прагму арул. - person dirkgently; 22.02.2009