Я установил функции буксировки: одну для включения исключения для чисел с плавающей запятой и одну для отключения исключения.
В приведенном ниже коде я включил исключение буксировки за один раз (_EM_ZERODIVIDE и _EM_OVERFLOW), после того как мне нужно отключить только _EM_ZERODIVIDE и разрешить _EM_OVERFLOW.
Какой аргумент передать моей функции ResetFloatExeption (....).
См. Подробности в коде.

    #include <stdio.h>
    #include <float.h>
    #include <math.h>
    #pragma fenv_access (on)


    // SetFloatExeption
    void SetFloatExeption (unsigned int new_control)
    {
         _clearfp(); 
        _controlfp_s(0,new_control, _MCW_EM);
    }

    // ResetFloatExeption
    void ResetFloatExeption (unsigned int new_control) 
    {
         _clearfp(); 
        _controlfp_s(0,new_control, _MCW_EM);
    }

    //***************  main  ****//
    void main( void )
    {
        unsigned int old_control;
        double a = 1.1;
        double b = 0.0;
        float d;

        _controlfp_s(&old_control,0,0);         

        // Enable exception _EM_ZERODIVIDE and _EM_OVERFLOW

        SetFloatExeption (old_control & ~(_EM_ZERODIVIDE | _EM_OVERFLOW) );
         // Here, How to call ResetFloatExeption to disable juste _EM_ZERODIVIDE and let  _EM_OVERFLOW  enabled
        ResetFloatExeption(old_control & ???);      
        fprintf(stdout,"a/b= %.10e\n",a/b);     

        int exponent = 50;
        d = pow(10.0, exponent);                

        printf("d = %f\n",d);                   
    }
1
Phiber 28 Мар 2014 в 19:43

2 ответа

Лучший ответ
old_control & ~_EM_ZERODIVIDE | _EM_OVERFLOW

Обе ваши функции делают то же самое. Может стоит удалить один?

2
alexeibs 28 Мар 2014 в 19:53

Если вы используете C ++, обычно лучше иметь класс, который обрабатывает две основные операции, связанные с исключениями с плавающей запятой.

1) Временное отключение определенных исключений. 2) Временное включение определенных исключений.

В обоих случаях класс может позаботиться о внесении запрошенного изменения в настройки исключения с плавающей запятой, а затем сбросить его. Здесь вы можете найти пример таких классов:

http://randomascii.wordpress.com/2012/04/21/exceptional-floating-point/

В зависимости от ваших потребностей вы можете использовать их как есть или скопировать реализации конструктора / деструктора в свои функции.

1
Bruce Dawson 31 Мар 2014 в 09:32