xref: /DragonOS/kernel/src/common/math/round.c (revision 38b341b8aa671f75ac26d05059aa2e9a09e653b7)
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 }