Exemplo n.º 1
0
	double pow(double x, double y)	/* wrapper pow */
{
#ifdef _IEEE_LIBM
	return  __ieee754_pow(x,y);
#else
	double z;
	z=__ieee754_pow(x,y);
	if(_LIB_VERSION == _IEEE_|| isnan(y)) return z;
	if(isnan(x)) {
	    if(y==0.0)
	        return __kernel_standard(x,y,42); /* pow(NaN,0.0) */
	    else
		return z;
	}
	if(x==0.0){
	    if(y==0.0)
	        return __kernel_standard(x,y,20); /* pow(0.0,0.0) */
	    if(finite(y)&&y<0.0)
	        return __kernel_standard(x,y,23); /* pow(0.0,negative) */
	    return z;
	}
	if(!finite(z)) {
	    if(finite(x)&&finite(y)) {
	        if(isnan(z))
	            return __kernel_standard(x,y,24); /* pow neg**non-int */
	        else
	            return __kernel_standard(x,y,21); /* pow overflow */
	    }
	}
	if(z==0.0&&finite(x)&&finite(y))
	    return __kernel_standard(x,y,22); /* pow underflow */
	return z;
#endif
}
Exemplo n.º 2
0
/* wrapper powf */
float
powf (float x, float y)
{
#if defined(__UCLIBC_HAS_FENV__)
  float z = (float)  __ieee754_pow ((double) x, (double) y);
  if (__builtin_expect (!isfinite (z), 0))
    {
      if (_LIB_VERSION != _IEEE_)
	{
	  if (isnan (x))
	    {
	      if (y == 0.0f)
		/* pow(NaN,0.0) */
		return __kernel_standard_f (x, y, 142);
	    }
	  else if (isfinite (x) && isfinite (y))
	    {
	      if (isnan (z))
		/* pow neg**non-int */
		return __kernel_standard_f (x, y, 124);
	      else if (x == 0.0f && y < 0.0f)
		{
		  if (signbit (x) && signbit (z))
		    /* pow(-0.0,negative) */
		    return __kernel_standard_f (x, y, 123);
		  else
		    /* pow(+0.0,negative) */
		    return __kernel_standard_f (x, y, 143);
		}
	      else
		/* pow overflow */
		return __kernel_standard_f (x, y, 121);
	    }
	}
    }
  else if (__builtin_expect (z == 0.0f, 0) && isfinite (x) && isfinite (y)
	   && _LIB_VERSION != _IEEE_)
    {
      if (x == 0.0f)
	{
	  if (y == 0.0f)
	    /* pow(0.0,0.0) */
	    return __kernel_standard_f (x, y, 120);
	}
      else
	/* pow underflow */
	return __kernel_standard_f (x, y, 122);
    }

	return z;
#else
	return (float) __ieee754_pow ((double) x, (double) y);
#endif /* __UCLIBC_HAS_FENV__ */
}
Exemplo n.º 3
0
void
Math_pow(void *fp)
{
	F_Math_pow *f;

	f = fp;

	*f->ret = __ieee754_pow(f->x, f->y);
}
Exemplo n.º 4
0
/* wrapper pow */
double
__pow (double x, double y)
{
  double z = __ieee754_pow (x, y);
  if (__builtin_expect (!__finite (z), 0))
    {
      if (_LIB_VERSION != _IEEE_)
	{
	  if (__isnan (x))
	    {
	      if (y == 0.0)
		/* pow(NaN,0.0) */
		return __kernel_standard (x, y, 42);
	    }
	  else if (__finite (x) && __finite (y))
	    {
	      if (__isnan (z))
		/* pow neg**non-int */
		return __kernel_standard (x, y, 24);
	      else if (x == 0.0 && y < 0.0)
		{
		  if (signbit (x) && signbit (z))
		    /* pow(-0.0,negative) */
		    return __kernel_standard (x, y, 23);
		  else
		    /* pow(+0.0,negative) */
		    return __kernel_standard (x, y, 43);
		}
	      else
		/* pow overflow */
		return __kernel_standard (x, y, 21);
	    }
	}
    }
  else if (__builtin_expect (z == 0.0, 0) && __finite (x) && __finite (y)
	   && _LIB_VERSION != _IEEE_)
    {
      if (x == 0.0)
	{
	  if (y == 0.0)
	    /* pow(0.0,0.0) */
	    return __kernel_standard (x, y, 20);
	}
      else
	/* pow underflow */
	return __kernel_standard (x, y, 22);
    }

  return z;
}
Exemplo n.º 5
0
        double pow(double x, double y)  /* wrapper pow */
{
#ifdef CYGSEM_LIBM_COMPAT_IEEE_ONLY
        return  __ieee754_pow(x,y);
#else
        double z;
        z=__ieee754_pow(x,y);
        if(cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_IEEE||
           isnan(y))
            return z;
        if(isnan(x)) {
            if(y==0.0) 
                return __kernel_standard(x,y,42); /* pow(NaN,0.0) */
            else 
                return z;
        }
        if(x==0.0){ 
            if(y==0.0)
                return __kernel_standard(x,y,20); /* pow(0.0,0.0) */
            if(finite(y)&&y<0.0)
                return __kernel_standard(x,y,23); /* pow(0.0,negative) */
            return z;
        }
        if(!finite(z)) {
            if(finite(x)&&finite(y)) {
                if(isnan(z))
                    return __kernel_standard(x,y,24);/* pow neg**non-int */
                else 
                    return __kernel_standard(x,y,21); /* pow overflow */
            }
        } 
        if(z==0.0&&finite(x)&&finite(y))
            return __kernel_standard(x,y,22); /* pow underflow */
        return z;
#endif
}
Exemplo n.º 6
0
EXPORT(sqInt) primitiveRaisedToPower(void) {
    double rcvr;
    double result;
    double arg;

	arg = interpreterProxy->stackFloatValue(0);
	rcvr = interpreterProxy->stackFloatValue(1);
	if (interpreterProxy->failed()) {
		return null;
	}
	result = __ieee754_pow(rcvr, arg);
	if (isnan(result)) {
		return interpreterProxy->primitiveFail();
	}
	interpreterProxy->pop((interpreterProxy->methodArgumentCount()) + 1);
	interpreterProxy->pushFloat(result);
}
primitiveRaisedToPower(void)
{
	// FloatMathPlugin>>#primitiveRaisedToPower
    double arg;
    double rcvr;
    double result;

	arg = stackFloatValue(0);
	rcvr = stackFloatValue(1);
	if (failed()) {
		return null;
	}
	result = __ieee754_pow(rcvr, arg);
	if (isnan(result)) {
		return primitiveFail();
	}
	pop((methodArgumentCount()) + 1);
	pushFloat(result);
}
Exemplo n.º 8
0
double
SECTION
__ieee754_pow(double x, double y) {
  double z,a,aa,error, t,a1,a2,y1,y2;
#if 0
  double gor=1.0;
#endif
  mynumber u,v;
  int k;
  int4 qx,qy;
  v.x=y;
  u.x=x;
  if (v.i[LOW_HALF] == 0) { /* of y */
    qx = u.i[HIGH_HALF]&0x7fffffff;
    /* Checking  if x is not too small to compute */
    if (((qx==0x7ff00000)&&(u.i[LOW_HALF]!=0))||(qx>0x7ff00000)) return NaNQ.x;
    if (y == 1.0) return x;
    if (y == 2.0) return x*x;
    if (y == -1.0) return 1.0/x;
    if (y == 0) return 1.0;
  }
  /* else */
  if(((u.i[HIGH_HALF]>0 && u.i[HIGH_HALF]<0x7ff00000)||        /* x>0 and not x->0 */
       (u.i[HIGH_HALF]==0 && u.i[LOW_HALF]!=0))  &&
				      /*   2^-1023< x<= 2^-1023 * 0x1.0000ffffffff */
      (v.i[HIGH_HALF]&0x7fffffff) < 0x4ff00000) {              /* if y<-1 or y>1   */
    double retval;

    SET_RESTORE_ROUND (FE_TONEAREST);

    /* Avoid internal underflow for tiny y.  The exact value of y does
       not matter if |y| <= 2**-64.  */
    if (ABS (y) < 0x1p-64)
      y = y < 0 ? -0x1p-64 : 0x1p-64;
    z = log1(x,&aa,&error);                                 /* x^y  =e^(y log (X)) */
    t = y*134217729.0;
    y1 = t - (t-y);
    y2 = y - y1;
    t = z*134217729.0;
    a1 = t - (t-z);
    a2 = (z - a1)+aa;
    a = y1*a1;
    aa = y2*a1 + y*a2;
    a1 = a+aa;
    a2 = (a-a1)+aa;
    error = error*ABS(y);
    t = __exp1(a1,a2,1.9e16*error);     /* return -10 or 0 if wasn't computed exactly */
    retval = (t>0)?t:power1(x,y);

    return retval;
  }

  if (x == 0) {
    if (((v.i[HIGH_HALF] & 0x7fffffff) == 0x7ff00000 && v.i[LOW_HALF] != 0)
	|| (v.i[HIGH_HALF] & 0x7fffffff) > 0x7ff00000)
      return y;
    if (ABS(y) > 1.0e20) return (y>0)?0:1.0/0.0;
    k = checkint(y);
    if (k == -1)
      return y < 0 ? 1.0/x : x;
    else
      return y < 0 ? 1.0/0.0 : 0.0;                               /* return 0 */
  }

  qx = u.i[HIGH_HALF]&0x7fffffff;  /*   no sign   */
  qy = v.i[HIGH_HALF]&0x7fffffff;  /*   no sign   */

  if (qx >= 0x7ff00000 && (qx > 0x7ff00000 || u.i[LOW_HALF] != 0)) return NaNQ.x;
  if (qy >= 0x7ff00000 && (qy > 0x7ff00000 || v.i[LOW_HALF] != 0))
    return x == 1.0 ? 1.0 : NaNQ.x;

  /* if x<0 */
  if (u.i[HIGH_HALF] < 0) {
    k = checkint(y);
    if (k==0) {
      if (qy == 0x7ff00000) {
	if (x == -1.0) return 1.0;
	else if (x > -1.0) return v.i[HIGH_HALF] < 0 ? INF.x : 0.0;
	else return v.i[HIGH_HALF] < 0 ? 0.0 : INF.x;
      }
      else if (qx == 0x7ff00000)
	return y < 0 ? 0.0 : INF.x;
      return NaNQ.x;                              /* y not integer and x<0 */
    }
    else if (qx == 0x7ff00000)
      {
	if (k < 0)
	  return y < 0 ? nZERO.x : nINF.x;
	else
	  return y < 0 ? 0.0 : INF.x;
      }
    return (k==1)?__ieee754_pow(-x,y):-__ieee754_pow(-x,y); /* if y even or odd */
  }
  /* x>0 */

  if (qx == 0x7ff00000)                              /* x= 2^-0x3ff */
    {if (y == 0) return NaNQ.x;
    return (y>0)?x:0; }

  if (qy > 0x45f00000 && qy < 0x7ff00000) {
    if (x == 1.0) return 1.0;
    if (y>0) return (x>1.0)?huge*huge:tiny*tiny;
    if (y<0) return (x<1.0)?huge*huge:tiny*tiny;
  }

  if (x == 1.0) return 1.0;
  if (y>0) return (x>1.0)?INF.x:0;
  if (y<0) return (x<1.0)?INF.x:0;
  return 0;     /* unreachable, to make the compiler happy */
}
Exemplo n.º 9
0
Arquivo: e_pow.c Projeto: kraj/glibc
/* An ultimate power routine. Given two IEEE double machine numbers y, x it
   computes the correctly rounded (to nearest) value of X^y.  */
double
SECTION
__ieee754_pow (double x, double y)
{
    double z, a, aa, error, t, a1, a2, y1, y2;
    mynumber u, v;
    int k;
    int4 qx, qy;
    v.x = y;
    u.x = x;
    if (v.i[LOW_HALF] == 0)
    {   /* of y */
        qx = u.i[HIGH_HALF] & 0x7fffffff;
        /* Is x a NaN?  */
        if ((((qx == 0x7ff00000) && (u.i[LOW_HALF] != 0)) || (qx > 0x7ff00000))
                && (y != 0 || issignaling (x)))
            return x + x;
        if (y == 1.0)
            return x;
        if (y == 2.0)
            return x * x;
        if (y == -1.0)
            return 1.0 / x;
        if (y == 0)
            return 1.0;
    }
    /* else */
    if (((u.i[HIGH_HALF] > 0 && u.i[HIGH_HALF] < 0x7ff00000) ||	/* x>0 and not x->0 */
            (u.i[HIGH_HALF] == 0 && u.i[LOW_HALF] != 0)) &&
            /*   2^-1023< x<= 2^-1023 * 0x1.0000ffffffff */
            (v.i[HIGH_HALF] & 0x7fffffff) < 0x4ff00000)
    {   /* if y<-1 or y>1   */
        double retval;

        {
            SET_RESTORE_ROUND (FE_TONEAREST);

            /* Avoid internal underflow for tiny y.  The exact value of y does
               not matter if |y| <= 2**-64.  */
            if (fabs (y) < 0x1p-64)
                y = y < 0 ? -0x1p-64 : 0x1p-64;
            z = log1 (x, &aa, &error);	/* x^y  =e^(y log (X)) */
            t = y * CN;
            y1 = t - (t - y);
            y2 = y - y1;
            t = z * CN;
            a1 = t - (t - z);
            a2 = (z - a1) + aa;
            a = y1 * a1;
            aa = y2 * a1 + y * a2;
            a1 = a + aa;
            a2 = (a - a1) + aa;
            error = error * fabs (y);
            t = __exp1 (a1, a2, 1.9e16 * error);	/* return -10 or 0 if wasn't computed exactly */
            retval = (t > 0) ? t : power1 (x, y);
        }

        if (isinf (retval))
            retval = huge * huge;
        else if (retval == 0)
            retval = tiny * tiny;
        else
            math_check_force_underflow_nonneg (retval);
        return retval;
    }

    if (x == 0)
    {
        if (((v.i[HIGH_HALF] & 0x7fffffff) == 0x7ff00000 && v.i[LOW_HALF] != 0)
                || (v.i[HIGH_HALF] & 0x7fffffff) > 0x7ff00000)	/* NaN */
            return y + y;
        if (fabs (y) > 1.0e20)
            return (y > 0) ? 0 : 1.0 / 0.0;
        k = checkint (y);
        if (k == -1)
            return y < 0 ? 1.0 / x : x;
        else
            return y < 0 ? 1.0 / 0.0 : 0.0;	/* return 0 */
    }

    qx = u.i[HIGH_HALF] & 0x7fffffff;	/*   no sign   */
    qy = v.i[HIGH_HALF] & 0x7fffffff;	/*   no sign   */

    if (qx >= 0x7ff00000 && (qx > 0x7ff00000 || u.i[LOW_HALF] != 0))	/* NaN */
        return x + y;
    if (qy >= 0x7ff00000 && (qy > 0x7ff00000 || v.i[LOW_HALF] != 0))	/* NaN */
        return x == 1.0 && !issignaling (y) ? 1.0 : y + y;

    /* if x<0 */
    if (u.i[HIGH_HALF] < 0)
    {
        k = checkint (y);
        if (k == 0)
        {
            if (qy == 0x7ff00000)
            {
                if (x == -1.0)
                    return 1.0;
                else if (x > -1.0)
                    return v.i[HIGH_HALF] < 0 ? INF.x : 0.0;
                else
                    return v.i[HIGH_HALF] < 0 ? 0.0 : INF.x;
            }
            else if (qx == 0x7ff00000)
                return y < 0 ? 0.0 : INF.x;
            return (x - x) / (x - x);	/* y not integer and x<0 */
        }
        else if (qx == 0x7ff00000)
        {
            if (k < 0)
                return y < 0 ? nZERO.x : nINF.x;
            else
                return y < 0 ? 0.0 : INF.x;
        }
        /* if y even or odd */
        if (k == 1)
            return __ieee754_pow (-x, y);
        else
        {
            double retval;
            {
                SET_RESTORE_ROUND (FE_TONEAREST);
                retval = -__ieee754_pow (-x, y);
            }
            if (isinf (retval))
                retval = -huge * huge;
            else if (retval == 0)
                retval = -tiny * tiny;
            return retval;
        }
    }
    /* x>0 */

    if (qx == 0x7ff00000)		/* x= 2^-0x3ff */
        return y > 0 ? x : 0;

    if (qy > 0x45f00000 && qy < 0x7ff00000)
    {
        if (x == 1.0)
            return 1.0;
        if (y > 0)
            return (x > 1.0) ? huge * huge : tiny * tiny;
        if (y < 0)
            return (x < 1.0) ? huge * huge : tiny * tiny;
    }

    if (x == 1.0)
        return 1.0;
    if (y > 0)
        return (x > 1.0) ? INF.x : 0;
    if (y < 0)
        return (x < 1.0) ? INF.x : 0;
    return 0;			/* unreachable, to make the compiler happy */
}
Exemplo n.º 10
0
Err mathlib_pow(UInt16 refnum, double x, double y, double *result) {
#pragma unused(refnum)
	*result = __ieee754_pow(x, y);
	return mlErrNone;
}
Exemplo n.º 11
0
static double
gamma_positive (double x, int *exp2_adj)
{
  int local_signgam;
  if (x < 0.5)
    {
      *exp2_adj = 0;
      return __ieee754_exp (__ieee754_lgamma_r (x + 1, &local_signgam)) / x;
    }
  else if (x <= 1.5)
    {
      *exp2_adj = 0;
      return __ieee754_exp (__ieee754_lgamma_r (x, &local_signgam));
    }
  else if (x < 6.5)
    {
      /* Adjust into the range for using exp (lgamma).  */
      *exp2_adj = 0;
      double n = __ceil (x - 1.5);
      double x_adj = x - n;
      double eps;
      double prod = __gamma_product (x_adj, 0, n, &eps);
      return (__ieee754_exp (__ieee754_lgamma_r (x_adj, &local_signgam))
	      * prod * (1.0 + eps));
    }
  else
    {
      double eps = 0;
      double x_eps = 0;
      double x_adj = x;
      double prod = 1;
      if (x < 12.0)
	{
	  /* Adjust into the range for applying Stirling's
	     approximation.  */
	  double n = __ceil (12.0 - x);
#if FLT_EVAL_METHOD != 0
	  volatile
#endif
	  double x_tmp = x + n;
	  x_adj = x_tmp;
	  x_eps = (x - (x_adj - n));
	  prod = __gamma_product (x_adj - n, x_eps, n, &eps);
	}
      /* The result is now gamma (X_ADJ + X_EPS) / (PROD * (1 + EPS)).
	 Compute gamma (X_ADJ + X_EPS) using Stirling's approximation,
	 starting by computing pow (X_ADJ, X_ADJ) with a power of 2
	 factored out.  */
      double exp_adj = -eps;
      double x_adj_int = __round (x_adj);
      double x_adj_frac = x_adj - x_adj_int;
      int x_adj_log2;
      double x_adj_mant = __frexp (x_adj, &x_adj_log2);
      if (x_adj_mant < M_SQRT1_2)
	{
	  x_adj_log2--;
	  x_adj_mant *= 2.0;
	}
      *exp2_adj = x_adj_log2 * (int) x_adj_int;
      double ret = (__ieee754_pow (x_adj_mant, x_adj)
		    * __ieee754_exp2 (x_adj_log2 * x_adj_frac)
		    * __ieee754_exp (-x_adj)
		    * __ieee754_sqrt (2 * M_PI / x_adj)
		    / prod);
      exp_adj += x_eps * __ieee754_log (x);
      double bsum = gamma_coeff[NCOEFF - 1];
      double x_adj2 = x_adj * x_adj;
      for (size_t i = 1; i <= NCOEFF - 1; i++)
	bsum = bsum / x_adj2 + gamma_coeff[NCOEFF - 1 - i];
      exp_adj += bsum / x_adj;
      return ret + ret * __expm1 (exp_adj);
    }
}