1/* Adapted for use as nearbyint by Ulrich Drepper <drepper@cygnus.com>. */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunPro, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 */
12
13/*
14 * rint(x)
15 * Return x rounded to integral value according to the prevailing
16 * rounding mode.
17 * Method:
18 * Using floating addition.
19 * Exception:
20 * Inexact flag raised if x not equal to rint(x).
21 */
22
23#include <fenv.h>
24#include <math.h>
25#include <math-barriers.h>
26#include <math_private.h>
27#include <fenv_private.h>
28#include <libm-alias-double.h>
29#include <math-use-builtins.h>
30
31double
32__nearbyint (double x)
33{
34#if USE_NEARBYINT_BUILTIN
35 return __builtin_nearbyint (x);
36#else
37 /* Use generic implementation. */
38 static const double
39 TWO52[2] = {
40 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
41 -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */
42 };
43 fenv_t env;
44 int64_t i0, sx;
45 int32_t j0;
46 EXTRACT_WORDS64 (i0, x);
47 sx = (i0 >> 63) & 1;
48 j0 = ((i0 >> 52) & 0x7ff) - 0x3ff;
49 if (__glibc_likely (j0 < 52))
50 {
51 if (j0 < 0)
52 {
53 libc_feholdexcept (&env);
54 double w = TWO52[sx] + math_opt_barrier (x);
55 double t = w - TWO52[sx];
56 math_force_eval (t);
57 libc_fesetenv (&env);
58 return copysign (t, x);
59 }
60 }
61 else
62 {
63 if (j0 == 0x400)
64 return x + x; /* inf or NaN */
65 else
66 return x; /* x is integral */
67 }
68 libc_feholdexcept (&env);
69 double w = TWO52[sx] + math_opt_barrier (x);
70 double t = w - TWO52[sx];
71 math_force_eval (t);
72 libc_fesetenv (&env);
73 return t;
74#endif /* ! USE_NEARBYINT_BUILTIN */
75}
76libm_alias_double (__nearbyint, nearbyint)
77