source: trunk/libs/newlib/src/newlib/libm/common/s_llround.c @ 567

Last change on this file since 567 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 2.5 KB
Line 
1/* lround adapted to be llround for Newlib, 2009 by Craig Howland.  */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunPro, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 */
12
13#include "fdlibm.h"
14
15#ifndef _DOUBLE_IS_32BITS
16
17long long int
18llround(double x)
19{
20  __int32_t sign, exponent_less_1023;
21  /* Most significant word, least significant word. */
22  __uint32_t msw, lsw;
23  long long int result;
24 
25  EXTRACT_WORDS(msw, lsw, x);
26
27  /* Extract sign. */
28  sign = ((msw & 0x80000000) ? -1 : 1);
29  /* Extract exponent field. */
30  exponent_less_1023 = ((msw & 0x7ff00000) >> 20) - 1023;
31  msw &= 0x000fffff;
32  msw |= 0x00100000;
33
34  /* exponent_less_1023 in [-1023,1024] */
35  if (exponent_less_1023 < 20)
36    {
37      /* exponent_less_1023 in [-1023,19] */
38      if (exponent_less_1023 < 0)
39        {
40          if (exponent_less_1023 < -1)
41            return 0;
42          else
43            return sign;
44        }
45      else
46        {
47          /* exponent_less_1023 in [0,19] */
48          /* shift amt in [0,19] */
49          msw += 0x80000 >> exponent_less_1023;
50          /* shift amt in [20,1] */
51          result = msw >> (20 - exponent_less_1023);
52        }
53    }
54  else if (exponent_less_1023 < (8 * sizeof (long long int)) - 1)
55    {
56      /* 64bit longlong: exponent_less_1023 in [20,62] */
57      if (exponent_less_1023 >= 52)
58        /* 64bit longlong: exponent_less_1023 in [52,62] */
59        /* 64bit longlong: shift amt in [32,42] */
60        result = ((long long int) msw << (exponent_less_1023 - 20))
61                    /* 64bit longlong: shift amt in [0,10] */
62                    | (lsw << (exponent_less_1023 - 52));
63      else
64        {
65          /* 64bit longlong: exponent_less_1023 in [20,51] */
66          unsigned int tmp = lsw
67                    /* 64bit longlong: shift amt in [0,31] */
68                    + (0x80000000 >> (exponent_less_1023 - 20));
69          if (tmp < lsw)
70            ++msw;
71          /* 64bit longlong: shift amt in [0,31] */
72          result = ((long long int) msw << (exponent_less_1023 - 20))
73                    /* ***64bit longlong: shift amt in [32,1] */
74                    | SAFE_RIGHT_SHIFT (tmp, (52 - exponent_less_1023));
75        }
76    }
77  else
78    /* Result is too large to be represented by a long long int. */
79    return (long long int)x;
80
81  return sign * result;
82}
83
84#endif /* _DOUBLE_IS_32BITS */
Note: See TracBrowser for help on using the repository browser.