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