#include <stdio.h>
#include <math.h>
#include <errno.h>
#include <string.h>
#include <fenv.h>

int main() {
    double inputs[] = {171, 0, -1.0, -1000.5, 1000, INFINITY, -INFINITY};
    size_t count = sizeof(inputs)/sizeof(inputs[0]);

    for (size_t i = 0; i < count; ++i) {
        double x = inputs[i];

        // Test tgamma
        errno = 0;
        feclearexcept(FE_ALL_EXCEPT);
        double t = tgamma(x);

        printf("  tgamma(%f) = %f, errno = %d", x, t, errno);
        if (errno) printf(" (%s)", strerror(errno));

        int t_excepts = fetestexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW);
        if (t_excepts) {
            printf(", exception:");
            if (t_excepts & FE_DIVBYZERO) printf(" FE_DIVBYZERO");
            if (t_excepts & FE_INVALID)   printf(" FE_INVALID");
            if (t_excepts & FE_OVERFLOW)  printf(" FE_OVERFLOW");
            if (t_excepts & FE_UNDERFLOW)  printf(" FE_UNDERFLOW");
        }
        printf("\n");


        // Test lgamma
        errno = 0;
        feclearexcept(FE_ALL_EXCEPT);
        double l = lgamma(x);

        printf("  lgamma(%f) = %f, errno = %d", x, l, errno);
        if (errno) printf(" (%s)", strerror(errno));

        int l_excepts = fetestexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
        if (l_excepts) {
            printf(", exception:");
            if (l_excepts & FE_DIVBYZERO) printf(" FE_DIVBYZERO");
            if (l_excepts & FE_INVALID)   printf(" FE_INVALID");
            if (l_excepts & FE_OVERFLOW)  printf(" FE_OVERFLOW");
        }
        printf("\n");

        printf("\n");
    }

    return 0;
}
