1 /*
2 * ====================================================
3 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
4 *
5 * Developed at SunPro, a Sun Microsystems, Inc. business.
6 * Permission to use, copy, modify, and distribute this
7 * software is freely granted, provided that this notice
8 * is preserved.
9 * ====================================================
10 */
11 /*
12 FUNCTION
13 <<lround>>, <<lroundf>>, <<llround>>, <<llroundf>>---round to integer, to nearest
14 INDEX
15 lround
16 INDEX
17 lroundf
18 INDEX
19 llround
20 INDEX
21 llroundf
22
23 SYNOPSIS
24 #include <math.h>
25 long int lround(double <[x]>);
26 long int lroundf(float <[x]>);
27 long long int llround(double <[x]>);
28 long long int llroundf(float <[x]>);
29
30 DESCRIPTION
31 The <<lround>> and <<llround>> functions round their argument to the
32 nearest integer value, rounding halfway cases away from zero, regardless
33 of the current rounding direction. If the rounded value is outside the
34 range of the return type, the numeric result is unspecified (depending
35 upon the floating-point implementation, not the library). A range
36 error may occur if the magnitude of x is too large.
37
38 RETURNS
39 <[x]> rounded to an integral value as an integer.
40
41 SEEALSO
42 See the <<round>> functions for the return being the same floating-point type
43 as the argument. <<lrint>>, <<llrint>>.
44
45 PORTABILITY
46 ANSI C, POSIX
47
48 */
49
50 #include "fdlibm.h"
51 #include <limits.h>
52
53 #ifdef _NEED_FLOAT64
54
55 long int
lround64(__float64 x)56 lround64(__float64 x)
57 {
58 __int32_t sign, exponent_less_1023;
59 /* Most significant word, least significant word. */
60 __uint32_t msw, lsw;
61 long int result;
62
63 EXTRACT_WORDS(msw, lsw, x);
64
65 /* Extract sign. */
66 sign = ((msw & 0x80000000) ? -1 : 1);
67 /* Extract exponent field. */
68 exponent_less_1023 = ((msw & 0x7ff00000) >> 20) - 1023;
69 msw &= 0x000fffff;
70 msw |= 0x00100000;
71 /* exponent_less_1023 in [-1023,1024] */
72 if (exponent_less_1023 < 20)
73 {
74 /* exponent_less_1023 in [-1023,19] */
75 if (exponent_less_1023 < 0)
76 {
77 if (exponent_less_1023 < -1)
78 return 0;
79 else
80 return sign;
81 }
82 else
83 {
84 /* exponent_less_1023 in [0,19] */
85 /* shift amt in [0,19] */
86 msw += 0x80000 >> exponent_less_1023;
87 /* shift amt in [20,1] */
88 result = msw >> (20 - exponent_less_1023);
89 }
90 }
91 else if (exponent_less_1023 < (__int32_t) ((8 * sizeof (long int)) - 1))
92 {
93 /* 32bit long: exponent_less_1023 in [20,30] */
94 /* 64bit long: exponent_less_1023 in [20,62] */
95 if (exponent_less_1023 >= 52)
96 /* 64bit long: exponent_less_1023 in [52,62] */
97 /* 64bit long: shift amt in [32,42] */
98 result = ((long int) msw << (exponent_less_1023 - 20))
99 /* 64bit long: shift amt in [0,10] */
100 | ((long int) lsw << (exponent_less_1023 - 52));
101 else
102 {
103 /* 32bit long: exponent_less_1023 in [20,30] */
104 /* 64bit long: exponent_less_1023 in [20,51] */
105 __uint32_t tmp = lsw
106 /* 32bit long: shift amt in [0,10] */
107 /* 64bit long: shift amt in [0,31] */
108 + (0x80000000 >> (exponent_less_1023 - 20));
109 if (tmp < lsw)
110 ++msw;
111 /* 32bit long: shift amt in [0,10] */
112 /* 64bit long: shift amt in [0,31] */
113 result = ((long int) msw << (exponent_less_1023 - 20))
114 /* ***32bit long: shift amt in [32,22] */
115 /* ***64bit long: shift amt in [32,1] */
116 | SAFE_RIGHT_SHIFT (tmp, (52 - exponent_less_1023));
117 }
118 }
119 else
120 {
121 /* Result is too large to be represented by a long int. */
122 if (sign == 1 ||
123 !((sizeof(long) == 4 && x > LONG_MIN - _F_64(0.5)) ||
124 (sizeof(long) > 4 && x >= LONG_MIN)))
125 {
126 __math_set_invalid();
127 return sign == 1 ? LONG_MAX : LONG_MIN;
128 }
129 return (long int)x;
130 }
131
132 if (sizeof (long) == 4 && sign == 1 && result == LONG_MIN)
133 __math_set_invalid();
134
135 return sign * result;
136 }
137
138 _MATH_ALIAS_j_d(lround)
139
140 #endif /* _NEED_FLOAT64 */
141