mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-27 07:20:11 +00:00
Make compilable and fix overflow condition.
This commit is contained in:
parent
27157fb6a0
commit
d391bc58dd
@ -24,36 +24,50 @@
|
||||
#include "math_private.h"
|
||||
|
||||
long long int
|
||||
__llrint (long double x)
|
||||
__llrint (double x)
|
||||
{
|
||||
int32_t se, sx;
|
||||
u_int32_t h, l;
|
||||
int32_t e;
|
||||
u_int32_t h, l, s;
|
||||
long long int result;
|
||||
|
||||
x = __m81_u(__rintl) (x);
|
||||
x = __m81_u(__rint) (x);
|
||||
|
||||
/* We could use __fixxfdi from libgcc, but here we can take advantage of
|
||||
the known floating point format. */
|
||||
GET_LDOUBLE_WORDS (se, h, l, x);
|
||||
EXTRACT_WORDS (h, l, x);
|
||||
|
||||
sx = se & (1 << 15);
|
||||
se = (se ^ sx) - 0x3fff;
|
||||
e = ((h >> 20) & 0x7ff) - 0x3ff;
|
||||
if (e < 0)
|
||||
return 0;
|
||||
s = h;
|
||||
h &= 0xfffff;
|
||||
h |= 0x100000;
|
||||
|
||||
if (se < 64)
|
||||
if (e < 63)
|
||||
{
|
||||
if (se > 31)
|
||||
result = (((long long int) (h >> (63 - se)) << 32)
|
||||
| (l >> (63 - se)) | (h << (se - 31)));
|
||||
if (e > 52)
|
||||
{
|
||||
h <<= e - 52;
|
||||
h |= l >> (84 - e);
|
||||
l <<= e - 52;
|
||||
result = ((long long int) h << 32) | l;
|
||||
}
|
||||
else if (e > 20)
|
||||
{
|
||||
l >>= 52 - e;
|
||||
l |= h << (e - 20);
|
||||
h >>= 52 - e;
|
||||
result = ((long long int) h << 32) | l;
|
||||
}
|
||||
else
|
||||
result = h >> (31 - se);
|
||||
if (sx)
|
||||
result = h >> (20 - e);
|
||||
if (s & 0x80000000)
|
||||
result = -result;
|
||||
}
|
||||
else
|
||||
/* Too large. The number is either +-inf or NaN or it is too
|
||||
large to be effected by rounding. The standard leaves it
|
||||
undefined what to return when the number is too large to fit in
|
||||
a `long long int'. */
|
||||
/* The number is too large or not finite. The standard leaves it
|
||||
undefined what to return when the number is too large to fit in a
|
||||
`long long int'. */
|
||||
result = -1LL;
|
||||
|
||||
return result;
|
||||
|
Loading…
Reference in New Issue
Block a user