source: trunk/libs/newlib/src/newlib/libm/math/w_pow.c @ 452

Last change on this file since 452 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 4.7 KB
Line 
1
2
3/* @(#)w_pow.c 5.2 93/10/01 */
4/*
5 * ====================================================
6 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
7 *
8 * Developed at SunPro, a Sun Microsystems, Inc. business.
9 * Permission to use, copy, modify, and distribute this
10 * software is freely granted, provided that this notice
11 * is preserved.
12 * ====================================================
13 */
14
15/*
16FUNCTION
17        <<pow>>, <<powf>>---x to the power y
18INDEX
19        pow
20INDEX
21        powf
22
23
24SYNOPSIS
25        #include <math.h>
26        double pow(double <[x]>, double <[y]>);
27        float powf(float <[x]>, float <[y]>);
28
29DESCRIPTION
30        <<pow>> and <<powf>> calculate <[x]> raised to the exponent <[y]>.
31        @tex
32        (That is, $x^y$.)
33        @end tex
34
35RETURNS
36        On success, <<pow>> and <<powf>> return the value calculated.
37
38        When the argument values would produce overflow, <<pow>>
39        returns <<HUGE_VAL>> and set <<errno>> to <<ERANGE>>.  If the
40        argument <[x]> passed to <<pow>> or <<powf>> is a negative
41        noninteger, and <[y]> is also not an integer, then <<errno>>
42        is set to <<EDOM>>.  If <[x]> and <[y]> are both 0, then
43        <<pow>> and <<powf>> return <<1>>.
44
45        You can modify error handling for these functions using <<matherr>>.
46
47PORTABILITY
48        <<pow>> is ANSI C. <<powf>> is an extension.  */
49
50/*
51 * wrapper pow(x,y) return x**y
52 */
53
54#include "fdlibm.h"
55#include <errno.h>
56
57#ifndef _DOUBLE_IS_32BITS
58
59#ifdef __STDC__
60        double pow(double x, double y)  /* wrapper pow */
61#else
62        double pow(x,y)                 /* wrapper pow */
63        double x,y;
64#endif
65{
66#ifdef _IEEE_LIBM
67        return  __ieee754_pow(x,y);
68#else
69        double z;
70#ifndef HUGE_VAL
71#define HUGE_VAL inf
72        double inf = 0.0;
73
74        SET_HIGH_WORD(inf,0x7ff00000);  /* set inf to infinite */
75#endif
76        struct exception exc;
77        z=__ieee754_pow(x,y);
78        if(_LIB_VERSION == _IEEE_|| isnan(y)) return z;
79        if(isnan(x)) {
80            if(y==0.0) { 
81                /* pow(NaN,0.0) */
82                /* error only if _LIB_VERSION == _SVID_ & _XOPEN_ */
83                exc.type = DOMAIN;
84                exc.name = "pow";
85                exc.err = 0;
86                exc.arg1 = x;
87                exc.arg2 = y;
88                exc.retval = 1.0;
89                if (_LIB_VERSION == _IEEE_ ||
90                    _LIB_VERSION == _POSIX_) exc.retval = 1.0;
91                else if (!matherr(&exc)) {
92                        errno = EDOM;
93                }
94                if (exc.err != 0)
95                   errno = exc.err;
96                return exc.retval; 
97            } else 
98                return z;
99        }
100        if(x==0.0){ 
101            if(y==0.0) {
102                /* pow(0.0,0.0) */
103                /* error only if _LIB_VERSION == _SVID_ */
104                exc.type = DOMAIN;
105                exc.name = "pow";
106                exc.err = 0;
107                exc.arg1 = x;
108                exc.arg2 = y;
109                exc.retval = 0.0;
110                if (_LIB_VERSION != _SVID_) exc.retval = 1.0;
111                else if (!matherr(&exc)) {
112                        errno = EDOM;
113                }
114                if (exc.err != 0)
115                   errno = exc.err;
116                return exc.retval; 
117            }
118            if(finite(y)&&y<0.0) {
119                /* 0**neg */
120                exc.type = DOMAIN;
121                exc.name = "pow";
122                exc.err = 0;
123                exc.arg1 = x;
124                exc.arg2 = y;
125                if (_LIB_VERSION == _SVID_) 
126                  exc.retval = 0.0;
127                else
128                  exc.retval = -HUGE_VAL;
129                if (_LIB_VERSION == _POSIX_)
130                  errno = EDOM;
131                else if (!matherr(&exc)) {
132                  errno = EDOM;
133                }
134                if (exc.err != 0)
135                   errno = exc.err;
136                return exc.retval; 
137            } 
138            return z;
139        }
140        if(!finite(z)) {
141            if(finite(x)&&finite(y)) {
142                if(isnan(z)) {
143                    /* neg**non-integral */
144                    exc.type = DOMAIN;
145                    exc.name = "pow";
146                    exc.err = 0;
147                    exc.arg1 = x;
148                    exc.arg2 = y;
149                    if (_LIB_VERSION == _SVID_) 
150                        exc.retval = 0.0;
151                    else 
152                        exc.retval = 0.0/0.0;   /* X/Open allow NaN */
153                    if (_LIB_VERSION == _POSIX_) 
154                        errno = EDOM;
155                    else if (!matherr(&exc)) {
156                        errno = EDOM;
157                    }
158                    if (exc.err != 0)
159                        errno = exc.err;
160                    return exc.retval; 
161                } else {
162                    /* pow(x,y) overflow */
163                    exc.type = OVERFLOW;
164                    exc.name = "pow";
165                    exc.err = 0;
166                    exc.arg1 = x;
167                    exc.arg2 = y;
168                    if (_LIB_VERSION == _SVID_) {
169                       exc.retval = HUGE;
170                       y *= 0.5;
171                       if(x<0.0&&rint(y)!=y) exc.retval = -HUGE;
172                    } else {
173                       exc.retval = HUGE_VAL;
174                       y *= 0.5;
175                       if(x<0.0&&rint(y)!=y) exc.retval = -HUGE_VAL;
176                    }
177                    if (_LIB_VERSION == _POSIX_)
178                        errno = ERANGE;
179                    else if (!matherr(&exc)) {
180                        errno = ERANGE;
181                    }
182                    if (exc.err != 0)
183                        errno = exc.err;
184                    return exc.retval; 
185                }
186            }
187        } 
188        if(z==0.0&&finite(x)&&finite(y)) {
189            /* pow(x,y) underflow */
190            exc.type = UNDERFLOW;
191            exc.name = "pow";
192            exc.err = 0;
193            exc.arg1 = x;
194            exc.arg2 = y;
195            exc.retval =  0.0;
196            if (_LIB_VERSION == _POSIX_)
197                errno = ERANGE;
198            else if (!matherr(&exc)) {
199                errno = ERANGE;
200            }
201            if (exc.err != 0)
202                errno = exc.err;
203            return exc.retval; 
204        } 
205        return z;
206#endif
207}
208
209#endif /* defined(_DOUBLE_IS_32BITS) */
210
211
212
213
214
215
216
217
218
219
220
221
222
223
Note: See TracBrowser for help on using the repository browser.