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(0x1p
127, 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(0x1p
1023, 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(0x1p
16383L, 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";