Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 pj 1
/* e_sqrtf.c -- float version of e_sqrt.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
#ifndef lint
17
static char rcsid[] = "$\Id: e_sqrtf.c,v 1.2 1995/05/30 05:48:52 rgrimes Exp $";
18
#endif
19
 
20
#include "math.h"
21
#include "math_private.h"
22
 
23
#ifdef __STDC__
24
static  const float     one     = 1.0, tiny=1.0e-30;
25
#else
26
static  float   one     = 1.0, tiny=1.0e-30;
27
#endif
28
 
29
#ifdef __STDC__
30
        float __ieee754_sqrtf(float x)
31
#else
32
        float __ieee754_sqrtf(x)
33
        float x;
34
#endif
35
{
36
        float z;
37
        int32_t sign = (int)0x80000000;
38
        int32_t ix,s,q,m,t,i;
39
        u_int32_t r;
40
 
41
        GET_FLOAT_WORD(ix,x);
42
 
43
    /* take care of Inf and NaN */
44
        if((ix&0x7f800000)==0x7f800000) {
45
            return x*x+x;               /* sqrt(NaN)=NaN, sqrt(+inf)=+inf
46
                                           sqrt(-inf)=sNaN */
47
        }
48
    /* take care of zero */
49
        if(ix<=0) {
50
            if((ix&(~sign))==0) return x;/* sqrt(+-0) = +-0 */
51
            else if(ix<0)
52
                return (x-x)/(x-x);             /* sqrt(-ve) = sNaN */
53
        }
54
    /* normalize x */
55
        m = (ix>>23);
56
        if(m==0) {                              /* subnormal x */
57
            for(i=0;(ix&0x00800000)==0;i++) ix<<=1;
58
            m -= i-1;
59
        }
60
        m -= 127;       /* unbias exponent */
61
        ix = (ix&0x007fffff)|0x00800000;
62
        if(m&1) /* odd m, double x to make it even */
63
            ix += ix;
64
        m >>= 1;        /* m = [m/2] */
65
 
66
    /* generate sqrt(x) bit by bit */
67
        ix += ix;
68
        q = s = 0;              /* q = sqrt(x) */
69
        r = 0x01000000;         /* r = moving bit from right to left */
70
 
71
        while(r!=0) {
72
            t = s+r;
73
            if(t<=ix) {
74
                s    = t+r;
75
                ix  -= t;
76
                q   += r;
77
            }
78
            ix += ix;
79
            r>>=1;
80
        }
81
 
82
    /* use floating add to find out rounding direction */
83
        if(ix!=0) {
84
            z = one-tiny; /* trigger inexact flag */
85
            if (z>=one) {
86
                z = one+tiny;
87
                if (z>one)
88
                    q += 2;
89
                else
90
                    q += (q&1);
91
            }
92
        }
93
        ix = (q>>1)+0x3f000000;
94
        ix += (m <<23);
95
        SET_FLOAT_WORD(z,ix);
96
        return z;
97
}