Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
4349 Serge 1
 
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
FUNCTION
14
<>, <>, <>, <>--round to integer
15
INDEX
16
	lrint
17
INDEX
18
	lrintf
19
INDEX
20
	llrint
21
INDEX
22
	llrintf
23
24
 
25
	#include 
26
	long int lrint(double <[x]>);
27
	long int lrintf(float <[x]>);
28
	long long int llrint(double <[x]>);
29
	long long int llrintf(float <[x]>);
30
31
 
32
The <> and <> functions round their argument to the nearest
33
integer value, using the current rounding direction.  If the rounded value is
34
outside the range of the return type, the numeric result is unspecified.  A
35
range error may occur if the magnitude of <[x]> is too large.
36
The "inexact" floating-point exception is raised in implementations that
37
support it when the result differs in value from the argument (i.e., when
38
a fraction actually has been truncated).
39
40
 
41
<[x]> rounded to an integral value, using the current rounding direction.
42
43
 
44
<>
45
46
 
47
ANSI C, POSIX
48
49
 
50
51
 
52
 * lrint(x)
53
 * Return x rounded to integral value according to the prevailing
54
 * rounding mode.
55
 * Method:
56
 *	Using floating addition.
57
 * Exception:
58
 *	Inexact flag raised if x not equal to lrint(x).
59
 */
60
61
 
62
63
 
64
65
 
66
static const double
67
#else
68
static double
69
#endif
70
71
 
72
   the fractional part of x, according to the implementation's current rounding
73
   mode.  2^52 is the smallest double that can be represented using all 52 significant
74
   digits. */
75
TWO52[2]={
76
  4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
77
 -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */
78
};
79
80
 
81
	long int lrint(double x)
82
#else
83
	long int lrint(x)
84
	double x;
85
#endif
86
{
87
  __int32_t i0,j0,sx;
88
  __uint32_t i1;
89
  double t;
90
  volatile double w;
91
  long int result;
92
93
 
94
95
 
96
  sx = (i0>>31)&1;
97
98
 
99
  j0 = ((i0 & 0x7ff00000) >> 20) - 1023;
100
  /* j0 in [-1023,1024] */
101
102
 
103
    {
104
      /* j0 in [-1023,19] */
105
      if(j0 < -1)
106
        return 0;
107
      else
108
        {
109
          /* j0 in [0,19] */
110
	  /* shift amt in [0,19] */
111
          w = TWO52[sx] + x;
112
          t = w - TWO52[sx];
113
          GET_HIGH_WORD(i0, t);
114
          /* Detect the all-zeros representation of plus and
115
             minus zero, which fails the calculation below. */
116
          if ((i0 & ~(1L << 31)) == 0)
117
              return 0;
118
          /* After round:  j0 in [0,20] */
119
          j0 = ((i0 & 0x7ff00000) >> 20) - 1023;
120
          i0 &= 0x000fffff;
121
          i0 |= 0x00100000;
122
	  /* shift amt in [20,0] */
123
          result = i0 >> (20 - j0);
124
        }
125
    }
126
  else if (j0 < (int)(8 * sizeof (long int)) - 1)
127
    {
128
      /* 32bit return: j0 in [20,30] */
129
      /* 64bit return: j0 in [20,62] */
130
      if (j0 >= 52)
131
	/* 64bit return: j0 in [52,62] */
132
	/* 64bit return: left shift amt in [32,42] */
133
        result = ((long int) ((i0 & 0x000fffff) | 0x0010000) << (j0 - 20)) |
134
		/* 64bit return: right shift amt in [0,10] */
135
                   (i1 << (j0 - 52));
136
      else
137
        {
138
	  /* 32bit return: j0 in [20,30] */
139
	  /* 64bit return: j0 in [20,51] */
140
          w = TWO52[sx] + x;
141
          t = w - TWO52[sx];
142
          EXTRACT_WORDS (i0, i1, t);
143
          j0 = ((i0 & 0x7ff00000) >> 20) - 1023;
144
          i0 &= 0x000fffff;
145
          i0 |= 0x00100000;
146
          /* After round:
147
	   * 32bit return: j0 in [20,31];
148
	   * 64bit return: j0 in [20,52] */
149
	  /* 32bit return: left shift amt in [0,11] */
150
	  /* 64bit return: left shift amt in [0,32] */
151
          /* ***32bit return: right shift amt in [32,21] */
152
          /* ***64bit return: right shift amt in [32,0] */
153
          result = ((long int) i0 << (j0 - 20))
154
			| SAFE_RIGHT_SHIFT (i1, (52 - j0));
155
        }
156
    }
157
  else
158
    {
159
      return (long int) x;
160
    }
161
162
 
163
}
164
165
 
166