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