Home | History | Annotate | Download | only in libm
      1 /* wf_pow.c -- float version of w_pow.c.
      2  * Conversion to float by Ian Lance Taylor, Cygnus Support, ian (at) 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__
     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__
    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