err++;
}
d = ulperrf(y, p->y, p->dy);
- if (!checkulp(d, p->r)) {
+ if (!checkulp(d, p->r) || yi != p->i) {
printf("%s:%d: %s frexpf(%a) want %a,%lld got %a,%d ulperr %.3f = %a + %a\n",
p->file, p->line, rstr(p->r), p->x, p->y, p->i, y, yi, d, d-p->dy, p->dy);
err++;
T(lgamma_r, d_di)
T(lgammaf_r, f_fi)
T(lgammal_r, l_li)
+T(ilogb, d_i)
+T(ilogbf, f_i)
+T(ilogbl, l_i)
#define inf INFINITY
#define nan NAN
-struct f1 { int r; float x; float y; float dy; int e; };
-struct f2 { int r; float x; float x2; float y; float dy; int e; };
-struct d1 { int r; double x; double y; float dy; int e; };
-struct d2 { int r; double x; double x2; double y; float dy; int e; };
-struct l1 { int r; long double x; long double y; float dy; int e; };
-struct l2 { int r; long double x; long double x2; long double y; float dy; int e; };
-
struct t {
int type;
int r;
int mplgamma_r(struct t *t) { return mplgamma(t); }
int mplgammaf_r(struct t *t) { return mplgammaf(t); }
int mplgammal_r(struct t *t) { return mplgammal(t); }
+
+int mpilogb(struct t *t)
+{
+ MPFR_DECL_INIT(mx, 53);
+
+ mpfr_set_d(mx, t->x, MPFR_RNDN);
+ t->i = mpfr_get_exp(mx) - 1;
+ t->e = 0;
+ return 0;
+}
+int mpilogbf(struct t *t)
+{
+ MPFR_DECL_INIT(mx, 24);
+
+ mpfr_set_flt(mx, t->x, MPFR_RNDN);
+ t->i = mpfr_get_exp(mx) - 1;
+ t->e = 0;
+ return 0;
+}
+int mpilogbl(struct t *t)
+{
+ MPFR_DECL_INIT(mx, 64);
+
+ mpfr_set_ld(mx, t->x, MPFR_RNDN);
+ t->i = mpfr_get_exp(mx) - 1;
+ t->e = 0;
+ return 0;
+}
+
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;
+}
+
--- /dev/null
+#include <stdint.h>
+#include <stdio.h>
+#include "util.h"
+
+static struct d_i t[] = {
+HEADERS
+};
+
+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 = ___(p->x);
+ e = fetestexcept(INEXACT|INVALID|DIVBYZERO|UNDERFLOW|OVERFLOW);
+
+ if (!checkexcept(e, p->e, p->r)) {
+ printf("%s:%d: bad fp exception: %s ___(%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 ___(%a) want %lld got %d\n",
+ p->file, p->line, rstr(p->r), p->x, p->i, yi);
+ err++;
+ }
+ }
+ return !!err;
+}
err++;
}
d = ulperrf(y, p->y, p->dy);
- if (!checkulp(d, p->r)) {
+ if (!checkulp(d, p->r) || yi != p->i) {
printf("%s:%d: %s ___(%a) want %a,%lld got %a,%d ulperr %.3f = %a + %a\n",
p->file, p->line, rstr(p->r), p->x, p->y, p->i, y, yi, d, d-p->dy, p->dy);
err++;
--- /dev/null
+#include <stdint.h>
+#include <stdio.h>
+#include "util.h"
+
+static struct f_i t[] = {
+HEADERS
+};
+
+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 = ___(p->x);
+ e = fetestexcept(INEXACT|INVALID|DIVBYZERO|UNDERFLOW|OVERFLOW);
+
+ if (!checkexcept(e, p->e, p->r)) {
+ printf("%s:%d: bad fp exception: %s ___(%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 ___(%a) want %lld got %d\n",
+ p->file, p->line, rstr(p->r), p->x, p->i, yi);
+ err++;
+ }
+ }
+ return !!err;
+}
--- /dev/null
+#include <stdint.h>
+#include <stdio.h>
+#include "util.h"
+
+static struct l_i t[] = {
+#if LDBL_MANT_DIG == 53
+DHEADERS
+#elif LDBL_MANT_DIG == 64
+HEADERS
+#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 = ___(p->x);
+ e = fetestexcept(INEXACT|INVALID|DIVBYZERO|UNDERFLOW|OVERFLOW);
+
+ if (!checkexcept(e, p->e, p->r)) {
+ printf("%s:%d: bad fp exception: %s ___(%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 ___(%La) want %lld got %d\n",
+ p->file, p->line, rstr(p->r), p->x, p->i, yi);
+ err++;
+ }
+ }
+ return !!err;
+}
--- /dev/null
+#include <stdint.h>
+#include <stdio.h>
+#include "util.h"
+
+static struct d_i t[] = {
+#include "sanity/ilogb.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 = ilogb(p->x);
+ e = fetestexcept(INEXACT|INVALID|DIVBYZERO|UNDERFLOW|OVERFLOW);
+
+ if (!checkexcept(e, p->e, p->r)) {
+ printf("%s:%d: bad fp exception: %s ilogb(%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 ilogb(%a) want %lld got %d\n",
+ p->file, p->line, rstr(p->r), p->x, p->i, yi);
+ err++;
+ }
+ }
+ return !!err;
+}
--- /dev/null
+#include <stdint.h>
+#include <stdio.h>
+#include "util.h"
+
+static struct f_i t[] = {
+#include "sanity/ilogbf.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 = ilogbf(p->x);
+ e = fetestexcept(INEXACT|INVALID|DIVBYZERO|UNDERFLOW|OVERFLOW);
+
+ if (!checkexcept(e, p->e, p->r)) {
+ printf("%s:%d: bad fp exception: %s ilogbf(%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 ilogbf(%a) want %lld got %d\n",
+ p->file, p->line, rstr(p->r), p->x, p->i, yi);
+ err++;
+ }
+ }
+ return !!err;
+}
--- /dev/null
+#include <stdint.h>
+#include <stdio.h>
+#include "util.h"
+
+static struct l_i t[] = {
+#if LDBL_MANT_DIG == 53
+#include "sanity/ilogb.h"
+
+#elif LDBL_MANT_DIG == 64
+#include "sanity/ilogbl.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 = ilogbl(p->x);
+ e = fetestexcept(INEXACT|INVALID|DIVBYZERO|UNDERFLOW|OVERFLOW);
+
+ if (!checkexcept(e, p->e, p->r)) {
+ printf("%s:%d: bad fp exception: %s ilogbl(%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 ilogbl(%La) want %lld got %d\n",
+ p->file, p->line, rstr(p->r), p->x, p->i, yi);
+ err++;
+ }
+ }
+ return !!err;
+}
err++;
}
d = ulperrf(y, p->y, p->dy);
- if (!checkulp(d, p->r)) {
+ if (!checkulp(d, p->r) || yi != p->i) {
printf("%s:%d: %s lgammaf(%a) want %a,%lld got %a,%d ulperr %.3f = %a + %a\n",
p->file, p->line, rstr(p->r), p->x, p->y, p->i, y, yi, d, d-p->dy, p->dy);
err++;
err++;
}
d = ulperrf(y, p->y, p->dy);
- if (!checkulp(d, p->r)) {
+ if (!checkulp(d, p->r) || yi != p->i) {
printf("%s:%d: %s lgammaf_r(%a) want %a,%lld got %a,%d ulperr %.3f = %a + %a\n",
p->file, p->line, rstr(p->r), p->x, p->y, p->i, y, yi, d, d-p->dy, p->dy);
err++;
--- /dev/null
+T(RN, -0x1.02239f3c6a8f1p+3, 3, 0)
+T(RN, 0x1.161868e18bc67p+2, 2, 0)
+T(RN, -0x1.0c34b3e01e6e7p+3, 3, 0)
+T(RN, -0x1.a206f0a19dcc4p+2, 2, 0)
+T(RN, 0x1.288bbb0d6a1e6p+3, 3, 0)
+T(RN, 0x1.52efd0cd80497p-1, -1, 0)
+T(RN, -0x1.a05cc754481d1p-2, -2, 0)
+T(RN, 0x1.1f9ef934745cbp-1, -1, 0)
+T(RN, 0x1.8c5db097f7442p-1, -1, 0)
+T(RN, -0x1.5b86ea8118a0ep-1, -1, 0)
--- /dev/null
+T(RN, -0x1.0223ap+3, 3, 0)
+T(RN, 0x1.161868p+2, 2, 0)
+T(RN, -0x1.0c34b4p+3, 3, 0)
+T(RN, -0x1.a206fp+2, 2, 0)
+T(RN, 0x1.288bbcp+3, 3, 0)
+T(RN, 0x1.52efdp-1, -1, 0)
+T(RN, -0x1.a05cc8p-2, -2, 0)
+T(RN, 0x1.1f9efap-1, -1, 0)
+T(RN, 0x1.8c5dbp-1, -1, 0)
+T(RN, -0x1.5b86eap-1, -1, 0)
--- /dev/null
+T(RN, -0x1.02239f3c6a8f13dep+3L, 3, 0)
+T(RN, 0x1.161868e18bc67782p+2L, 2, 0)
+T(RN, -0x1.0c34b3e01e6e682cp+3L, 3, 0)
+T(RN, -0x1.a206f0a19dcc3948p+2L, 2, 0)
+T(RN, 0x1.288bbb0d6a1e5bdap+3L, 3, 0)
+T(RN, 0x1.52efd0cd80496a5ap-1L, -1, 0)
+T(RN, -0x1.a05cc754481d0bdp-2L, -2, 0)
+T(RN, 0x1.1f9ef934745cad6p-1L, -1, 0)
+T(RN, 0x1.8c5db097f744257ep-1L, -1, 0)
+T(RN, -0x1.5b86ea8118a0e2bcp-1L, -1, 0)
+++ /dev/null
-T(RN, -0x1.02239f3c6a8f13dep+3L, 0x1.3ecac9327b83da68p-3L, -0x1.ca2bf8p-5, INEXACT)
-T(RN, 0x1.161868e18bc67782p+2L, -0x1.69612a9105745e1p-2L, -0x1.cbcae6p-4, INEXACT)
-T(RN, -0x1.0c34b3e01e6e682cp+3L, 0x1.2fd575f8ad8c5192p-4L, -0x1.c21578p-2, INEXACT)
-T(RN, -0x1.a206f0a19dcc3948p+2L, 0x1.0f2e220b69812a82p-2L, -0x1.60a902p-3, INEXACT)
-T(RN, 0x1.288bbb0d6a1e5bdap+3L, -0x1.3528d44599375b04p-3L, -0x1.4a0b2p-2, INEXACT)
-T(RN, 0x1.52efd0cd80496a5ap-1L, 0x1.c96cc73e4a92d2dap-1L, -0x1.1a88cp-2, INEXACT)
-T(RN, -0x1.a05cc754481d0bdp-2L, 0x1.eb0e4b64aa8d73b8p-1L, -0x1.0cd56p-2, INEXACT)
-T(RN, 0x1.1f9ef934745cad6p-1L, 0x1.d865721eff3120b2p-1L, 0x1.ac5aa6p-2, INEXACT)
-T(RN, 0x1.8c5db097f744257ep-1L, 0x1.b61d359fb77bcd54p-1L, -0x1.cb8a56p-2, INEXACT)
-T(RN, -0x1.5b86ea8118a0e2bcp-1L, 0x1.c6b4501b05a3741ap-1L, 0x1.950002p-3, INEXACT)
+++ /dev/null
-T(RN, -0x1.02239f3c6a8f13dep+3L, -0x1.f2def55fbf5a9384p-3L, -0x1.07c388p-2, INEXACT)
-T(RN, 0x1.161868e18bc67782p+2L, -0x1.7d48aacc4b124218p-3L, 0x1.5c39a2p-3, INEXACT)
-T(RN, -0x1.0c34b3e01e6e682cp+3L, -0x1.14890a09c4ef434p-2L, 0x1.373684p-4, INEXACT)
-T(RN, -0x1.a206f0a19dcc3948p+2L, 0x1.288dbd86fec97402p-3L, 0x1.d09fp-2, INEXACT)
-T(RN, 0x1.288bbb0d6a1e5bdap+3L, 0x1.a6564e6ccad3f18cp-3L, 0x1.55bb0ep-3, INEXACT)
-T(RN, 0x1.52efd0cd80496a5ap-1L, 0x1.40b4d5149fe157c4p-2L, -0x1.47bccap-3, INEXACT)
-T(RN, -0x1.a05cc754481d0bdp-2L, -0x1.97d1273f3fd01b56p-3L, -0x1.58719ep-3, INEXACT)
-T(RN, 0x1.1f9ef934745cad6p-1L, 0x1.146c6965ab4ce622p-2L, -0x1.5c5a7cp-4, INEXACT)
-T(RN, 0x1.8c5db097f744257ep-1L, 0x1.6f67a8cdd55148dcp-2L, -0x1.5dd1e6p-2, INEXACT)
-T(RN, -0x1.5b86ea8118a0e2bcp-1L, -0x1.47e4ba219f50ec6ap-2L, 0x1.2d38ep-2, INEXACT)
+++ /dev/null
-T(RN, -0x1.02239f3c6a8f13dep+3L, nan, 0x0p+0, INVALID)
-T(RN, 0x1.161868e18bc67782p+2L, -0x1.293dc7b9b494bb34p-3L, 0x1.bcf78cp-2, INEXACT)
-T(RN, -0x1.0c34b3e01e6e682cp+3L, nan, 0x0p+0, INVALID)
-T(RN, -0x1.a206f0a19dcc3948p+2L, nan, 0x0p+0, INVALID)
-T(RN, 0x1.288bbb0d6a1e5bdap+3L, 0x1.b65800c37acbd066p-3L, 0x1.44eb34p-2, INEXACT)
-T(RN, 0x1.52efd0cd80496a5ap-1L, -0x1.de7c075a80e46016p-3L, -0x1.bee94p-2, INEXACT)
-T(RN, -0x1.a05cc754481d0bdp-2L, nan, 0x0p+0, INVALID)
-T(RN, 0x1.1f9ef934745cad6p-1L, -0x1.6ea9b7e5ba012c86p-2L, -0x1.f725e2p-2, INEXACT)
-T(RN, 0x1.8c5db097f744257ep-1L, -0x1.ccadb2ae7e0f1ef2p-4L, 0x1.e9404cp-5, INEXACT)
-T(RN, -0x1.5b86ea8118a0e2bcp-1L, nan, 0x0p+0, INVALID)
+++ /dev/null
-T(RN, -0x1.02239f3c6a8f13dep+3L, nan, 0x0p+0, INVALID)
-T(RN, 0x1.161868e18bc67782p+2L, 0x1.5ab54680a596400ep-2L, -0x1.cddd8ap-3, INEXACT)
-T(RN, -0x1.0c34b3e01e6e682cp+3L, nan, 0x0p+0, INVALID)
-T(RN, -0x1.a206f0a19dcc3948p+2L, nan, 0x0p+0, INVALID)
-T(RN, 0x1.288bbb0d6a1e5bdap+3L, 0x1.4d2f9a5b066b0c1ap-3L, -0x1.e2f31p-2, INEXACT)
-T(RN, 0x1.52efd0cd80496a5ap-1L, -0x1.2887c4a1be0bb6aap+0L, -0x1.bba6bcp-2, INEXACT)
-T(RN, -0x1.a05cc754481d0bdp-2L, nan, 0x0p+0, INVALID)
-T(RN, 0x1.1f9ef934745cad6p-1L, -0x1.55417537f9faceaap+0L, 0x1.71da42p-2, INEXACT)
-T(RN, 0x1.8c5db097f744257ep-1L, -0x1.02189c42315d140cp+0L, -0x1.9c5444p-3, INEXACT)
-T(RN, -0x1.5b86ea8118a0e2bcp-1L, nan, 0x0p+0, INVALID)
struct di_d {POS int r; double x; long long i; double y; float dy; int e; };
struct fi_f {POS int r; float x; long long i; float y; float dy; int e; };
struct li_l {POS int r; long double x; long long i; long double y; float dy; int e; };
+struct d_i {POS int r; double x; long long i; int e; };
+struct f_i {POS int r; float x; long long i; int e; };
+struct l_i {POS int r; long double x; long long i; int e; };
#undef POS
char *estr(int);