Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
3362 | Serge | 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 | < |
||
14 | INDEX |
||
15 | lround |
||
16 | INDEX |
||
17 | lroundf |
||
18 | INDEX |
||
19 | llround |
||
20 | INDEX |
||
21 | llroundf |
||
22 | |||
23 | ANSI_SYNOPSIS |
||
24 | #include |
||
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 < |
||
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 < |
||
43 | as the argument. < |
||
44 | |||
45 | PORTABILITY |
||
46 | ANSI C, POSIX |
||
47 | |||
48 | */ |
||
49 | |||
50 | #include "fdlibm.h" |
||
51 | |||
52 | #ifndef _DOUBLE_IS_32BITS |
||
53 | |||
54 | #ifdef __STDC__ |
||
55 | long int lround(double x) |
||
56 | #else |
||
57 | long int lround(x) |
||
58 | double x; |
||
59 | #endif |
||
60 | { |
||
61 | __int32_t sign, exponent_less_1023; |
||
62 | /* Most significant word, least significant word. */ |
||
63 | __uint32_t msw, lsw; |
||
64 | long int result; |
||
65 | |||
66 | EXTRACT_WORDS(msw, lsw, x); |
||
67 | |||
68 | /* Extract sign. */ |
||
69 | sign = ((msw & 0x80000000) ? -1 : 1); |
||
70 | /* Extract exponent field. */ |
||
71 | exponent_less_1023 = ((msw & 0x7ff00000) >> 20) - 1023; |
||
72 | msw &= 0x000fffff; |
||
73 | msw |= 0x00100000; |
||
74 | /* exponent_less_1023 in [-1023,1024] */ |
||
75 | if (exponent_less_1023 < 20) |
||
76 | { |
||
77 | /* exponent_less_1023 in [-1023,19] */ |
||
78 | if (exponent_less_1023 < 0) |
||
79 | { |
||
80 | if (exponent_less_1023 < -1) |
||
81 | return 0; |
||
82 | else |
||
83 | return sign; |
||
84 | } |
||
85 | else |
||
86 | { |
||
87 | /* exponent_less_1023 in [0,19] */ |
||
88 | /* shift amt in [0,19] */ |
||
89 | msw += 0x80000 >> exponent_less_1023; |
||
90 | /* shift amt in [20,1] */ |
||
91 | result = msw >> (20 - exponent_less_1023); |
||
92 | } |
||
93 | } |
||
94 | else if (exponent_less_1023 < (8 * sizeof (long int)) - 1) |
||
95 | { |
||
96 | /* 32bit long: exponent_less_1023 in [20,30] */ |
||
97 | /* 64bit long: exponent_less_1023 in [20,62] */ |
||
98 | if (exponent_less_1023 >= 52) |
||
99 | /* 64bit long: exponent_less_1023 in [52,62] */ |
||
100 | /* 64bit long: shift amt in [32,42] */ |
||
101 | result = ((long int) msw << (exponent_less_1023 - 20)) |
||
102 | /* 64bit long: shift amt in [0,10] */ |
||
103 | | (lsw << (exponent_less_1023 - 52)); |
||
104 | else |
||
105 | { |
||
106 | /* 32bit long: exponent_less_1023 in [20,30] */ |
||
107 | /* 64bit long: exponent_less_1023 in [20,51] */ |
||
108 | unsigned int tmp = lsw |
||
109 | /* 32bit long: shift amt in [0,10] */ |
||
110 | /* 64bit long: shift amt in [0,31] */ |
||
111 | + (0x80000000 >> (exponent_less_1023 - 20)); |
||
112 | if (tmp < lsw) |
||
113 | ++msw; |
||
114 | /* 32bit long: shift amt in [0,10] */ |
||
115 | /* 64bit long: shift amt in [0,31] */ |
||
116 | result = ((long int) msw << (exponent_less_1023 - 20)) |
||
117 | /* ***32bit long: shift amt in [32,22] */ |
||
118 | /* ***64bit long: shift amt in [32,1] */ |
||
119 | | SAFE_RIGHT_SHIFT (tmp, (52 - exponent_less_1023)); |
||
120 | } |
||
121 | } |
||
122 | else |
||
123 | /* Result is too large to be represented by a long int. */ |
||
124 | return (long int)x; |
||
125 | |||
126 | return sign * result; |
||
127 | } |
||
128 | |||
129 | #endif /* _DOUBLE_IS_32BITS */><>>><>><>>>>> |