Annotation of src/lib/libm/src/lrint.c, Revision 1.2
1.2 ! drochner 1: /* $NetBSD: lrint.c,v 1.1 2004/06/30 15:08:30 drochner Exp $ */
1.1 drochner 2:
3: #include <math.h>
4: #include <sys/ieee754.h>
5: #include <machine/limits.h>
6: #include "math_private.h"
7:
8: #ifndef LRINTNAME
9: #define LRINTNAME lrint
10: #define RESTYPE long int
11: #define RESTYPE_MIN LONG_MIN
12: #define RESTYPE_MAX LONG_MAX
13: #endif
14:
15: #define RESTYPE_BITS (sizeof(RESTYPE) * 8)
16:
17: static const double
18: TWO52[2]={
19: 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
20: -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */
21: };
22:
23: RESTYPE
24: LRINTNAME(double x)
25: {
26: u_int32_t i0, i1;
27: int e, s, shift;
28: RESTYPE res;
29:
30: GET_HIGH_WORD(i0, x);
31: e = i0 >> 20;
32: s = e >> DBL_EXPBITS;
33: e = (e & 0x7ff) - DBL_EXP_BIAS;
34:
35: /* 1.0 x 2^-1 is the smallest number which can be rounded to 1 */
36: if (e < -1)
37: return (0);
38: /* 1.0 x 2^31 (or 2^63) is already too large */
39: if (e >= (int)RESTYPE_BITS - 1)
40: return (s ? RESTYPE_MIN : RESTYPE_MAX); /* ??? unspecified */
41:
42: /* >= 2^52 is already an exact integer */
43: if (e < DBL_FRACBITS) {
44: /* round, using current direction */
45: x += TWO52[s];
46: x -= TWO52[s];
47: }
48:
49: EXTRACT_WORDS(i0, i1, x);
50: e = ((i0 >> 20) & 0x7ff) - DBL_EXP_BIAS;
51: i0 &= 0xfffff;
52: i0 |= (1 << 20);
53:
54: shift = e - DBL_FRACBITS;
55: if (shift >=0)
1.2 ! drochner 56: res = (shift < 32 ? (RESTYPE)i1 << shift : 0);
1.1 drochner 57: else
1.2 ! drochner 58: res = (shift > -32 ? i1 >> -shift : 0);
1.1 drochner 59: shift += 32;
60: if (shift >=0)
1.2 ! drochner 61: res |= (shift < 32 ? (RESTYPE)i0 << shift : 0);
1.1 drochner 62: else
1.2 ! drochner 63: res |= (shift > -32 ? i0 >> -shift : 0);
1.1 drochner 64:
65: return (s ? -res : res);
66: }
CVSweb <webmaster@jp.NetBSD.org>