|
nsz |
f9d179 |
#include <fenv.h>
|
|
nsz |
f9d179 |
#include <float.h>
|
|
nsz |
f9d179 |
#include <math.h>
|
|
nsz |
f9d179 |
|
|
nsz |
f9d179 |
#undef RN
|
|
nsz |
f9d179 |
#undef RZ
|
|
nsz |
f9d179 |
#undef RD
|
|
nsz |
f9d179 |
#undef RU
|
|
nsz |
75aab9 |
#ifdef FE_TONEAREST
|
|
nsz |
f9d179 |
#define RN FE_TONEAREST
|
|
nsz |
75aab9 |
#else
|
|
nsz |
75aab9 |
#define RN 0
|
|
nsz |
75aab9 |
#endif
|
|
nsz |
75aab9 |
#ifdef FE_TOWARDZERO
|
|
nsz |
f9d179 |
#define RZ FE_TOWARDZERO
|
|
nsz |
75aab9 |
#else
|
|
nsz |
75aab9 |
#define RZ -1
|
|
nsz |
75aab9 |
#endif
|
|
nsz |
75aab9 |
#ifdef FE_DOWNWARD
|
|
nsz |
f9d179 |
#define RD FE_DOWNWARD
|
|
nsz |
75aab9 |
#else
|
|
nsz |
75aab9 |
#define RD -1
|
|
nsz |
75aab9 |
#endif
|
|
nsz |
75aab9 |
#ifdef FE_UPWARD
|
|
nsz |
f9d179 |
#define RU FE_UPWARD
|
|
nsz |
75aab9 |
#else
|
|
nsz |
75aab9 |
#define RU -1
|
|
nsz |
75aab9 |
#endif
|
|
nsz |
f9d179 |
|
|
nsz |
f9d179 |
#undef INEXACT
|
|
nsz |
f9d179 |
#undef INVALID
|
|
nsz |
f9d179 |
#undef DIVBYZERO
|
|
nsz |
f9d179 |
#undef UNDERFLOW
|
|
nsz |
f9d179 |
#undef OVERFLOW
|
|
nsz |
75aab9 |
#ifdef FE_INEXACT
|
|
nsz |
f9d179 |
#define INEXACT FE_INEXACT
|
|
nsz |
75aab9 |
#else
|
|
nsz |
75aab9 |
#define INEXACT 0
|
|
nsz |
75aab9 |
#endif
|
|
nsz |
75aab9 |
#ifdef FE_INVALID
|
|
nsz |
f9d179 |
#define INVALID FE_INVALID
|
|
nsz |
75aab9 |
#else
|
|
nsz |
75aab9 |
#define INVALID 0
|
|
nsz |
75aab9 |
#endif
|
|
nsz |
75aab9 |
#ifdef FE_DIVBYZERO
|
|
nsz |
f9d179 |
#define DIVBYZERO FE_DIVBYZERO
|
|
nsz |
75aab9 |
#else
|
|
nsz |
75aab9 |
#define DIVBYZERO 0
|
|
nsz |
75aab9 |
#endif
|
|
nsz |
75aab9 |
#ifdef FE_UNDERFLOW
|
|
nsz |
f9d179 |
#define UNDERFLOW FE_UNDERFLOW
|
|
nsz |
75aab9 |
#else
|
|
nsz |
75aab9 |
#define UNDERFLOW 0
|
|
nsz |
75aab9 |
#endif
|
|
nsz |
75aab9 |
#ifdef FE_OVERFLOW
|
|
nsz |
f9d179 |
#define OVERFLOW FE_OVERFLOW
|
|
nsz |
75aab9 |
#else
|
|
nsz |
75aab9 |
#define OVERFLOW 0
|
|
nsz |
75aab9 |
#endif
|
|
nsz |
f9d179 |
|
|
nsz |
f9d179 |
#undef inf
|
|
nsz |
f9d179 |
#undef nan
|
|
nsz |
f9d179 |
#define inf INFINITY
|
|
nsz |
f9d179 |
#define nan NAN
|
|
nsz |
f9d179 |
|
|
nsz |
f9d179 |
#define T(...) {__FILE__, __LINE__, __VA_ARGS__},
|
|
nsz |
f9d179 |
|
|
nsz |
f9d179 |
#define POS char *file; int line;
|
|
nsz |
f9d179 |
struct d_d {POS int r; double x; double y; float dy; int e; };
|
|
nsz |
f9d179 |
struct f_f {POS int r; float x; float y; float dy; int e; };
|
|
nsz |
f9d179 |
struct l_l {POS int r; long double x; long double y; float dy; int e; };
|
|
nsz |
f9d179 |
struct ff_f {POS int r; float x; float x2; float y; float dy; int e; };
|
|
nsz |
f9d179 |
struct dd_d {POS int r; double x; double x2; double y; float dy; int e; };
|
|
nsz |
f9d179 |
struct ll_l {POS int r; long double x; long double x2; long double y; float dy; int e; };
|
|
nsz |
75aab9 |
struct d_di {POS int r; double x; double y; float dy; long long i; int e; };
|
|
nsz |
75aab9 |
struct f_fi {POS int r; float x; float y; float dy; long long i; int e; };
|
|
nsz |
75aab9 |
struct l_li {POS int r; long double x; long double y; float dy; long long i; int e; };
|
|
nsz |
75aab9 |
struct di_d {POS int r; double x; long long i; double y; float dy; int e; };
|
|
nsz |
75aab9 |
struct fi_f {POS int r; float x; long long i; float y; float dy; int e; };
|
|
nsz |
75aab9 |
struct li_l {POS int r; long double x; long long i; long double y; float dy; int e; };
|
|
nsz |
2146d5 |
struct d_i {POS int r; double x; long long i; int e; };
|
|
nsz |
2146d5 |
struct f_i {POS int r; float x; long long i; int e; };
|
|
nsz |
2146d5 |
struct l_i {POS int r; long double x; long long i; int e; };
|
|
nsz |
75aab9 |
#undef POS
|
|
nsz |
f9d179 |
|
|
nsz |
f9d179 |
char *estr(int);
|
|
nsz |
f9d179 |
char *rstr(int);
|
|
nsz |
f9d179 |
|
|
nsz |
f9d179 |
float ulperr(double got, double want, float dwant);
|
|
nsz |
f9d179 |
float ulperrf(float got, float want, float dwant);
|
|
nsz |
f9d179 |
float ulperrl(long double got, long double want, float dwant);
|
|
nsz |
f9d179 |
|
|
nsz |
f9d179 |
static int checkexcept(int got, int want, int r)
|
|
nsz |
f9d179 |
{
|
|
nsz |
d22f4f |
// TODO: we dont checkunderflow and inexact for now
|
|
nsz |
f9d179 |
if (r == RN)
|
|
nsz |
d22f4f |
return (got|INEXACT|UNDERFLOW) == (want|INEXACT|UNDERFLOW);
|
|
nsz |
d22f4f |
// return got == want || got == (want|INEXACT);
|
|
nsz |
d22f4f |
return 1;
|
|
nsz |
f9d179 |
}
|
|
nsz |
f9d179 |
|
|
nsz |
f9d179 |
static int checkulp(float d, int r)
|
|
nsz |
f9d179 |
{
|
|
nsz |
d22f4f |
// TODO: we only care about >=1.5 ulp errors for now, should be 1.0
|
|
nsz |
f9d179 |
if (r == RN)
|
|
nsz |
d22f4f |
return fabsf(d) < 1.5;
|
|
nsz |
d22f4f |
return 1;
|
|
nsz |
f9d179 |
}
|
|
nsz |
f9d179 |
|