1 /* wf_pow.c -- float version of w_pow.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  * wrapper powf(x,y) return x**y
18  */
19 
20 #include "fdlibm.h"
21 #include <errno.h>
22 
23 #ifdef __STDC__
powf(float x,float y)24 	float powf(float x, float y)	/* wrapper powf */
25 #else
26 	float powf(x,y)			/* wrapper powf */
27 	float x,y;
28 #endif
29 {
30 #ifdef _IEEE_LIBM
31 	return  __ieee754_powf(x,y);
32 #else
33 	float z;
34 	struct exception exc;
35 	z=__ieee754_powf(x,y);
36 	if(_LIB_VERSION == _IEEE_|| isnan(y)) return z;
37 	if(isnan(x)) {
38 	    if(y==(float)0.0) {
39 		/* powf(NaN,0.0) */
40 		/* error only if _LIB_VERSION == _SVID_ & _XOPEN_ */
41 		exc.type = DOMAIN;
42 		exc.name = "powf";
43 		exc.err = 0;
44 		exc.arg1 = (double)x;
45 		exc.arg2 = (double)y;
46 		exc.retval = 1.0;
47 		if (_LIB_VERSION == _IEEE_ ||
48 		    _LIB_VERSION == _POSIX_) exc.retval = 1.0;
49 		else if (!matherr(&exc)) {
50 			errno = EDOM;
51 		}
52 	        if (exc.err != 0)
53 	           errno = exc.err;
54                 return (float)exc.retval;
55 	    } else
56 		return z;
57 	}
58 	if(x==(float)0.0){
59 	    if(y==(float)0.0) {
60 		/* powf(0.0,0.0) */
61 		/* error only if _LIB_VERSION == _SVID_ */
62 		exc.type = DOMAIN;
63 		exc.name = "powf";
64 		exc.err = 0;
65 		exc.arg1 = (double)x;
66 		exc.arg2 = (double)y;
67 		exc.retval = 0.0;
68 		if (_LIB_VERSION != _SVID_) exc.retval = 1.0;
69 		else if (!matherr(&exc)) {
70 			errno = EDOM;
71 		}
72 	        if (exc.err != 0)
73 	           errno = exc.err;
74                 return (float)exc.retval;
75 	    }
76 	    if(finitef(y)&&y<(float)0.0) {
77 		/* 0**neg */
78 		exc.type = DOMAIN;
79 		exc.name = "powf";
80 		exc.err = 0;
81 		exc.arg1 = (double)x;
82 		exc.arg2 = (double)y;
83 		if (_LIB_VERSION == _SVID_)
84 		  exc.retval = 0.0;
85 		else
86 		  exc.retval = -HUGE_VAL;
87 		if (_LIB_VERSION == _POSIX_)
88 		  errno = EDOM;
89 		else if (!matherr(&exc)) {
90 		  errno = EDOM;
91 		}
92 	        if (exc.err != 0)
93 	           errno = exc.err;
94                 return (float)exc.retval;
95             }
96 	    return z;
97 	}
98 	if(!finitef(z)) {
99 	    if(finitef(x)&&finitef(y)) {
100 	        if(isnan(z)) {
101 		    /* neg**non-integral */
102 		    exc.type = DOMAIN;
103 		    exc.name = "powf";
104 		    exc.err = 0;
105 		    exc.arg1 = (double)x;
106 		    exc.arg2 = (double)y;
107 		    if (_LIB_VERSION == _SVID_)
108 		        exc.retval = 0.0;
109 		    else
110 		        exc.retval = 0.0/0.0;	/* X/Open allow NaN */
111 		    if (_LIB_VERSION == _POSIX_)
112 		        errno = EDOM;
113 		    else if (!matherr(&exc)) {
114 		        errno = EDOM;
115 		    }
116 	            if (exc.err != 0)
117 	                errno = exc.err;
118                     return (float)exc.retval;
119 	        } else {
120 		    /* powf(x,y) overflow */
121 		    exc.type = OVERFLOW;
122 		    exc.name = "powf";
123 		    exc.err = 0;
124 		    exc.arg1 = (double)x;
125 		    exc.arg2 = (double)y;
126 		    if (_LIB_VERSION == _SVID_) {
127 		       exc.retval = HUGE;
128 		       y *= 0.5;
129 		       if(x<0.0&&rint(y)!=y) exc.retval = -HUGE;
130 		    } else {
131 		       exc.retval = HUGE_VAL;
132                        y *= 0.5;
133 		       if(x<0.0&&rint(y)!=y) exc.retval = -HUGE_VAL;
134 		    }
135 		    if (_LIB_VERSION == _POSIX_)
136 		        errno = ERANGE;
137 		    else if (!matherr(&exc)) {
138 			errno = ERANGE;
139 		    }
140 	            if (exc.err != 0)
141 	                errno = exc.err;
142                     return (float)exc.retval;
143                 }
144 	    }
145 	}
146 	if(z==(float)0.0&&finitef(x)&&finitef(y)) {
147 	    /* powf(x,y) underflow */
148 	    exc.type = UNDERFLOW;
149 	    exc.name = "powf";
150 	    exc.err = 0;
151 	    exc.arg1 = (double)x;
152 	    exc.arg2 = (double)y;
153 	    exc.retval =  0.0;
154 	    if (_LIB_VERSION == _POSIX_)
155 	        errno = ERANGE;
156 	    else if (!matherr(&exc)) {
157 	     	errno = ERANGE;
158 	    }
159 	    if (exc.err != 0)
160 	        errno = exc.err;
161             return (float)exc.retval;
162         }
163 	return z;
164 #endif
165 }
166 
167 #ifdef _DOUBLE_IS_32BITS
168 
169 #ifdef __STDC__
pow(double x,double y)170 	double pow(double x, double y)
171 #else
172 	double pow(x,y)
173 	double x,y;
174 #endif
175 {
176 	return (double) powf((float) x, (float) y);
177 }
178 
179 #endif /* defined(_DOUBLE_IS_32BITS) */
180