7 union { float f; uint32_t i; } u = { x };
8 int e = u.i>>23 & 0xff;
17 union { double f; uint64_t i; } u = { x };
18 int e = u.i>>52 & 0x7ff;
22 return e - 0x3ff - 52;
25 int eulpl(long double x)
27 #if LDBL_MANT_DIG == 53
29 #elif LDBL_MANT_DIG == 64
30 union { long double f; struct {uint64_t m; uint16_t e; uint16_t pad;} i; } u = { x };
31 int e = u.i.e & 0x7fff;
35 return e - 0x3fff - 63;
42 float ulperrf(float got, float want, float dwant)
44 if (isnan(got) && isnan(want))
47 if (signbit(got) == signbit(want))
52 got = copysignf(0x1p127, got);
55 return scalbn(got - want, -eulpf(want)) + dwant;
58 float ulperr(double got, double want, float dwant)
60 if (isnan(got) && isnan(want))
63 if (signbit(got) == signbit(want))
65 return inf; // treat 0 sign errors badly
68 got = copysign(0x1p1023, got);
71 return scalbn(got - want, -eulp(want)) + dwant;
74 float ulperrl(long double got, long double want, float dwant)
76 #if LDBL_MANT_DIG == 53
77 return ulperr(got, want, dwant);
78 #elif LDBL_MANT_DIG == 64
79 if (isnan(got) && isnan(want))
82 if (signbit(got) == signbit(want))
87 got = copysignl(0x1p16383L, got);
90 return scalbnl(got - want, -eulpl(want)) + dwant;
97 #define length(a) (sizeof(a)/sizeof*(a))
98 #define flag(x) {x, #x}
112 static char buf[256];
116 for (i = 0; i < length(eflags); i++)
117 if (f & eflags[i].flag) {
118 p += sprintf(p, "%s%s", all ? "|" : "", eflags[i].s);
119 all |= eflags[i].flag;
122 p += sprintf(p, "%s%d", all ? "|" : "", f & ~all);
125 p += sprintf(p, "%s", all ? "" : "0");
132 case RN: return "RN";
134 case RZ: return "RZ";
137 case RU: return "RU";
140 case RD: return "RD";