Mingw-64 Detect domain and range errors in math functions

Using C++11:

I am trying to determine how to handle domain and range errors using the g++ compiler (Mingw64). I have provided some sample code below which is the approach that I use for g++ on Linux systems. When I compile I get the following messages:

warning: ignoring #pragma STDC FENV_ACCESS [-Wunknown-pragmas] #pragma STDC FENV_ACCESS ON
error: 'math_errhandling' was not declared in this scope
error: 'MATH_ERRNO' was not declared in this scope
error: 'MATH_ERREXCEPT' was not declared in this scope

I have looked for these symbols in the normal include headers but I don't see them.  Any help is greatly appreciated. I must note that  math_errhandling, MATH_ERRNO,  MATH_ERREXCEPT and the pragma  STDC FENV_ACCESS are part of the c++(2011) standard.

#include <cmath>
#include <fenv>
#include <cerrno>


#pragma STDC FENV_ACCESS ON
if (math_errhandling & MATH_ERREXCEPT) {
feclearexcept(FE_ALL_EXCEPT);
}
errno = 0;
result = pow(x, y);

if ((math_errhandling & MATH_ERRNO) && errno != 0) {
  /* Handle range error */
}
else if ((math_errhandling & MATH_ERREXCEPT) &&
           fetestexcept(FE_INVALID | FE_DIVBYZERO |
                        FE_OVERFLOW | FE_UNDERFLOW) != 0) {
  /* Handle range error */
}
}
/ Use result... /
}
orondo jonesAsked:
Who is Participating?
 
phoffricCommented:
I get thousands of hits when searching on the OP's keywords.

I see that you are using
#include <fenv>
I am not sure where you got that header file. For pure C++11, you should be using
#include <cfenv>

I have also seen <fenv.h> online.



Try running the code in this link
http://en.cppreference.com/w/cpp/numeric/math/math_errhandling
Make sure you include the compiler option to use C++11:
g++ -std=c++11

#include <iostream>
#include <cfenv>
#include <cmath>
#include <cerrno>
#include <cstring>
#pragma STDC FENV_ACCESS ON
int main()
{
    std::cout << "MATH_ERRNO is "
              << (math_errhandling & MATH_ERRNO ? "set" : "not set") << '\n'
              << "MATH_ERREXCEPT is "
              << (math_errhandling & MATH_ERREXCEPT ? "set" : "not set") << '\n';
    std::feclearexcept(FE_ALL_EXCEPT);
    errno = 0;
    std::cout <<  "log(0) = " << std::log(0) << '\n';
    if(errno == ERANGE)
            std::cout << "errno = ERANGE (" << std::strerror(errno) << ")\n";
    if(std::fetestexcept(FE_DIVBYZERO))
        std::cout << "FE_DIVBYZERO (pole error) reported\n";
}

Open in new window

0
 
sarabandeCommented:
I have looked for these symbols in the normal include headers but I don't see them.
you have to look in your linux system where those expressions are coming from.

i have doubts that those non-standard expressions are portable to mingw. so i would try to comment all those things that don't compile or replace them by own functions (based on c++ standard modules only) if you think you would need them.

for example

if ((math_errhandling & MATH_ERRNO) && errno != 0) 

Open in new window


might be replaced by

if (errno != 0) 

Open in new window


probably without disadvantages because it was defeatable in the linux code as well.

Sara
0
 
orondo jonesAuthor Commented:
Actually, the expressions are part of the 2011 c++ standard.
0
 
orondo jonesAuthor Commented:
The code provided in the link works with Visual Studio 2017 with the exception that the pragma is not defined. You get a warning. With  MinGW-64 the following code works (you have to compile with the flag -fsignaling-nans)

int main ()
{
            fpeInit_ fenv_t fe;
            int fint;
           feholdexcept(&fe);
           feclearexcept (FE_ALL_EXCEPT);


          int = fetestexcept(FE_ALL_EXCEPT);
          if (fint & FE_DIVBYZERO ||  fint & FE_INVALID   ||   fint & FE_OVERFLOW  ||  fint & FE_UNDERFLOW)
          {
                 feclearexcept (FE_ALL_EXCEPT);
                 feupdateenv(&fe);
                 
        }


}
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.