OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [newlib/] [newlib/] [libm/] [mathfp/] [sf_fmod.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 56 joel
/* ef_fmod.c -- float version of e_fmod.c.
2
 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
3
 */
4
 
5
/*
6
 * ====================================================
7
 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
8
 *
9
 * Developed at SunPro, a Sun Microsystems, Inc. business.
10
 * Permission to use, copy, modify, and distribute this
11
 * software is freely granted, provided that this notice
12
 * is preserved.
13
 * ====================================================
14
 */
15
 
16
/*
17
 * fmodf(x,y)
18
 * Return x mod y in exact arithmetic
19
 * Method: shift and subtract
20
 */
21
 
22
#include "fdlibm.h"
23
#include "zmath.h"
24
 
25
static const float one = 1.0, Zero[] = {0.0, -0.0,};
26
 
27
float
28
_DEFUN (fmodf, (float, float),
29
        float x _AND
30
        float y)
31
{
32
        __int32_t n,hx,hy,hz,ix,iy,sx,i;
33
 
34
        GET_FLOAT_WORD(hx,x);
35
        GET_FLOAT_WORD(hy,y);
36
        sx = hx&0x80000000;             /* sign of x */
37
        hx ^=sx;                /* |x| */
38
        hy &= 0x7fffffff;       /* |y| */
39
 
40
    /* purge off exception values */
41
        if(hy==0||(hx>=0x7f800000)||             /* y=0,or x not finite */
42
           (hy>0x7f800000))                     /* or y is NaN */
43
            return (x*y)/(x*y);
44
        if(hx<hy) return x;                     /* |x|<|y| return x */
45
        if(hx==hy)
46
            return Zero[(__uint32_t)sx>>31];    /* |x|=|y| return x*0*/
47
 
48
    /* determine ix = ilogb(x) */
49
        if(hx<0x00800000) {     /* subnormal x */
50
            for (ix = -126,i=(hx<<8); i>0; i<<=1) ix -=1;
51
        } else ix = (hx>>23)-127;
52
 
53
    /* determine iy = ilogb(y) */
54
        if(hy<0x00800000) {     /* subnormal y */
55
            for (iy = -126,i=(hy<<8); i>=0; i<<=1) iy -=1;
56
        } else iy = (hy>>23)-127;
57
 
58
    /* set up {hx,lx}, {hy,ly} and align y to x */
59
        if(ix >= -126)
60
            hx = 0x00800000|(0x007fffff&hx);
61
        else {          /* subnormal x, shift x to normal */
62
            n = -126-ix;
63
            hx = hx<<n;
64
        }
65
        if(iy >= -126)
66
            hy = 0x00800000|(0x007fffff&hy);
67
        else {          /* subnormal y, shift y to normal */
68
            n = -126-iy;
69
            hy = hy<<n;
70
        }
71
 
72
    /* fix point fmod */
73
        n = ix - iy;
74
        while(n--) {
75
            hz=hx-hy;
76
            if(hz<0){hx = hx+hx;}
77
            else {
78
                if(hz==0)                /* return sign(x)*0 */
79
                    return Zero[(__uint32_t)sx>>31];
80
                hx = hz+hz;
81
            }
82
        }
83
        hz=hx-hy;
84
        if(hz>=0) {hx=hz;}
85
 
86
    /* convert back to floating value and restore the sign */
87
        if(hx==0)                        /* return sign(x)*0 */
88
            return Zero[(__uint32_t)sx>>31];
89
        while(hx<0x00800000) {          /* normalize x */
90
            hx = hx+hx;
91
            iy -= 1;
92
        }
93
        if(iy>= -126) {         /* normalize output */
94
            hx = ((hx-0x00800000)|((iy+127)<<23));
95
            SET_FLOAT_WORD(x,hx|sx);
96
        } else {                /* subnormal output */
97
            n = -126 - iy;
98
            hx >>= n;
99
            SET_FLOAT_WORD(x,hx|sx);
100
            x *= one;           /* create necessary signal */
101
        }
102
        return x;               /* exact output */
103
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.