X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=src%2Fmath%2Fnextafter.c;h=02c6edcfb1619f8b3c68c418c0b1a44000417edb;hb=d22f4f43182fe1cc70b343b6a52cb8e3a54d1f44;hp=344cc54787f0f21e3cb80f6176a525ada3700841;hpb=9d3ffa45089292491306c31e64757e44f90fc8f8;p=libc-test diff --git a/src/math/nextafter.c b/src/math/nextafter.c index 344cc54..02c6edc 100644 --- a/src/math/nextafter.c +++ b/src/math/nextafter.c @@ -1,81 +1,41 @@ -#include #include -#include #include -#include -#include -#include "fenvutil.h" -#include "test.h" +#include "util.h" + +static struct dd_d t[] = { -static struct { - double x; - double y; - double z; - int except; -} t[] = { - 0, 0, 0, 0, - 0, -0.0, -0.0, 0, - -0.0, 0, 0, 0, - 0, 1, 0x1p-1074, FE_INEXACT|FE_UNDERFLOW, - 0, -1, -0x1p-1074, FE_INEXACT|FE_UNDERFLOW, - -0.0, 1, 0x1p-1074, FE_INEXACT|FE_UNDERFLOW, - -0.0, -1, -0x1p-1074, FE_INEXACT|FE_UNDERFLOW, - 0x1p-1074, INFINITY, 0x1p-1073, FE_INEXACT|FE_UNDERFLOW, - 0x1p-1074, -INFINITY, 0, FE_INEXACT|FE_UNDERFLOW, --0x1p-1074, INFINITY, -0.0, FE_INEXACT|FE_UNDERFLOW, --0x1p-1074, -INFINITY, -0x1p-1073, FE_INEXACT|FE_UNDERFLOW, - DBL_MIN, 0, 0x0.fffffffffffffp-1022, FE_INEXACT|FE_UNDERFLOW, - -DBL_MIN, 0, -0x0.fffffffffffffp-1022, FE_INEXACT|FE_UNDERFLOW, - 1, 2, 0x1.0000000000001p+0, 0, - 1, -2, 0x1.fffffffffffffp-1, 0, - 1, 0.5, 0x1.fffffffffffffp-1, 0, - 0x1p1023, 0x1p1000, 0x1.fffffffffffffp+1022, 0, - 0x1p1023, INFINITY, 0x1.0000000000001p+1023, 0, - -1.5, -2.5, -0x1.8000000000001p+0, 0, - -1.5, 2.5, -0x1.7ffffffffffffp+0, 0, - 1.5, -2.5, 0x1.7ffffffffffffp+0, 0, - DBL_MAX, INFINITY, INFINITY, FE_INEXACT|FE_OVERFLOW, - INFINITY, INFINITY, INFINITY, 0, - -DBL_MAX, -INFINITY, -INFINITY, FE_INEXACT|FE_OVERFLOW, - -INFINITY, -INFINITY, -INFINITY, 0, - NAN, 1, NAN, 0, - 1, NAN, NAN, 0, }; -void test_nextafter() +int main(void) { - int f, i; - double z; + #pragma STDC FENV_ACCESS ON + double y; + float d; + int e, i, err = 0; + struct dd_d *p; for (i = 0; i < sizeof t/sizeof *t; i++) { - feclearexcept(FE_ALL_EXCEPT); - z = nextafter(t[i].x, t[i].y); - f = fetestexcept(FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW|FE_UNDERFLOW|FE_INEXACT); + p = t + i; - if (z != t[i].z && !(isnan(z) && isnan(t[i].z))) - error("nextafter(%a, %a) want %a got %a\n", t[i].x, t[i].y, t[i].z, z); - if (f != t[i].except) - error("nextafter(%a, %a)==%a want except=%s got except=%s\n", - t[i].x, t[i].y, t[i].z, strdup(strexcept(t[i].except)), strdup(strexcept(f))); - } -} - -void bench_nextafter_normal(int N) -{ - int i; - volatile double z; - - for (i = 0; i < N; i++) { - z = nextafter(1.25, 4); - } -} - -void bench_nextafter_subnormal(int N) -{ - int i; - volatile double z; - - for (i = 0; i < N; i++) { - z = nextafter(0x1p-1070, -0x1p-1071); + if (p->r < 0) + continue; + fesetround(p->r); + feclearexcept(FE_ALL_EXCEPT); + y = nextafter(p->x, p->x2); + e = fetestexcept(INEXACT|INVALID|DIVBYZERO|UNDERFLOW|OVERFLOW); + + if (!checkexcept(e, p->e, p->r)) { + printf("%s:%d: bad fp exception: %s nextafter(%a,%a)=%a, want %s", + p->file, p->line, rstr(p->r), p->x, p->x2, p->y, estr(p->e)); + printf(" got %s\n", estr(e)); + err++; + } + d = ulperr(y, p->y, p->dy); + if (!checkulp(d, p->r)) { + printf("%s:%d: %s nextafter(%a,%a) want %a got %a ulperr %.3f = %a + %a\n", + p->file, p->line, rstr(p->r), p->x, p->x2, p->y, y, d, d-p->dy, p->dy); + err++; + } } + return !!err; }