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
))
46 if (got
== want
&& signbit(got
) == signbit(want
))
49 got
= copysignf(0x1p
127, got
);
52 return scalbn(got
- want
, -eulpf(want
)) + dwant
;
55 float ulperr(double got
, double want
, float dwant
)
57 if (isnan(got
) && isnan(want
))
59 if (got
== want
&& signbit(got
) == signbit(want
))
62 got
= copysign(0x1p
1023, got
);
65 return scalbn(got
- want
, -eulp(want
)) + dwant
;
68 float ulperrl(long double got
, long double want
, float dwant
)
70 #if LDBL_MANT_DIG == 53
71 return ulperr(got
, want
, dwant
);
72 #elif LDBL_MANT_DIG == 64
73 if (isnan(got
) && isnan(want
))
75 if (got
== want
&& signbit(got
) == signbit(want
))
78 got
= copysignl(0x1p
16383L, got
);
81 return scalbn(got
- want
, -eulpl(want
)) + dwant
;
88 #define length(a) (sizeof(a)/sizeof*(a))
89 #define flag(x) {x, #x}
103 static char buf
[256];
107 for (i
= 0; i
< length(eflags
); i
++)
108 if (f
& eflags
[i
].flag
) {
109 p
+= sprintf(p
, "%s%s", all
? "|" : "", eflags
[i
].s
);
110 all
|= eflags
[i
].flag
;
113 p
+= sprintf(p
, "%s%d", all
? "|" : "", f
& ~all
);
116 p
+= sprintf(p
, "%s", all
? "" : "0");
123 case RN
: return "RN";
124 case RZ
: return "RZ";
125 case RU
: return "RU";
126 case RD
: return "RD";
131 void setupfenv(int r
)
134 feclearexcept(FE_ALL_EXCEPT
);
139 return fetestexcept(INEXACT
|INVALID
|DIVBYZERO
|UNDERFLOW
|OVERFLOW
);