math: add lrint, lround
authornsz <nsz@port70.net>
Sat, 13 Oct 2012 13:54:33 +0000 (15:54 +0200)
committernsz <nsz@port70.net>
Sat, 13 Oct 2012 13:54:33 +0000 (15:54 +0200)
27 files changed:
src/math/gen/functions.h
src/math/gen/mp.c
src/math/gen/mplibm.c
src/math/llrint.c [new file with mode: 0644]
src/math/llrintf.c [new file with mode: 0644]
src/math/llrintl.c [new file with mode: 0644]
src/math/llround.c [new file with mode: 0644]
src/math/llroundf.c [new file with mode: 0644]
src/math/llroundl.c [new file with mode: 0644]
src/math/lrint.c [new file with mode: 0644]
src/math/lrintf.c [new file with mode: 0644]
src/math/lrintl.c [new file with mode: 0644]
src/math/lround.c [new file with mode: 0644]
src/math/lroundf.c [new file with mode: 0644]
src/math/lroundl.c [new file with mode: 0644]
src/math/sanity/llrint.h [new file with mode: 0644]
src/math/sanity/llrintf.h [new file with mode: 0644]
src/math/sanity/llrintl.h [new file with mode: 0644]
src/math/sanity/llround.h [new file with mode: 0644]
src/math/sanity/llroundf.h [new file with mode: 0644]
src/math/sanity/llroundl.h [new file with mode: 0644]
src/math/sanity/lrint.h [new file with mode: 0644]
src/math/sanity/lrintf.h [new file with mode: 0644]
src/math/sanity/lrintl.h [new file with mode: 0644]
src/math/sanity/lround.h [new file with mode: 0644]
src/math/sanity/lroundf.h [new file with mode: 0644]
src/math/sanity/lroundl.h [new file with mode: 0644]

index 596c21b..0612aaf 100644 (file)
@@ -164,3 +164,15 @@ T(lgammal_r,   l_li)
 T(ilogb,       d_i)
 T(ilogbf,      f_i)
 T(ilogbl,      l_i)
+T(llrint,      d_i)
+T(llrintf,     f_i)
+T(llrintl,     l_i)
+T(lrint,       d_i)
+T(lrintf,      f_i)
+T(lrintl,      l_i)
+T(llround,     d_i)
+T(llroundf,    f_i)
+T(llroundl,    l_i)
+T(lround,      d_i)
+T(lroundf,     f_i)
+T(lroundl,     l_i)
index 0effca2..23ac5af 100644 (file)
@@ -755,3 +755,26 @@ int mpilogbl(struct t *t)
        return 0;
 }
 
+// TODO: ll* is hard to do with mpfr
+#define mp_f_i(n) \
+int mp##n(struct t *t) \
+{ \
+       setupfenv(t->r); \
+       t->i = n(t->x); \
+       t->e = getexcept(); \
+       return 0; \
+}
+
+mp_f_i(llrint)
+mp_f_i(llrintf)
+mp_f_i(llrintl)
+mp_f_i(lrint)
+mp_f_i(lrintf)
+mp_f_i(lrintl)
+mp_f_i(llround)
+mp_f_i(llroundf)
+mp_f_i(llroundl)
+mp_f_i(lround)
+mp_f_i(lroundf)
+mp_f_i(lroundl)
+
index fffed54..93225a9 100644 (file)
@@ -1,6 +1,5 @@
 #include "gen.h"
 
-#include <stdio.h>
 static int mpf1(struct t *s, float (*f)(float))
 {
        s->dy = 0;
@@ -25,7 +24,6 @@ static int mpd1(struct t *s, double (*f)(double))
        setupfenv(s->r);
        s->y = f(s->x);
        s->e = getexcept();
-//printf("%La %d\n", s->y, s->e);
        return 0;
 }
 
@@ -221,122 +219,44 @@ int mppow10(struct t *t) { return mpd1(t, pow10); }
 int mppow10f(struct t *t) { return mpf1(t, pow10f); }
 int mppow10l(struct t *t) { return mpl1(t, pow10l); }
 
-int mpfrexp(struct t *t)
-{
-       int i;
-
-       t->dy = 0;
-       setupfenv(t->r);
-       t->y = frexp(t->x, &i);
-       t->e = getexcept();
-       t->i = i;
-       return 0;
-}
-
-int mpfrexpf(struct t *t)
-{
-       int i;
-
-       t->dy = 0;
-       setupfenv(t->r);
-       t->y = frexpf(t->x, &i);
-       t->e = getexcept();
-       t->i = i;
-       return 0;
-}
-
-int mpfrexpl(struct t *t)
-{
-       int i;
-
-       t->dy = 0;
-       setupfenv(t->r);
-       t->y = frexpl(t->x, &i);
-       t->e = getexcept();
-       t->i = i;
-       return 0;
-}
-
-int mpldexp(struct t *t)
-{
-       t->dy = 0;
-       setupfenv(t->r);
-       t->y = ldexp(t->x, t->i);
-       t->e = getexcept();
-       return 0;
-}
-
-int mpldexpf(struct t *t)
-{
-       t->dy = 0;
-       setupfenv(t->r);
-       t->y = ldexpf(t->x, t->i);
-       t->e = getexcept();
-       return 0;
+#define mp_f_fi(n) \
+int mp##n(struct t *t) \
+{ \
+       t->dy = 0; \
+       setupfenv(t->r); \
+       t->y = n(t->x, t->i); \
+       t->e = getexcept(); \
+       return 0; \
 }
 
-int mpldexpl(struct t *t)
-{
-       t->dy = 0;
-       setupfenv(t->r);
-       t->y = ldexpl(t->x, t->i);
-       t->e = getexcept();
-       return 0;
-}
-
-int mpscalbn(struct t *t)
-{
-       t->dy = 0;
-       setupfenv(t->r);
-       t->y = scalbn(t->x, t->i);
-       t->e = getexcept();
-       return 0;
+mp_f_fi(ldexp)
+mp_f_fi(ldexpf)
+mp_f_fi(ldexpl)
+mp_f_fi(scalbn)
+mp_f_fi(scalbnf)
+mp_f_fi(scalbnl)
+mp_f_fi(scalbln)
+mp_f_fi(scalblnf)
+mp_f_fi(scalblnl)
+
+#define mp_fi_f(n) \
+int mp##n(struct t *t) \
+{ \
+       int i; \
+       t->dy = 0; \
+       setupfenv(t->r); \
+       t->y = n(t->x, &i); \
+       t->e = getexcept(); \
+       t->i = i; \
+       return 0; \
 }
 
-int mpscalbnf(struct t *t)
-{
-       t->dy = 0;
-       setupfenv(t->r);
-       t->y = scalbnf(t->x, t->i);
-       t->e = getexcept();
-       return 0;
-}
-
-int mpscalbnl(struct t *t)
-{
-       t->dy = 0;
-       setupfenv(t->r);
-       t->y = scalbnl(t->x, t->i);
-       t->e = getexcept();
-       return 0;
-}
-
-int mpscalbln(struct t *t)
-{
-       t->dy = 0;
-       setupfenv(t->r);
-       t->y = scalbln(t->x, t->i);
-       t->e = getexcept();
-       return 0;
-}
-
-int mpscalblnf(struct t *t)
-{
-       t->dy = 0;
-       setupfenv(t->r);
-       t->y = scalblnf(t->x, t->i);
-       t->e = getexcept();
-       return 0;
-}
-
-int mpscalblnl(struct t *t)
-{
-       t->dy = 0;
-       setupfenv(t->r);
-       t->y = scalblnl(t->x, t->i);
-       t->e = getexcept();
-       return 0;
-}
+mp_fi_f(frexp)
+mp_fi_f(frexpf)
+mp_fi_f(frexpl)
+mp_fi_f(lgamma_r)
+mp_fi_f(lgammaf_r)
+mp_fi_f(lgammal_r)
 
 int mplgamma(struct t *t)
 {
@@ -368,61 +288,28 @@ int mplgammal(struct t *t)
        return 0;
 }
 
-int mplgamma_r(struct t *t)
-{
-       int i;
-
-       t->dy = 0;
-       setupfenv(t->r);
-       t->y = lgamma_r(t->x, &i);
-       t->e = getexcept();
-       t->i = i;
-       return 0;
+#define mp_f_i(n) \
+int mp##n(struct t *t) \
+{ \
+       setupfenv(t->r); \
+       t->i = n(t->x); \
+       t->e = getexcept(); \
+       return 0; \
 }
 
-int mplgammaf_r(struct t *t)
-{
-       int i;
-
-       t->dy = 0;
-       setupfenv(t->r);
-       t->y = lgammaf_r(t->x, &i);
-       t->e = getexcept();
-       t->i = i;
-       return 0;
-}
-
-int mplgammal_r(struct t *t)
-{
-       int i;
-
-       t->dy = 0;
-       setupfenv(t->r);
-       t->y = lgammal_r(t->x, &i);
-       t->e = getexcept();
-       t->i = i;
-       return 0;
-}
-
-int mpilogb(struct t *t)
-{
-       setupfenv(t->r);
-       t->i = ilogb(t->x);
-       t->e = getexcept();
-       return 0;
-}
-int mpilogbf(struct t *t)
-{
-       setupfenv(t->r);
-       t->i = ilogbf(t->x);
-       t->e = getexcept();
-       return 0;
-}
-int mpilogbl(struct t *t)
-{
-       setupfenv(t->r);
-       t->i = ilogbl(t->x);
-       t->e = getexcept();
-       return 0;
-}
+mp_f_i(ilogb)
+mp_f_i(ilogbf)
+mp_f_i(ilogbl)
+mp_f_i(llrint)
+mp_f_i(llrintf)
+mp_f_i(llrintl)
+mp_f_i(lrint)
+mp_f_i(lrintf)
+mp_f_i(lrintl)
+mp_f_i(llround)
+mp_f_i(llroundf)
+mp_f_i(llroundl)
+mp_f_i(lround)
+mp_f_i(lroundf)
+mp_f_i(lroundl)
 
diff --git a/src/math/llrint.c b/src/math/llrint.c
new file mode 100644 (file)
index 0000000..a4bdc10
--- /dev/null
@@ -0,0 +1,41 @@
+#include <stdint.h>
+#include <stdio.h>
+#include "util.h"
+
+static struct d_i t[] = {
+#include "sanity/llrint.h"
+
+};
+
+int main(void)
+{
+       #pragma STDC FENV_ACCESS ON
+       int yi;
+       float d;
+       int e, i, err = 0;
+       struct d_i *p;
+
+       for (i = 0; i < sizeof t/sizeof *t; i++) {
+               p = t + i;
+
+               if (p->r < 0)
+                       continue;
+               fesetround(p->r);
+               feclearexcept(FE_ALL_EXCEPT);
+               yi = llrint(p->x);
+               e = fetestexcept(INEXACT|INVALID|DIVBYZERO|UNDERFLOW|OVERFLOW);
+
+               if (!checkexcept(e, p->e, p->r)) {
+                       printf("%s:%d: bad fp exception: %s llrint(%a)=%lld, want %s",
+                               p->file, p->line, rstr(p->r), p->x, p->i, estr(p->e));
+                       printf(" got %s\n", estr(e));
+                       err++;
+               }
+               if (yi != p->i) {
+                       printf("%s:%d: %s llrint(%a) want %lld got %d\n",
+                               p->file, p->line, rstr(p->r), p->x, p->i, yi);
+                       err++;
+               }
+       }
+       return !!err;
+}
diff --git a/src/math/llrintf.c b/src/math/llrintf.c
new file mode 100644 (file)
index 0000000..e69be37
--- /dev/null
@@ -0,0 +1,41 @@
+#include <stdint.h>
+#include <stdio.h>
+#include "util.h"
+
+static struct f_i t[] = {
+#include "sanity/llrintf.h"
+
+};
+
+int main(void)
+{
+       #pragma STDC FENV_ACCESS ON
+       int yi;
+       float d;
+       int e, i, err = 0;
+       struct f_i *p;
+
+       for (i = 0; i < sizeof t/sizeof *t; i++) {
+               p = t + i;
+
+               if (p->r < 0)
+                       continue;
+               fesetround(p->r);
+               feclearexcept(FE_ALL_EXCEPT);
+               yi = llrintf(p->x);
+               e = fetestexcept(INEXACT|INVALID|DIVBYZERO|UNDERFLOW|OVERFLOW);
+
+               if (!checkexcept(e, p->e, p->r)) {
+                       printf("%s:%d: bad fp exception: %s llrintf(%a)=%lld, want %s",
+                               p->file, p->line, rstr(p->r), p->x, p->i, estr(p->e));
+                       printf(" got %s\n", estr(e));
+                       err++;
+               }
+               if (yi != p->i) {
+                       printf("%s:%d: %s llrintf(%a) want %lld got %d\n",
+                               p->file, p->line, rstr(p->r), p->x, p->i, yi);
+                       err++;
+               }
+       }
+       return !!err;
+}
diff --git a/src/math/llrintl.c b/src/math/llrintl.c
new file mode 100644 (file)
index 0000000..9d99e87
--- /dev/null
@@ -0,0 +1,46 @@
+#include <stdint.h>
+#include <stdio.h>
+#include "util.h"
+
+static struct l_i t[] = {
+#if LDBL_MANT_DIG == 53
+#include "sanity/llrint.h"
+
+#elif LDBL_MANT_DIG == 64
+#include "sanity/llrintl.h"
+
+#endif
+};
+
+int main(void)
+{
+       #pragma STDC FENV_ACCESS ON
+       int yi;
+       float d;
+       int e, i, err = 0;
+       struct l_i *p;
+
+       for (i = 0; i < sizeof t/sizeof *t; i++) {
+               p = t + i;
+
+               if (p->r < 0)
+                       continue;
+               fesetround(p->r);
+               feclearexcept(FE_ALL_EXCEPT);
+               yi = llrintl(p->x);
+               e = fetestexcept(INEXACT|INVALID|DIVBYZERO|UNDERFLOW|OVERFLOW);
+
+               if (!checkexcept(e, p->e, p->r)) {
+                       printf("%s:%d: bad fp exception: %s llrintl(%La)=%lld, want %s",
+                               p->file, p->line, rstr(p->r), p->x, p->i, estr(p->e));
+                       printf(" got %s\n", estr(e));
+                       err++;
+               }
+               if (yi != p->i) {
+                       printf("%s:%d: %s llrintl(%La) want %lld got %d\n",
+                               p->file, p->line, rstr(p->r), p->x, p->i, yi);
+                       err++;
+               }
+       }
+       return !!err;
+}
diff --git a/src/math/llround.c b/src/math/llround.c
new file mode 100644 (file)
index 0000000..42aaa40
--- /dev/null
@@ -0,0 +1,41 @@
+#include <stdint.h>
+#include <stdio.h>
+#include "util.h"
+
+static struct d_i t[] = {
+#include "sanity/llround.h"
+
+};
+
+int main(void)
+{
+       #pragma STDC FENV_ACCESS ON
+       int yi;
+       float d;
+       int e, i, err = 0;
+       struct d_i *p;
+
+       for (i = 0; i < sizeof t/sizeof *t; i++) {
+               p = t + i;
+
+               if (p->r < 0)
+                       continue;
+               fesetround(p->r);
+               feclearexcept(FE_ALL_EXCEPT);
+               yi = llround(p->x);
+               e = fetestexcept(INEXACT|INVALID|DIVBYZERO|UNDERFLOW|OVERFLOW);
+
+               if (!checkexcept(e, p->e, p->r)) {
+                       printf("%s:%d: bad fp exception: %s llround(%a)=%lld, want %s",
+                               p->file, p->line, rstr(p->r), p->x, p->i, estr(p->e));
+                       printf(" got %s\n", estr(e));
+                       err++;
+               }
+               if (yi != p->i) {
+                       printf("%s:%d: %s llround(%a) want %lld got %d\n",
+                               p->file, p->line, rstr(p->r), p->x, p->i, yi);
+                       err++;
+               }
+       }
+       return !!err;
+}
diff --git a/src/math/llroundf.c b/src/math/llroundf.c
new file mode 100644 (file)
index 0000000..fcb5340
--- /dev/null
@@ -0,0 +1,41 @@
+#include <stdint.h>
+#include <stdio.h>
+#include "util.h"
+
+static struct f_i t[] = {
+#include "sanity/llroundf.h"
+
+};
+
+int main(void)
+{
+       #pragma STDC FENV_ACCESS ON
+       int yi;
+       float d;
+       int e, i, err = 0;
+       struct f_i *p;
+
+       for (i = 0; i < sizeof t/sizeof *t; i++) {
+               p = t + i;
+
+               if (p->r < 0)
+                       continue;
+               fesetround(p->r);
+               feclearexcept(FE_ALL_EXCEPT);
+               yi = llroundf(p->x);
+               e = fetestexcept(INEXACT|INVALID|DIVBYZERO|UNDERFLOW|OVERFLOW);
+
+               if (!checkexcept(e, p->e, p->r)) {
+                       printf("%s:%d: bad fp exception: %s llroundf(%a)=%lld, want %s",
+                               p->file, p->line, rstr(p->r), p->x, p->i, estr(p->e));
+                       printf(" got %s\n", estr(e));
+                       err++;
+               }
+               if (yi != p->i) {
+                       printf("%s:%d: %s llroundf(%a) want %lld got %d\n",
+                               p->file, p->line, rstr(p->r), p->x, p->i, yi);
+                       err++;
+               }
+       }
+       return !!err;
+}
diff --git a/src/math/llroundl.c b/src/math/llroundl.c
new file mode 100644 (file)
index 0000000..6468208
--- /dev/null
@@ -0,0 +1,46 @@
+#include <stdint.h>
+#include <stdio.h>
+#include "util.h"
+
+static struct l_i t[] = {
+#if LDBL_MANT_DIG == 53
+#include "sanity/llround.h"
+
+#elif LDBL_MANT_DIG == 64
+#include "sanity/llroundl.h"
+
+#endif
+};
+
+int main(void)
+{
+       #pragma STDC FENV_ACCESS ON
+       int yi;
+       float d;
+       int e, i, err = 0;
+       struct l_i *p;
+
+       for (i = 0; i < sizeof t/sizeof *t; i++) {
+               p = t + i;
+
+               if (p->r < 0)
+                       continue;
+               fesetround(p->r);
+               feclearexcept(FE_ALL_EXCEPT);
+               yi = llroundl(p->x);
+               e = fetestexcept(INEXACT|INVALID|DIVBYZERO|UNDERFLOW|OVERFLOW);
+
+               if (!checkexcept(e, p->e, p->r)) {
+                       printf("%s:%d: bad fp exception: %s llroundl(%La)=%lld, want %s",
+                               p->file, p->line, rstr(p->r), p->x, p->i, estr(p->e));
+                       printf(" got %s\n", estr(e));
+                       err++;
+               }
+               if (yi != p->i) {
+                       printf("%s:%d: %s llroundl(%La) want %lld got %d\n",
+                               p->file, p->line, rstr(p->r), p->x, p->i, yi);
+                       err++;
+               }
+       }
+       return !!err;
+}
diff --git a/src/math/lrint.c b/src/math/lrint.c
new file mode 100644 (file)
index 0000000..9174030
--- /dev/null
@@ -0,0 +1,41 @@
+#include <stdint.h>
+#include <stdio.h>
+#include "util.h"
+
+static struct d_i t[] = {
+#include "sanity/lrint.h"
+
+};
+
+int main(void)
+{
+       #pragma STDC FENV_ACCESS ON
+       int yi;
+       float d;
+       int e, i, err = 0;
+       struct d_i *p;
+
+       for (i = 0; i < sizeof t/sizeof *t; i++) {
+               p = t + i;
+
+               if (p->r < 0)
+                       continue;
+               fesetround(p->r);
+               feclearexcept(FE_ALL_EXCEPT);
+               yi = lrint(p->x);
+               e = fetestexcept(INEXACT|INVALID|DIVBYZERO|UNDERFLOW|OVERFLOW);
+
+               if (!checkexcept(e, p->e, p->r)) {
+                       printf("%s:%d: bad fp exception: %s lrint(%a)=%lld, want %s",
+                               p->file, p->line, rstr(p->r), p->x, p->i, estr(p->e));
+                       printf(" got %s\n", estr(e));
+                       err++;
+               }
+               if (yi != p->i) {
+                       printf("%s:%d: %s lrint(%a) want %lld got %d\n",
+                               p->file, p->line, rstr(p->r), p->x, p->i, yi);
+                       err++;
+               }
+       }
+       return !!err;
+}
diff --git a/src/math/lrintf.c b/src/math/lrintf.c
new file mode 100644 (file)
index 0000000..87754aa
--- /dev/null
@@ -0,0 +1,41 @@
+#include <stdint.h>
+#include <stdio.h>
+#include "util.h"
+
+static struct f_i t[] = {
+#include "sanity/lrintf.h"
+
+};
+
+int main(void)
+{
+       #pragma STDC FENV_ACCESS ON
+       int yi;
+       float d;
+       int e, i, err = 0;
+       struct f_i *p;
+
+       for (i = 0; i < sizeof t/sizeof *t; i++) {
+               p = t + i;
+
+               if (p->r < 0)
+                       continue;
+               fesetround(p->r);
+               feclearexcept(FE_ALL_EXCEPT);
+               yi = lrintf(p->x);
+               e = fetestexcept(INEXACT|INVALID|DIVBYZERO|UNDERFLOW|OVERFLOW);
+
+               if (!checkexcept(e, p->e, p->r)) {
+                       printf("%s:%d: bad fp exception: %s lrintf(%a)=%lld, want %s",
+                               p->file, p->line, rstr(p->r), p->x, p->i, estr(p->e));
+                       printf(" got %s\n", estr(e));
+                       err++;
+               }
+               if (yi != p->i) {
+                       printf("%s:%d: %s lrintf(%a) want %lld got %d\n",
+                               p->file, p->line, rstr(p->r), p->x, p->i, yi);
+                       err++;
+               }
+       }
+       return !!err;
+}
diff --git a/src/math/lrintl.c b/src/math/lrintl.c
new file mode 100644 (file)
index 0000000..bb2756b
--- /dev/null
@@ -0,0 +1,46 @@
+#include <stdint.h>
+#include <stdio.h>
+#include "util.h"
+
+static struct l_i t[] = {
+#if LDBL_MANT_DIG == 53
+#include "sanity/lrint.h"
+
+#elif LDBL_MANT_DIG == 64
+#include "sanity/lrintl.h"
+
+#endif
+};
+
+int main(void)
+{
+       #pragma STDC FENV_ACCESS ON
+       int yi;
+       float d;
+       int e, i, err = 0;
+       struct l_i *p;
+
+       for (i = 0; i < sizeof t/sizeof *t; i++) {
+               p = t + i;
+
+               if (p->r < 0)
+                       continue;
+               fesetround(p->r);
+               feclearexcept(FE_ALL_EXCEPT);
+               yi = lrintl(p->x);
+               e = fetestexcept(INEXACT|INVALID|DIVBYZERO|UNDERFLOW|OVERFLOW);
+
+               if (!checkexcept(e, p->e, p->r)) {
+                       printf("%s:%d: bad fp exception: %s lrintl(%La)=%lld, want %s",
+                               p->file, p->line, rstr(p->r), p->x, p->i, estr(p->e));
+                       printf(" got %s\n", estr(e));
+                       err++;
+               }
+               if (yi != p->i) {
+                       printf("%s:%d: %s lrintl(%La) want %lld got %d\n",
+                               p->file, p->line, rstr(p->r), p->x, p->i, yi);
+                       err++;
+               }
+       }
+       return !!err;
+}
diff --git a/src/math/lround.c b/src/math/lround.c
new file mode 100644 (file)
index 0000000..51ca347
--- /dev/null
@@ -0,0 +1,41 @@
+#include <stdint.h>
+#include <stdio.h>
+#include "util.h"
+
+static struct d_i t[] = {
+#include "sanity/lround.h"
+
+};
+
+int main(void)
+{
+       #pragma STDC FENV_ACCESS ON
+       int yi;
+       float d;
+       int e, i, err = 0;
+       struct d_i *p;
+
+       for (i = 0; i < sizeof t/sizeof *t; i++) {
+               p = t + i;
+
+               if (p->r < 0)
+                       continue;
+               fesetround(p->r);
+               feclearexcept(FE_ALL_EXCEPT);
+               yi = lround(p->x);
+               e = fetestexcept(INEXACT|INVALID|DIVBYZERO|UNDERFLOW|OVERFLOW);
+
+               if (!checkexcept(e, p->e, p->r)) {
+                       printf("%s:%d: bad fp exception: %s lround(%a)=%lld, want %s",
+                               p->file, p->line, rstr(p->r), p->x, p->i, estr(p->e));
+                       printf(" got %s\n", estr(e));
+                       err++;
+               }
+               if (yi != p->i) {
+                       printf("%s:%d: %s lround(%a) want %lld got %d\n",
+                               p->file, p->line, rstr(p->r), p->x, p->i, yi);
+                       err++;
+               }
+       }
+       return !!err;
+}
diff --git a/src/math/lroundf.c b/src/math/lroundf.c
new file mode 100644 (file)
index 0000000..8590289
--- /dev/null
@@ -0,0 +1,41 @@
+#include <stdint.h>
+#include <stdio.h>
+#include "util.h"
+
+static struct f_i t[] = {
+#include "sanity/lroundf.h"
+
+};
+
+int main(void)
+{
+       #pragma STDC FENV_ACCESS ON
+       int yi;
+       float d;
+       int e, i, err = 0;
+       struct f_i *p;
+
+       for (i = 0; i < sizeof t/sizeof *t; i++) {
+               p = t + i;
+
+               if (p->r < 0)
+                       continue;
+               fesetround(p->r);
+               feclearexcept(FE_ALL_EXCEPT);
+               yi = lroundf(p->x);
+               e = fetestexcept(INEXACT|INVALID|DIVBYZERO|UNDERFLOW|OVERFLOW);
+
+               if (!checkexcept(e, p->e, p->r)) {
+                       printf("%s:%d: bad fp exception: %s lroundf(%a)=%lld, want %s",
+                               p->file, p->line, rstr(p->r), p->x, p->i, estr(p->e));
+                       printf(" got %s\n", estr(e));
+                       err++;
+               }
+               if (yi != p->i) {
+                       printf("%s:%d: %s lroundf(%a) want %lld got %d\n",
+                               p->file, p->line, rstr(p->r), p->x, p->i, yi);
+                       err++;
+               }
+       }
+       return !!err;
+}
diff --git a/src/math/lroundl.c b/src/math/lroundl.c
new file mode 100644 (file)
index 0000000..45f8925
--- /dev/null
@@ -0,0 +1,46 @@
+#include <stdint.h>
+#include <stdio.h>
+#include "util.h"
+
+static struct l_i t[] = {
+#if LDBL_MANT_DIG == 53
+#include "sanity/lround.h"
+
+#elif LDBL_MANT_DIG == 64
+#include "sanity/lroundl.h"
+
+#endif
+};
+
+int main(void)
+{
+       #pragma STDC FENV_ACCESS ON
+       int yi;
+       float d;
+       int e, i, err = 0;
+       struct l_i *p;
+
+       for (i = 0; i < sizeof t/sizeof *t; i++) {
+               p = t + i;
+
+               if (p->r < 0)
+                       continue;
+               fesetround(p->r);
+               feclearexcept(FE_ALL_EXCEPT);
+               yi = lroundl(p->x);
+               e = fetestexcept(INEXACT|INVALID|DIVBYZERO|UNDERFLOW|OVERFLOW);
+
+               if (!checkexcept(e, p->e, p->r)) {
+                       printf("%s:%d: bad fp exception: %s lroundl(%La)=%lld, want %s",
+                               p->file, p->line, rstr(p->r), p->x, p->i, estr(p->e));
+                       printf(" got %s\n", estr(e));
+                       err++;
+               }
+               if (yi != p->i) {
+                       printf("%s:%d: %s lroundl(%La) want %lld got %d\n",
+                               p->file, p->line, rstr(p->r), p->x, p->i, yi);
+                       err++;
+               }
+       }
+       return !!err;
+}
diff --git a/src/math/sanity/llrint.h b/src/math/sanity/llrint.h
new file mode 100644 (file)
index 0000000..842f6dd
--- /dev/null
@@ -0,0 +1,10 @@
+T(RN,   -0x1.02239f3c6a8f1p+3, -8, INEXACT)
+T(RN,    0x1.161868e18bc67p+2, 4, INEXACT)
+T(RN,   -0x1.0c34b3e01e6e7p+3, -8, INEXACT)
+T(RN,   -0x1.a206f0a19dcc4p+2, -7, INEXACT)
+T(RN,    0x1.288bbb0d6a1e6p+3, 9, INEXACT)
+T(RN,    0x1.52efd0cd80497p-1, 1, INEXACT)
+T(RN,   -0x1.a05cc754481d1p-2, 0, INEXACT)
+T(RN,    0x1.1f9ef934745cbp-1, 1, INEXACT)
+T(RN,    0x1.8c5db097f7442p-1, 1, INEXACT)
+T(RN,   -0x1.5b86ea8118a0ep-1, -1, INEXACT)
diff --git a/src/math/sanity/llrintf.h b/src/math/sanity/llrintf.h
new file mode 100644 (file)
index 0000000..6ce24b3
--- /dev/null
@@ -0,0 +1,10 @@
+T(RN,   -0x1.0223ap+3, -8, INEXACT)
+T(RN,   0x1.161868p+2, 4, INEXACT)
+T(RN,  -0x1.0c34b4p+3, -8, INEXACT)
+T(RN,   -0x1.a206fp+2, -7, INEXACT)
+T(RN,   0x1.288bbcp+3, 9, INEXACT)
+T(RN,    0x1.52efdp-1, 1, INEXACT)
+T(RN,  -0x1.a05cc8p-2, 0, INEXACT)
+T(RN,   0x1.1f9efap-1, 1, INEXACT)
+T(RN,    0x1.8c5dbp-1, 1, INEXACT)
+T(RN,  -0x1.5b86eap-1, -1, INEXACT)
diff --git a/src/math/sanity/llrintl.h b/src/math/sanity/llrintl.h
new file mode 100644 (file)
index 0000000..9eda6b0
--- /dev/null
@@ -0,0 +1,10 @@
+T(RN,      -0x1.02239f3c6a8f13dep+3L, -8, INEXACT)
+T(RN,       0x1.161868e18bc67782p+2L, 4, INEXACT)
+T(RN,      -0x1.0c34b3e01e6e682cp+3L, -8, INEXACT)
+T(RN,      -0x1.a206f0a19dcc3948p+2L, -7, INEXACT)
+T(RN,       0x1.288bbb0d6a1e5bdap+3L, 9, INEXACT)
+T(RN,       0x1.52efd0cd80496a5ap-1L, 1, INEXACT)
+T(RN,       -0x1.a05cc754481d0bdp-2L, 0, INEXACT)
+T(RN,        0x1.1f9ef934745cad6p-1L, 1, INEXACT)
+T(RN,       0x1.8c5db097f744257ep-1L, 1, INEXACT)
+T(RN,      -0x1.5b86ea8118a0e2bcp-1L, -1, INEXACT)
diff --git a/src/math/sanity/llround.h b/src/math/sanity/llround.h
new file mode 100644 (file)
index 0000000..842f6dd
--- /dev/null
@@ -0,0 +1,10 @@
+T(RN,   -0x1.02239f3c6a8f1p+3, -8, INEXACT)
+T(RN,    0x1.161868e18bc67p+2, 4, INEXACT)
+T(RN,   -0x1.0c34b3e01e6e7p+3, -8, INEXACT)
+T(RN,   -0x1.a206f0a19dcc4p+2, -7, INEXACT)
+T(RN,    0x1.288bbb0d6a1e6p+3, 9, INEXACT)
+T(RN,    0x1.52efd0cd80497p-1, 1, INEXACT)
+T(RN,   -0x1.a05cc754481d1p-2, 0, INEXACT)
+T(RN,    0x1.1f9ef934745cbp-1, 1, INEXACT)
+T(RN,    0x1.8c5db097f7442p-1, 1, INEXACT)
+T(RN,   -0x1.5b86ea8118a0ep-1, -1, INEXACT)
diff --git a/src/math/sanity/llroundf.h b/src/math/sanity/llroundf.h
new file mode 100644 (file)
index 0000000..6ce24b3
--- /dev/null
@@ -0,0 +1,10 @@
+T(RN,   -0x1.0223ap+3, -8, INEXACT)
+T(RN,   0x1.161868p+2, 4, INEXACT)
+T(RN,  -0x1.0c34b4p+3, -8, INEXACT)
+T(RN,   -0x1.a206fp+2, -7, INEXACT)
+T(RN,   0x1.288bbcp+3, 9, INEXACT)
+T(RN,    0x1.52efdp-1, 1, INEXACT)
+T(RN,  -0x1.a05cc8p-2, 0, INEXACT)
+T(RN,   0x1.1f9efap-1, 1, INEXACT)
+T(RN,    0x1.8c5dbp-1, 1, INEXACT)
+T(RN,  -0x1.5b86eap-1, -1, INEXACT)
diff --git a/src/math/sanity/llroundl.h b/src/math/sanity/llroundl.h
new file mode 100644 (file)
index 0000000..9eda6b0
--- /dev/null
@@ -0,0 +1,10 @@
+T(RN,      -0x1.02239f3c6a8f13dep+3L, -8, INEXACT)
+T(RN,       0x1.161868e18bc67782p+2L, 4, INEXACT)
+T(RN,      -0x1.0c34b3e01e6e682cp+3L, -8, INEXACT)
+T(RN,      -0x1.a206f0a19dcc3948p+2L, -7, INEXACT)
+T(RN,       0x1.288bbb0d6a1e5bdap+3L, 9, INEXACT)
+T(RN,       0x1.52efd0cd80496a5ap-1L, 1, INEXACT)
+T(RN,       -0x1.a05cc754481d0bdp-2L, 0, INEXACT)
+T(RN,        0x1.1f9ef934745cad6p-1L, 1, INEXACT)
+T(RN,       0x1.8c5db097f744257ep-1L, 1, INEXACT)
+T(RN,      -0x1.5b86ea8118a0e2bcp-1L, -1, INEXACT)
diff --git a/src/math/sanity/lrint.h b/src/math/sanity/lrint.h
new file mode 100644 (file)
index 0000000..842f6dd
--- /dev/null
@@ -0,0 +1,10 @@
+T(RN,   -0x1.02239f3c6a8f1p+3, -8, INEXACT)
+T(RN,    0x1.161868e18bc67p+2, 4, INEXACT)
+T(RN,   -0x1.0c34b3e01e6e7p+3, -8, INEXACT)
+T(RN,   -0x1.a206f0a19dcc4p+2, -7, INEXACT)
+T(RN,    0x1.288bbb0d6a1e6p+3, 9, INEXACT)
+T(RN,    0x1.52efd0cd80497p-1, 1, INEXACT)
+T(RN,   -0x1.a05cc754481d1p-2, 0, INEXACT)
+T(RN,    0x1.1f9ef934745cbp-1, 1, INEXACT)
+T(RN,    0x1.8c5db097f7442p-1, 1, INEXACT)
+T(RN,   -0x1.5b86ea8118a0ep-1, -1, INEXACT)
diff --git a/src/math/sanity/lrintf.h b/src/math/sanity/lrintf.h
new file mode 100644 (file)
index 0000000..6ce24b3
--- /dev/null
@@ -0,0 +1,10 @@
+T(RN,   -0x1.0223ap+3, -8, INEXACT)
+T(RN,   0x1.161868p+2, 4, INEXACT)
+T(RN,  -0x1.0c34b4p+3, -8, INEXACT)
+T(RN,   -0x1.a206fp+2, -7, INEXACT)
+T(RN,   0x1.288bbcp+3, 9, INEXACT)
+T(RN,    0x1.52efdp-1, 1, INEXACT)
+T(RN,  -0x1.a05cc8p-2, 0, INEXACT)
+T(RN,   0x1.1f9efap-1, 1, INEXACT)
+T(RN,    0x1.8c5dbp-1, 1, INEXACT)
+T(RN,  -0x1.5b86eap-1, -1, INEXACT)
diff --git a/src/math/sanity/lrintl.h b/src/math/sanity/lrintl.h
new file mode 100644 (file)
index 0000000..9eda6b0
--- /dev/null
@@ -0,0 +1,10 @@
+T(RN,      -0x1.02239f3c6a8f13dep+3L, -8, INEXACT)
+T(RN,       0x1.161868e18bc67782p+2L, 4, INEXACT)
+T(RN,      -0x1.0c34b3e01e6e682cp+3L, -8, INEXACT)
+T(RN,      -0x1.a206f0a19dcc3948p+2L, -7, INEXACT)
+T(RN,       0x1.288bbb0d6a1e5bdap+3L, 9, INEXACT)
+T(RN,       0x1.52efd0cd80496a5ap-1L, 1, INEXACT)
+T(RN,       -0x1.a05cc754481d0bdp-2L, 0, INEXACT)
+T(RN,        0x1.1f9ef934745cad6p-1L, 1, INEXACT)
+T(RN,       0x1.8c5db097f744257ep-1L, 1, INEXACT)
+T(RN,      -0x1.5b86ea8118a0e2bcp-1L, -1, INEXACT)
diff --git a/src/math/sanity/lround.h b/src/math/sanity/lround.h
new file mode 100644 (file)
index 0000000..842f6dd
--- /dev/null
@@ -0,0 +1,10 @@
+T(RN,   -0x1.02239f3c6a8f1p+3, -8, INEXACT)
+T(RN,    0x1.161868e18bc67p+2, 4, INEXACT)
+T(RN,   -0x1.0c34b3e01e6e7p+3, -8, INEXACT)
+T(RN,   -0x1.a206f0a19dcc4p+2, -7, INEXACT)
+T(RN,    0x1.288bbb0d6a1e6p+3, 9, INEXACT)
+T(RN,    0x1.52efd0cd80497p-1, 1, INEXACT)
+T(RN,   -0x1.a05cc754481d1p-2, 0, INEXACT)
+T(RN,    0x1.1f9ef934745cbp-1, 1, INEXACT)
+T(RN,    0x1.8c5db097f7442p-1, 1, INEXACT)
+T(RN,   -0x1.5b86ea8118a0ep-1, -1, INEXACT)
diff --git a/src/math/sanity/lroundf.h b/src/math/sanity/lroundf.h
new file mode 100644 (file)
index 0000000..6ce24b3
--- /dev/null
@@ -0,0 +1,10 @@
+T(RN,   -0x1.0223ap+3, -8, INEXACT)
+T(RN,   0x1.161868p+2, 4, INEXACT)
+T(RN,  -0x1.0c34b4p+3, -8, INEXACT)
+T(RN,   -0x1.a206fp+2, -7, INEXACT)
+T(RN,   0x1.288bbcp+3, 9, INEXACT)
+T(RN,    0x1.52efdp-1, 1, INEXACT)
+T(RN,  -0x1.a05cc8p-2, 0, INEXACT)
+T(RN,   0x1.1f9efap-1, 1, INEXACT)
+T(RN,    0x1.8c5dbp-1, 1, INEXACT)
+T(RN,  -0x1.5b86eap-1, -1, INEXACT)
diff --git a/src/math/sanity/lroundl.h b/src/math/sanity/lroundl.h
new file mode 100644 (file)
index 0000000..9eda6b0
--- /dev/null
@@ -0,0 +1,10 @@
+T(RN,      -0x1.02239f3c6a8f13dep+3L, -8, INEXACT)
+T(RN,       0x1.161868e18bc67782p+2L, 4, INEXACT)
+T(RN,      -0x1.0c34b3e01e6e682cp+3L, -8, INEXACT)
+T(RN,      -0x1.a206f0a19dcc3948p+2L, -7, INEXACT)
+T(RN,       0x1.288bbb0d6a1e5bdap+3L, 9, INEXACT)
+T(RN,       0x1.52efd0cd80496a5ap-1L, 1, INEXACT)
+T(RN,       -0x1.a05cc754481d0bdp-2L, 0, INEXACT)
+T(RN,        0x1.1f9ef934745cad6p-1L, 1, INEXACT)
+T(RN,       0x1.8c5db097f744257ep-1L, 1, INEXACT)
+T(RN,      -0x1.5b86ea8118a0e2bcp-1L, -1, INEXACT)