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