[BACK]Return to lrint.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libm / src

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>