mirror of
https://github.com/byteworksinc/ORCA-C.git
synced 2025-01-01 13:29:32 +00:00
Add tests and documentation for fma().
This commit is contained in:
parent
a988ef60bc
commit
c678151bde
@ -126,6 +126,9 @@ long double fdiml(long double, long double);
|
||||
double floor(double);
|
||||
float floorf(float);
|
||||
long double floorl(long double);
|
||||
double fma(double, double, double);
|
||||
float fmaf(float, float, float);
|
||||
long double fmal(long double, long double, long double);
|
||||
double fmax(double, double);
|
||||
float fmaxf(float, float);
|
||||
long double fmaxl(long double, long double);
|
||||
|
@ -32,6 +32,16 @@
|
||||
long double: fn##l, \
|
||||
default: _Generic((y), long double: fn##l, default: fn))((x),(y),(other))
|
||||
|
||||
#define __tg_real_x_y_z(fn,x,y,z) _Generic((x), \
|
||||
float: _Generic((y), \
|
||||
float: _Generic((z), float: fn##f, long double: fn##l, default: fn), \
|
||||
long double: fn##l, \
|
||||
default: _Generic((z), long double: fn##l, default: fn)), \
|
||||
long double: fn##l, \
|
||||
default: _Generic((y), \
|
||||
long double: fn##l, \
|
||||
default: _Generic((z), long double: fn##l, default: fn)))((x),(y),(z))
|
||||
|
||||
#define __tg_x(fn,x) __tg_real_x(fn,(x))
|
||||
#define __tg_x_y(fn,x,y) __tg_real_x_y(fn,(x),(y))
|
||||
|
||||
@ -54,6 +64,7 @@
|
||||
#define expm1(x) __tg_real_x(expm1,(x))
|
||||
#define fabs(x) __tg_real_x(fabs,(x))
|
||||
#define fdim(x,y) __tg_real_x_y(fdim,(x),(y))
|
||||
#define fma(x,y,z) __tg_real_x_y_z(fma,(x),(y),(z))
|
||||
#define fmax(x,y) __tg_real_x_y(fmax,(x),(y))
|
||||
#define fmin(x,y) __tg_real_x_y(fmin,(x),(y))
|
||||
#define floor(x) __tg_real_x(floor,(x))
|
||||
|
@ -48,6 +48,14 @@ int main(void) {
|
||||
goto Fail; \
|
||||
} while (0)
|
||||
|
||||
#define expect_underflow(op, val) do { \
|
||||
feclearexcept(FE_ALL_EXCEPT); \
|
||||
if ((op) != (val)) \
|
||||
goto Fail; \
|
||||
if (!fetestexcept(FE_UNDERFLOW)) \
|
||||
goto Fail; \
|
||||
} while (0)
|
||||
|
||||
#define expect_exact(op, val) \
|
||||
if ((op) != (val)) \
|
||||
goto Fail
|
||||
@ -361,7 +369,7 @@ int main(void) {
|
||||
expect_pole_error(tgammaf(-0.0), -INFINITY);
|
||||
expect_domain_error(tgammal(-2.0));
|
||||
expect_domain_error(tgammal(-15.0));
|
||||
expect_domain_error(tgammal(-1e4900));
|
||||
expect_domain_error(tgammal(-1e4900L));
|
||||
expect_domain_error(tgammal(-INFINITY));
|
||||
expect_exact(tgammal(+INFINITY),+INFINITY);
|
||||
expect_approx(tgammal(1.0), 1.0);
|
||||
@ -565,6 +573,37 @@ int main(void) {
|
||||
expect_exact(fminl(-50.0, NAN), -50.0);
|
||||
expect_exact(fminl(NAN, 1e30L), 1e30L);
|
||||
|
||||
expect_nan(fma(+INFINITY, +0.0, NAN));
|
||||
expect_nan(fmaf(-0.0, -INFINITY, NAN));
|
||||
expect_domain_error(fmal(-INFINITY, +0.0, 123.0));
|
||||
expect_domain_error(fma(-0.0, +INFINITY, -INFINITY));
|
||||
expect_domain_error(fmaf(1e-10, -INFINITY, +INFINITY));
|
||||
expect_domain_error(fmal(+INFINITY, 1e-4950L, -INFINITY));
|
||||
expect_exact(fma(2.0, 3.0, 5.0), 11.0);
|
||||
expect_exact(fmal(2e50L, -3.0L, 5e50L), -1e50L);
|
||||
expect_exact(fmaf(-2.0, -3.0, -7.5), -1.5);
|
||||
expect_nan(fma(NAN, 1.23, 4.56));
|
||||
expect_nan(fmaf(1.23, NAN, 4.56));
|
||||
expect_nan(fmal(1.23, 4.56, NAN));
|
||||
expect_exact(fmal(+INFINITY, LDBL_TRUE_MIN, -1e4932L), +INFINITY);
|
||||
expect_overflow(fmal(1e4000L, 1e1000L, -1e4932L), +INFINITY);
|
||||
expect_exact(fmal(LDBL_MAX, 1.0, LDBL_TRUE_MIN), LDBL_MAX);
|
||||
expect_exact(fmal(-LDBL_MAX, 1.0, -LDBL_TRUE_MIN), -LDBL_MAX);
|
||||
fesetround(FE_UPWARD);
|
||||
expect_overflow(fmal(LDBL_MAX, 1.0, LDBL_TRUE_MIN), +INFINITY);
|
||||
expect_exact(fmal(-LDBL_MAX, 1.0, -LDBL_TRUE_MIN), -LDBL_MAX);
|
||||
fesetround(FE_DOWNWARD);
|
||||
expect_exact(fmal(LDBL_MAX, 1.0, LDBL_TRUE_MIN), LDBL_MAX);
|
||||
expect_overflow(fmal(-LDBL_MAX, 1.0, -LDBL_TRUE_MIN), -INFINITY);
|
||||
fesetround(FE_TOWARDZERO);
|
||||
expect_exact(fmal(LDBL_MAX, 1.0, LDBL_TRUE_MIN), LDBL_MAX);
|
||||
expect_exact(fmal(-LDBL_MAX, 1.0, -LDBL_TRUE_MIN), -LDBL_MAX);
|
||||
expect_underflow(fmal(-LDBL_TRUE_MIN, LDBL_TRUE_MIN, LDBL_TRUE_MIN), 0.0);
|
||||
fesetenv(FE_DFL_ENV);
|
||||
expect_exact(fmal(-LDBL_TRUE_MIN, LDBL_TRUE_MIN, LDBL_TRUE_MIN), LDBL_TRUE_MIN);
|
||||
expect_underflow(fmal(-LDBL_TRUE_MIN, LDBL_TRUE_MIN, 0.0), -0.0);
|
||||
expect_exact(fmal(LDBL_TRUE_MIN, 5.0, -LDBL_TRUE_MIN), LDBL_TRUE_MIN*4.0L);
|
||||
|
||||
expect_exact(strtod("-1.25e+3x", &p), -1250.0); expect_exact(*p, 'x');
|
||||
expect_exact(strtold("-InFin", &p), -INFINITY); expect_exact(*p, 'i');
|
||||
expect_exact(strtof("INFiniTy", &p), INFINITY); //expect_exact(*p, 0);
|
||||
|
@ -77,6 +77,138 @@ int main(void) {
|
||||
if (sizeof(nextafter(1LL, 20LL)) != sizeof(double))
|
||||
goto Fail;
|
||||
|
||||
if (sizeof(fma(1.0F, 1.0F, 1.0F)) != sizeof(float))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0F, 1.0F, 1.0)) != sizeof(double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0F, 1.0F, 1.0L)) != sizeof(long double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0F, 1.0F, 1LL)) != sizeof(double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0F, 1.0, 1.0F)) != sizeof(double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0F, 1.0, 1.0)) != sizeof(double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0F, 1.0, 1.0L)) != sizeof(long double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0F, 1.0, 1LL)) != sizeof(double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0F, 1.0L, 1.0F)) != sizeof(long double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0F, 1.0L, 1.0)) != sizeof(long double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0F, 1.0L, 1.0L)) != sizeof(long double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0F, 1.0L, 1LL)) != sizeof(long double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0F, 1L, 1.0F)) != sizeof(double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0F, 1L, 1.0)) != sizeof(double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0F, 1L, 1.0L)) != sizeof(long double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0F, 1L, 1LL)) != sizeof(double))
|
||||
goto Fail;
|
||||
|
||||
if (sizeof(fma(1.0, 1.0F, 1.0F)) != sizeof(double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0, 1.0F, 1.0)) != sizeof(double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0, 1.0F, 1.0L)) != sizeof(long double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0, 1.0F, 1LL)) != sizeof(double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0, 1.0, 1.0F)) != sizeof(double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0, 1.0, 1.0)) != sizeof(double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0, 1.0, 1.0L)) != sizeof(long double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0, 1.0, 1LL)) != sizeof(double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0, 1.0L, 1.0F)) != sizeof(long double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0, 1.0L, 1.0)) != sizeof(long double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0, 1.0L, 1.0L)) != sizeof(long double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0, 1.0L, 1LL)) != sizeof(long double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0, 1L, 1.0F)) != sizeof(double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0, 1L, 1.0)) != sizeof(double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0, 1L, 1.0L)) != sizeof(long double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0, 1L, 1LL)) != sizeof(double))
|
||||
goto Fail;
|
||||
|
||||
if (sizeof(fma(1.0L, 1.0F, 1.0F)) != sizeof(long double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0L, 1.0F, 1.0)) != sizeof(long double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0L, 1.0F, 1.0L)) != sizeof(long double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0L, 1.0F, 1LL)) != sizeof(long double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0L, 1.0, 1.0F)) != sizeof(long double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0L, 1.0, 1.0)) != sizeof(long double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0L, 1.0, 1.0L)) != sizeof(long double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0L, 1.0, 1LL)) != sizeof(long double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0L, 1.0L, 1.0F)) != sizeof(long double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0L, 1.0L, 1.0)) != sizeof(long double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0L, 1.0L, 1.0L)) != sizeof(long double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0L, 1.0L, 1LL)) != sizeof(long double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0L, 1L, 1.0F)) != sizeof(long double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0L, 1L, 1.0)) != sizeof(long double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0L, 1L, 1.0L)) != sizeof(long double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1.0L, 1L, 1LL)) != sizeof(long double))
|
||||
goto Fail;
|
||||
|
||||
if (sizeof(fma(1LL, 1.0F, 1.0F)) != sizeof(double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1LL, 1.0F, 1.0)) != sizeof(double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1LL, 1.0F, 1.0L)) != sizeof(long double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1LL, 1.0F, 1LL)) != sizeof(double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1LL, 1.0, 1.0F)) != sizeof(double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1LL, 1.0, 1.0)) != sizeof(double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1LL, 1.0, 1.0L)) != sizeof(long double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1LL, 1.0, 1LL)) != sizeof(double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1LL, 1.0L, 1.0F)) != sizeof(long double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1LL, 1.0L, 1.0)) != sizeof(long double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1LL, 1.0L, 1.0L)) != sizeof(long double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1LL, 1.0L, 1LL)) != sizeof(long double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1LL, 1L, 1.0F)) != sizeof(double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1LL, 1L, 1.0)) != sizeof(double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1LL, 1L, 1.0L)) != sizeof(long double))
|
||||
goto Fail;
|
||||
if (sizeof(fma(1LL, 1L, 1LL)) != sizeof(double))
|
||||
goto Fail;
|
||||
|
||||
printf ("Passed Conformance Test c99tgmath\n");
|
||||
return 0;
|
||||
|
||||
|
6
cc.notes
6
cc.notes
@ -1218,6 +1218,12 @@ long double fdiml(long double x, long double y);
|
||||
|
||||
These functions return x - y if x > y, or +0.0 if x <= y.
|
||||
|
||||
double fma(double x, double y, double z);
|
||||
float fmaf(float x, float y, float z);
|
||||
long double fmal(long double x, long double y, long double z);
|
||||
|
||||
These functions compute (x * y) + z, rounded as one ternary operation. That is, they behave as if the mathematical result is computed exactly and then rounded once to produce the return value.
|
||||
|
||||
double fmax(double x, double y);
|
||||
float fmaxf(float x, float y);
|
||||
long double fmaxl(long double x, long double y);
|
||||
|
Loading…
Reference in New Issue
Block a user