#include <iostream>
#include <cmath>
#include <cfenv>
#include <cerrno>
#include <cstring>

using namespace std;

void throw_fe()
{
    if (errno) throw runtime_error(strerror(errno));
    if(fetestexcept(FE_DIVBYZERO))     throw runtime_error("FE_DIVBYZERO");
    if(fetestexcept(FE_INEXACT))       throw runtime_error("FE_INEXACT");
    if(fetestexcept(FE_INVALID))       throw runtime_error("FE_INVALID");
    if(fetestexcept(FE_OVERFLOW))      throw runtime_error("FE_OVERFLOW");
    if(fetestexcept(FE_UNDERFLOW))     throw runtime_error("FE_UNDERFLOW");
}


double Pow(double x, double y)
{
    errno = 0;
    feclearexcept(FE_ALL_EXCEPT);
    double z = pow(x,y);
    throw_fe();
    return z;
}

double Sqrt(double x)
{
    errno = 0;
    feclearexcept(FE_ALL_EXCEPT);
    double z = sqrt(x);
    throw_fe();
    return z;
}

double Log(double x)
{
    errno = 0;
    feclearexcept(FE_ALL_EXCEPT);
    double z = log(x);
    throw_fe();
    return z;
}


int main()
{
    try {
        double q = Sqrt(-2) + Pow(1e20,1e20);
        printf("log(0) = %f\n", q);
    } catch(exception&e)
    {
        cout << "Catch: " << e.what()  << endl;
    }
}
