]>
Commit | Line | Data |
---|---|---|
dfd2257a | 1 | /* Round double value to long int. |
b168057a | 2 | Copyright (C) 1997-2015 Free Software Foundation, Inc. |
63551311 UD |
3 | This file is part of the GNU C Library. |
4 | Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. | |
5 | ||
6 | The GNU C Library is free software; you can redistribute it and/or | |
41bdb6e2 AJ |
7 | modify it under the terms of the GNU Lesser General Public |
8 | License as published by the Free Software Foundation; either | |
9 | version 2.1 of the License, or (at your option) any later version. | |
63551311 UD |
10 | |
11 | The GNU C Library is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
41bdb6e2 | 14 | Lesser General Public License for more details. |
63551311 | 15 | |
41bdb6e2 | 16 | You should have received a copy of the GNU Lesser General Public |
59ba27a6 PE |
17 | License along with the GNU C Library; if not, see |
18 | <http://www.gnu.org/licenses/>. */ | |
63551311 UD |
19 | |
20 | #include <math.h> | |
21 | ||
1ed0291c | 22 | #include <math_private.h> |
63551311 UD |
23 | |
24 | ||
63551311 | 25 | long int |
dfd2257a | 26 | __lround (double x) |
63551311 UD |
27 | { |
28 | int32_t j0; | |
29 | u_int32_t i1, i0; | |
30 | long int result; | |
0413b54c | 31 | int sign; |
63551311 UD |
32 | |
33 | EXTRACT_WORDS (i0, i1, x); | |
34 | j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; | |
0413b54c UD |
35 | sign = (i0 & 0x80000000) != 0 ? -1 : 1; |
36 | i0 &= 0xfffff; | |
dfd2257a UD |
37 | i0 |= 0x100000; |
38 | ||
63551311 UD |
39 | if (j0 < 20) |
40 | { | |
41 | if (j0 < 0) | |
dfd2257a | 42 | return j0 < -1 ? 0 : sign; |
63551311 UD |
43 | else |
44 | { | |
dfd2257a UD |
45 | i0 += 0x80000 >> j0; |
46 | ||
47 | result = i0 >> (20 - j0); | |
63551311 UD |
48 | } |
49 | } | |
cc3fa755 | 50 | else if (j0 < (int32_t) (8 * sizeof (long int)) - 1) |
63551311 | 51 | { |
dfd2257a | 52 | if (j0 >= 52) |
7f5517aa | 53 | result = ((long int) i0 << (j0 - 20)) | ((long int) i1 << (j0 - 52)); |
dfd2257a | 54 | else |
63551311 | 55 | { |
63551311 UD |
56 | u_int32_t j = i1 + (0x80000000 >> (j0 - 20)); |
57 | if (j < i1) | |
dfd2257a | 58 | ++i0; |
63551311 | 59 | |
3eb61415 UD |
60 | if (j0 == 20) |
61 | result = (long int) i0; | |
62 | else | |
63 | result = ((long int) i0 << (j0 - 20)) | (j >> (52 - j0)); | |
63551311 UD |
64 | } |
65 | } | |
dfd2257a | 66 | else |
63551311 UD |
67 | { |
68 | /* The number is too large. It is left implementation defined | |
69 | what happens. */ | |
dfd2257a | 70 | return (long int) x; |
63551311 UD |
71 | } |
72 | ||
dfd2257a | 73 | return sign * result; |
63551311 | 74 | } |
dfd2257a | 75 | |
d705269e | 76 | weak_alias (__lround, lround) |
dfd2257a UD |
77 | #ifdef NO_LONG_DOUBLE |
78 | strong_alias (__lround, __lroundl) | |
79 | weak_alias (__lround, lroundl) | |
80 | #endif |