1 /* s_rintf.c -- float version of s_rint.c.
2 */
3
4 /*
5 * ====================================================
6 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
7 *
8 * Developed at SunPro, a Sun Microsystems, Inc. business.
9 * Permission to use, copy, modify, and distribute this
10 * software is freely granted, provided that this notice
11 * is preserved.
12 * ====================================================
13 */
14
15
16 #include <fenv.h>
17 #include <math.h>
18 #include <math-barriers.h>
19 #include <math_private.h>
20 #include <fenv_private.h>
21 #include <libm-alias-float.h>
22 #include <math-use-builtins.h>
23
24 float
__nearbyintf(float x)25 __nearbyintf (float x)
26 {
27 #if USE_NEARBYINTF_BUILTIN
28 return __builtin_nearbyintf (x);
29 #else
30 /* Use generic implementation. */
31 static const float
32 TWO23[2] = {
33 8.3886080000e+06, /* 0x4b000000 */
34 -8.3886080000e+06, /* 0xcb000000 */
35 };
36 fenv_t env;
37 int32_t i0, j0, sx;
38 float w, t;
39 GET_FLOAT_WORD (i0, x);
40 sx = (i0 >> 31) & 1;
41 j0 = ((i0 >> 23) & 0xff) - 0x7f;
42 if (j0 < 23)
43 {
44 if (j0 < 0)
45 {
46 libc_feholdexceptf (&env);
47 w = TWO23[sx] + math_opt_barrier (x);
48 t = w - TWO23[sx];
49 math_force_eval (t);
50 libc_fesetenvf (&env);
51 GET_FLOAT_WORD (i0, t);
52 SET_FLOAT_WORD (t, (i0 & 0x7fffffff) | (sx << 31));
53 return t;
54 }
55 }
56 else
57 {
58 if (__glibc_unlikely (j0 == 0x80))
59 return x + x; /* inf or NaN */
60 else
61 return x; /* x is integral */
62 }
63 libc_feholdexceptf (&env);
64 w = TWO23[sx] + math_opt_barrier (x);
65 t = w - TWO23[sx];
66 math_force_eval (t);
67 libc_fesetenvf (&env);
68 return t;
69 #endif /* ! USE_NEARBYINT_BUILTIN */
70 }
71 libm_alias_float (__nearbyint, nearbyint)
72