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)10double 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 }