1 /* Round argument to nearest integral value according to current rounding
3 Copyright (C) 1997 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
5 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
7 The GNU C Library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
12 The GNU C Library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
17 You should have received a copy of the GNU Library General Public
18 License along with the GNU C Library; see the file COPYING.LIB. If not,
19 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
24 #include "math_private.h"
27 /* The `long double' is in fact the IEEE `double' type. */
28 static long double two52
[2] =
30 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
31 -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */
36 __rinttoll (long double x
)
43 EXTRACT_WORDS (i0
, i1
, x
);
46 j0
= ((i0
>> 20) & 0x7ff) - 0x3ff;
52 if (((i0
& 0x7fffffff) | i1
) == 0)
53 /* The number is 0. */
59 i0
|= ((i1
| -i1
) >> 12) & 0x80000;
60 SET_HIGH_WORD (x
, i0
);
63 GET_HIGH_WORD (i0
, t
);
64 if ((i0
& 0x7fffffff) >= 0x3fff0000)
72 u_int32_t i
= 0x000fffff >> j0
;
73 if (((i0
& i
) | i1
) == 0)
75 /* X is not integral. */
77 if (((i0
& i
) | i1
) != 0)
82 i0
= (i0
& (~i
)) | (0x20000 >> j0
);
84 INSERT_WORDS (x
, i0
, i1
);
87 EXTRACT_WORDS (i0
, i1
, x
);
89 j0
= ((i0
>> 20) & 0x7ff) - 0x3ff;
93 result
= ((i0
>> (20 - j0
)) & 0xfffff) | (0x00100000 >> (20 - j0
));
98 else if ((unsigned int) j0
< sizeof (long long int) * 8 && j0
< 53)
100 i
= ((u_int32_t
) (0xffffffff)) >> (j0
- 20);
103 /* x is not integral. */
106 i1
= (i1
& (~i
)) | (0x40000000 >> (j0
- 20));
109 INSERT_WORDS (x
, i0
, i1
);
112 EXTRACT_WORDS (i0
, i1
, x
);
114 j0
= ((i0
>> 20) & 0x7ff) - 0x3ff;
116 result
= i0
| 0x00100000;
120 result
|= i1
>> (52 - j0
);
126 /* Too large. The number is either +-inf or NaN or it is too
127 large to be effected by rounding. The standard leaves it
128 undefined what to return when the number is too large to fit in
130 result
= (long long int) x
;
136 static long double two63
[2] =
138 9.223372036854775808000000e+18, /* 0x403E, 0x00000000, 0x00000000 */
139 -9.223372036854775808000000e+18 /* 0xC03E, 0x00000000, 0x00000000 */
144 __rinttoll (long double x
)
148 long long int result
;
151 GET_LDOUBLE_WORDS (se
, i0
, i1
, x
);
154 j0
= (se
& 0x7fff) - 0x3fff;
160 if (((se
& 0x7fff) | i0
| i1
) == 0)
161 /* The number is 0. */
167 i0
|= (i1
| -i1
) & 0x80000000;
168 SET_LDOUBLE_MSW (x
, i0
);
171 GET_LDOUBLE_EXP (i0
, t
);
172 if ((i0
& 0x7fff) >= 0x3fff)
173 result
= sx
? -1 : 1;
180 u_int32_t i
= 0x7fffffff >> j0
;
181 if (((i0
& i
) | i1
) == 0)
183 /* X is not integral. */
185 if (((i0
& i
) | i1
) != 0)
190 i0
= (i0
& (~i
)) | (0x20000000 >> j0
);
192 SET_LDOUBLE_WORDS (x
, se
, i0
, i1
);
195 GET_LDOUBLE_WORDS (se
, i0
, i1
, x
);
198 j0
= (se
& 0x7fff) - 0x3fff;
203 result
= i0
>> (31 - j0
);
206 else if ((unsigned int) j0
< sizeof (long long int) * 8 && j0
< 64)
208 i
= ((u_int32_t
) (0xffffffff)) >> (j0
- 31);
211 /* x is not integral. */
214 i1
= (i1
& (~i
)) | (0x40000000 >> (j0
- 31));
217 SET_LDOUBLE_WORDS (x
, se
, i0
, i1
);
220 GET_LDOUBLE_WORDS (se
, i0
, i1
, x
);
222 j0
= (se
& 0x7fff) - 0x3fff;
228 result
|= i1
>> (63 - j0
);
232 /* Too large. The number is either +-inf or NaN or it is too
233 large to be effected by rounding. The standard leaves it
234 undefined what to return when the number is too large to fit in
236 result
= (long long int) x
;
242 weak_alias (__rinttoll
, rinttoll
)