source: trunk/libs/newlib/src/newlib/libm/common/s_lround.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: 3.6 KB
Line 
1/*
2 * ====================================================
3 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
4 *
5 * Developed at SunPro, a Sun Microsystems, Inc. business.
6 * Permission to use, copy, modify, and distribute this
7 * software is freely granted, provided that this notice
8 * is preserved.
9 * ====================================================
10 */
11/*
12FUNCTION
13<<lround>>, <<lroundf>>, <<llround>>, <<llroundf>>---round to integer, to nearest
14INDEX
15        lround
16INDEX
17        lroundf
18INDEX
19        llround
20INDEX
21        llroundf
22
23SYNOPSIS
24        #include <math.h>
25        long int lround(double <[x]>);
26        long int lroundf(float <[x]>);
27        long long int llround(double <[x]>);
28        long long int llroundf(float <[x]>);
29
30DESCRIPTION
31        The <<lround>> and <<llround>> functions round their argument to the
32        nearest integer value, rounding halfway cases away from zero, regardless
33        of the current rounding direction.  If the rounded value is outside the
34        range of the return type, the numeric result is unspecified (depending
35        upon the floating-point implementation, not the library).  A range
36        error may occur if the magnitude of x is too large.
37
38RETURNS
39<[x]> rounded to an integral value as an integer.
40
41SEEALSO
42See the <<round>> functions for the return being the same floating-point type
43as the argument.  <<lrint>>, <<llrint>>.
44
45PORTABILITY
46ANSI C, POSIX
47
48*/
49
50#include "fdlibm.h"
51
52#ifndef _DOUBLE_IS_32BITS
53
54#ifdef __STDC__
55        long int lround(double x)
56#else
57        long int lround(x)
58        double x;
59#endif
60{
61  __int32_t sign, exponent_less_1023;
62  /* Most significant word, least significant word. */
63  __uint32_t msw, lsw;
64  long int result;
65 
66  EXTRACT_WORDS(msw, lsw, x);
67
68  /* Extract sign. */
69  sign = ((msw & 0x80000000) ? -1 : 1);
70  /* Extract exponent field. */
71  exponent_less_1023 = ((msw & 0x7ff00000) >> 20) - 1023;
72  msw &= 0x000fffff;
73  msw |= 0x00100000;
74  /* exponent_less_1023 in [-1023,1024] */
75  if (exponent_less_1023 < 20)
76    {
77      /* exponent_less_1023 in [-1023,19] */
78      if (exponent_less_1023 < 0)
79        {
80          if (exponent_less_1023 < -1)
81            return 0;
82          else
83            return sign;
84        }
85      else
86        {
87          /* exponent_less_1023 in [0,19] */
88          /* shift amt in [0,19] */
89          msw += 0x80000 >> exponent_less_1023;
90          /* shift amt in [20,1] */
91          result = msw >> (20 - exponent_less_1023);
92        }
93    }
94  else if (exponent_less_1023 < (8 * sizeof (long int)) - 1)
95    {
96      /* 32bit long: exponent_less_1023 in [20,30] */
97      /* 64bit long: exponent_less_1023 in [20,62] */
98      if (exponent_less_1023 >= 52)
99        /* 64bit long: exponent_less_1023 in [52,62] */
100        /* 64bit long: shift amt in [32,42] */
101        result = ((long int) msw << (exponent_less_1023 - 20))
102                /* 64bit long: shift amt in [0,10] */
103                | (lsw << (exponent_less_1023 - 52));
104      else
105        {
106          /* 32bit long: exponent_less_1023 in [20,30] */
107          /* 64bit long: exponent_less_1023 in [20,51] */
108          unsigned int tmp = lsw
109                    /* 32bit long: shift amt in [0,10] */
110                    /* 64bit long: shift amt in [0,31] */
111                    + (0x80000000 >> (exponent_less_1023 - 20));
112          if (tmp < lsw)
113            ++msw;
114          /* 32bit long: shift amt in [0,10] */
115          /* 64bit long: shift amt in [0,31] */
116          result = ((long int) msw << (exponent_less_1023 - 20))
117                    /* ***32bit long: shift amt in [32,22] */
118                    /* ***64bit long: shift amt in [32,1] */
119                    | SAFE_RIGHT_SHIFT (tmp, (52 - exponent_less_1023));
120        }
121    }
122  else
123    /* Result is too large to be represented by a long int. */
124    return (long int)x;
125
126  return sign * result;
127}
128
129#endif /* _DOUBLE_IS_32BITS */
Note: See TracBrowser for help on using the repository browser.