9 union { float f; uint32_t i; } u = { x };
10 int e = u.i>>23 & 0xff;
19 union { double f; uint64_t i; } u = { x };
20 int e = u.i>>52 & 0x7ff;
24 return e - 0x3ff - 52;
27 int eulpl(long double x)
29 #if LDBL_MANT_DIG == 53
31 #elif LDBL_MANT_DIG == 64
32 union { long double f; struct {uint64_t m; uint16_t e; uint16_t pad;} i; } u = { x };
33 int e = u.i.e & 0x7fff;
37 return e - 0x3fff - 63;
44 double ulperr(double y, double ycr, double dy)
46 return dy + scalbn(ycr - y, -eulp(ycr));
49 char *skipstr(char *buf, char *sep)
51 while (*buf && strchr(sep, *buf))
56 int splitstr(char **a, int n, char *buf, char *sep)
60 for (i = j = 0; j < n; j++) {
61 for (; buf[i] && strchr(sep, buf[i]); i++)
66 for (i++; buf[i] && !strchr(sep, buf[i]); i++);
71 char *dropcomm(char *buf)
76 if ((*p == '/' && p[1] == '/') || *p == '#') {
83 #define length(a) (sizeof(a)/sizeof(*a))
84 #define flag(x) {x, #x}
102 for (i = 0; i < length(eflags); i++)
103 if (f & eflags[i].flag) {
104 p += sprintf(p, "%s%s", all ? "|" : "", eflags[i].s);
105 all |= eflags[i].flag;
108 p += sprintf(p, "%s%d", all ? "|" : "", f & ~all);
111 p += sprintf(p, "%s", all ? "" : "0");
115 int econv(int *f, char *s)
122 n = splitstr(a, length(a), s, "|");
123 for (i = 0; i < n; i++) {
124 for (j = 0; j < length(eflags); j++)
125 if (strcmp(a[i], eflags[j].s) == 0) {
126 *f |= eflags[j].flag;
129 if (j == length(eflags)) {
130 k = strtol(a[i], &e, 0);
142 case RN: return "RN";
143 case RZ: return "RZ";
144 case RU: return "RU";
145 case RD: return "RD";
150 int rconv(int *r, char *s)
152 if (strcmp(s, "RN") == 0)
154 else if (strcmp(s, "RZ") == 0)
156 else if (strcmp(s, "RD") == 0)
158 else if (strcmp(s, "RU") == 0)
165 void setupfenv(int r)
168 feclearexcept(FE_ALL_EXCEPT);
173 return fetestexcept(INEXACT|INVALID|DIVBYZERO|UNDERFLOW|OVERFLOW);