1/* s_rintl.c -- long double 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#if defined (LIBM_SCCS) && ! defined (lint)
16static char rcsid[] = "$NetBSD: $";
17#endif
18
19/*
20 * rintl(x)
21 * Return x rounded to integral value according to the prevailing
22 * rounding mode.
23 * Method:
24 * Using floating addition.
25 * Exception:
26 * Inexact flag raised if x not equal to rintl(x).
27 */
28
29#define NO_MATH_REDIRECT
30#include <math.h>
31#include <math_private.h>
32#include <libm-alias-ldouble.h>
33#include <math-use-builtins.h>
34
35_Float128
36__rintl (_Float128 x)
37{
38#if USE_RINTL_BUILTIN
39 return __builtin_rintl (x);
40#else
41 /* Use generic implementation. */
42 static const _Float128
43 TWO112[2] = {
44 5.19229685853482762853049632922009600E+33L, /* 0x406F000000000000, 0 */
45 -5.19229685853482762853049632922009600E+33L /* 0xC06F000000000000, 0 */
46 };
47 int64_t i0, j0, sx;
48 uint64_t i1 __attribute__ ((unused));
49 _Float128 w, t;
50 GET_LDOUBLE_WORDS64 (i0, i1, x);
51 sx = (((uint64_t) i0) >> 63);
52 j0 = ((i0 >> 48) & 0x7fff) - 0x3fff;
53 if (j0 < 112)
54 {
55 if (j0 < 0)
56 {
57 w = TWO112[sx] + x;
58 t = w - TWO112[sx];
59 GET_LDOUBLE_MSW64 (i0, t);
60 SET_LDOUBLE_MSW64 (t, (i0 & 0x7fffffffffffffffLL) | (sx << 63));
61 return t;
62 }
63 }
64 else
65 {
66 if (j0 == 0x4000)
67 return x + x; /* inf or NaN */
68 else
69 return x; /* x is integral */
70 }
71 w = TWO112[sx] + x;
72 return w - TWO112[sx];
73#endif /* ! USE_RINTL_BUILTIN */
74}
75libm_alias_ldouble (__rint, rint)
76

source code of glibc/sysdeps/ieee754/ldbl-128/s_rintl.c