Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3362 Serge 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
/*
12
FUNCTION
13
<>, <>, <>, <>--round to integer, to nearest
14
INDEX
15
	lround
16
INDEX
17
	lroundf
18
INDEX
19
	llround
20
INDEX
21
	llroundf
22
 
23
ANSI_SYNOPSIS
24
	#include 
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
 
30
DESCRIPTION
31
	The <> and <> 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
 
38
RETURNS
39
<[x]> rounded to an integral value as an integer.
40
 
41
SEEALSO
42
See the <> functions for the return being the same floating-point type
43
as the argument.  <>, <>.
44
 
45
PORTABILITY
46
ANSI 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 */