1 #include <libm.h>
2 
3 #if __FLT_EVAL_METHOD__ == 0 || __FLT_EVAL_METHOD__ == 1
4 #define EPS __DBL_EPSILON__
5 #elif __FLT_EVAL_METHOD__ == 2
6 #define EPS __LDBL_EPSILON__
7 #endif
8 static const double toint = 1 / EPS;
9 
round(double x)10 double round(double x)
11 {
12     union
13     {
14         double f;
15         uint64_t i;
16     } u = {x};
17 
18     int e = u.i >> 52 & 0x7ff;
19     double y;
20 
21     if (e >= 0x3ff + 52)
22         return x;
23     if (u.i >> 63)
24         x = -x;
25     if (e < 0x3ff - 1)
26     {
27         /* raise inexact if x!=0 */
28         FORCE_EVAL(x + toint);
29         return 0 * u.f;
30     }
31     y = x + toint - toint - x;
32     if (y > 0.5)
33         y = y + x - 1;
34     else if (y <= -0.5)
35         y = y + x + 1;
36     else
37         y = y + x;
38     if (u.i >> 63)
39         y = -y;
40     return y;
41 }