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 #ifdef _NEED_FLOAT64
16 
17 long long int
llround64(__float64 x)18 llround64(__float64 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 < (__int32_t) ((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 _MATH_ALIAS_k_d(llround)
85 
86 #endif /* _NEED_FLOAT64 */
87