1570af302Sopenharmony_ci#include "libm.h" 2570af302Sopenharmony_ci 3570af302Sopenharmony_ci#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1 4570af302Sopenharmony_ci#define EPS DBL_EPSILON 5570af302Sopenharmony_ci#elif FLT_EVAL_METHOD==2 6570af302Sopenharmony_ci#define EPS LDBL_EPSILON 7570af302Sopenharmony_ci#endif 8570af302Sopenharmony_cistatic const double_t toint = 1/EPS; 9570af302Sopenharmony_ci 10570af302Sopenharmony_cidouble round(double x) 11570af302Sopenharmony_ci{ 12570af302Sopenharmony_ci union {double f; uint64_t i;} u = {x}; 13570af302Sopenharmony_ci int e = u.i >> 52 & 0x7ff; 14570af302Sopenharmony_ci double_t y; 15570af302Sopenharmony_ci 16570af302Sopenharmony_ci if (e >= 0x3ff+52) 17570af302Sopenharmony_ci return x; 18570af302Sopenharmony_ci if (u.i >> 63) 19570af302Sopenharmony_ci x = -x; 20570af302Sopenharmony_ci if (e < 0x3ff-1) { 21570af302Sopenharmony_ci /* raise inexact if x!=0 */ 22570af302Sopenharmony_ci FORCE_EVAL(x + toint); 23570af302Sopenharmony_ci return 0*u.f; 24570af302Sopenharmony_ci } 25570af302Sopenharmony_ci y = x + toint - toint - x; 26570af302Sopenharmony_ci if (y > 0.5) 27570af302Sopenharmony_ci y = y + x - 1; 28570af302Sopenharmony_ci else if (y <= -0.5) 29570af302Sopenharmony_ci y = y + x + 1; 30570af302Sopenharmony_ci else 31570af302Sopenharmony_ci y = y + x; 32570af302Sopenharmony_ci if (u.i >> 63) 33570af302Sopenharmony_ci y = -y; 34570af302Sopenharmony_ci return y; 35570af302Sopenharmony_ci} 36