Ejemplo n.º 1
0
float
__ieee754_hypotf(float x, float y)
{
	double d_x, d_y;
	int32_t ha, hb;

	GET_FLOAT_WORD(ha,x);
	ha &= 0x7fffffff;
	GET_FLOAT_WORD(hb,y);
	hb &= 0x7fffffff;
	if (ha == 0x7f800000 && !issignaling (y))
	  return fabsf(x);
	else if (hb == 0x7f800000 && !issignaling (x))
	  return fabsf(y);
	else if (ha > 0x7f800000 || hb > 0x7f800000)
	  return fabsf(x) * fabsf(y);
	else if (ha == 0)
	  return fabsf(y);
	else if (hb == 0)
	  return fabsf(x);

	d_x = (double) x;
	d_y = (double) y;

	return (float) __ieee754_sqrt(d_x * d_x + d_y * d_y);
}
Ejemplo n.º 2
0
FLOAT
M_DECL_FUNC (__fmin) (FLOAT x, FLOAT y)
{
  if (islessequal (x, y))
    return x;
  else if (isgreater (x, y))
    return y;
  else if (issignaling (x) || issignaling (y))
    return x + y;
  else
    return isnan (y) ? x : y;
}
Ejemplo n.º 3
0
FLOAT
M_DECL_FUNC (__fminmag) (FLOAT x, FLOAT y)
{
  FLOAT ax = M_FABS (x);
  FLOAT ay = M_FABS (y);
  if (isless (ax, ay))
    return x;
  else if (isgreater (ax, ay))
    return y;
  else if (ax == ay)
    return x < y ? x : y;
  else if (issignaling (x) || issignaling (y))
    return x + y;
  else
    return isnan (y) ? x : y;
}
Ejemplo n.º 4
0
Archivo: e_powf.c Proyecto: kraj/glibc
float
__ieee754_powf(float x, float y)
{
	float z,ax,z_h,z_l,p_h,p_l;
	float y1,t1,t2,r,s,t,u,v,w;
	int32_t i,j,k,yisint,n;
	int32_t hx,hy,ix,iy,is;

	GET_FLOAT_WORD(hx,x);
	GET_FLOAT_WORD(hy,y);
	ix = hx&0x7fffffff;  iy = hy&0x7fffffff;

    /* y==zero: x**0 = 1 */
	if(iy==0 && !issignaling (x)) return one;

    /* x==+-1 */
	if(x == 1.0 && !issignaling (y)) return one;
	if(x == -1.0 && isinf(y)) return one;

    /* +-NaN return x+y */
	if(__builtin_expect(ix > 0x7f800000 ||
			    iy > 0x7f800000, 0))
		return x+y;

    /* determine if y is an odd int when x < 0
     * yisint = 0	... y is not an integer
     * yisint = 1	... y is an odd int
     * yisint = 2	... y is an even int
     */
	yisint  = 0;
	if(hx<0) {
	    if(iy>=0x4b800000) yisint = 2; /* even integer y */
	    else if(iy>=0x3f800000) {
		k = (iy>>23)-0x7f;	   /* exponent */
		j = iy>>(23-k);
		if((j<<(23-k))==iy) yisint = 2-(j&1);
	    }
	}
Ejemplo n.º 5
0
Archivo: e_pow.c Proyecto: 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 */
}
Ejemplo n.º 6
0
long double
__ieee754_hypotl(long double x, long double y)
{
	long double a,b,a1,a2,b1,b2,w,kld;
	int64_t j,k,ha,hb;
	double xhi, yhi, hi, lo;

	xhi = ldbl_high (x);
	EXTRACT_WORDS64 (ha, xhi);
	yhi = ldbl_high (y);
	EXTRACT_WORDS64 (hb, yhi);
	ha &= 0x7fffffffffffffffLL;
	hb &= 0x7fffffffffffffffLL;
	if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;}
	a = fabsl(a);	/* a <- |a| */
	b = fabsl(b);	/* b <- |b| */
	if((ha-hb)>0x0780000000000000LL) {return a+b;} /* x/y > 2**120 */
	k=0;
	kld = 1.0L;
	if(ha > 0x5f30000000000000LL) {	/* a>2**500 */
	   if(ha >= 0x7ff0000000000000LL) {	/* Inf or NaN */
	       w = a+b;			/* for sNaN */
	       if (issignaling (a) || issignaling (b))
		 return w;
	       if(ha == 0x7ff0000000000000LL)
		 w = a;
	       if(hb == 0x7ff0000000000000LL)
		 w = b;
	       return w;
	   }
	   /* scale a and b by 2**-600 */
	   a *= 0x1p-600L;
	   b *= 0x1p-600L;
	   k = 600;
	   kld = 0x1p+600L;
	}
	else if(hb < 0x23d0000000000000LL) {	/* b < 2**-450 */
	    if(hb <= 0x000fffffffffffffLL) {	/* subnormal b or 0 */
		if(hb==0) return a;
		a *= 0x1p+1022L;
		b *= 0x1p+1022L;
		k = -1022;
		kld = 0x1p-1022L;
	    } else {		/* scale a and b by 2^600 */
		a *= 0x1p+600L;
		b *= 0x1p+600L;
		k = -600;
		kld = 0x1p-600L;
	    }
	}
    /* medium size a and b */
	w = a-b;
	if (w>b) {
	    ldbl_unpack (a, &hi, &lo);
	    a1 = hi;
	    a2 = lo;
	    /* a*a + b*b
	       = (a1+a2)*a + b*b
	       = a1*a + a2*a + b*b
	       = a1*(a1+a2) + a2*a + b*b
	       = a1*a1 + a1*a2 + a2*a + b*b
	       = a1*a1 + a2*(a+a1) + b*b  */
	    w  = sqrtl(a1*a1-(b*(-b)-a2*(a+a1)));
	} else {
	    a  = a+a;
	    ldbl_unpack (b, &hi, &lo);
	    b1 = hi;
	    b2 = lo;
	    ldbl_unpack (a, &hi, &lo);
	    a1 = hi;
	    a2 = lo;
	    /* a*a + b*b
	       = a*a + (a-b)*(a-b) - (a-b)*(a-b) + b*b
	       = a*a + w*w  - (a*a - 2*a*b + b*b) + b*b
	       = w*w + 2*a*b
	       = w*w + (a1+a2)*b
	       = w*w + a1*b + a2*b
	       = w*w + a1*(b1+b2) + a2*b
	       = w*w + a1*b1 + a1*b2 + a2*b  */
	    w  = sqrtl(a1*b1-(w*(-w)-(a1*b2+a2*b)));
	}
	if(k!=0)
	    {
		w *= kld;
		math_check_force_underflow_nonneg (w);
		return w;
	    }
	else
	    return w;
}
Ejemplo n.º 7
0
Archivo: e_hypot.c Proyecto: kraj/glibc
double
__ieee754_hypot (double x, double y)
{
  double a, b, t1, t2, y1, y2, w;
  int32_t j, k, ha, hb;

  GET_HIGH_WORD (ha, x);
  ha &= 0x7fffffff;
  GET_HIGH_WORD (hb, y);
  hb &= 0x7fffffff;
  if (hb > ha)
    {
      a = y; b = x; j = ha; ha = hb; hb = j;
    }
  else
    {
      a = x; b = y;
    }
  SET_HIGH_WORD (a, ha);        /* a <- |a| */
  SET_HIGH_WORD (b, hb);        /* b <- |b| */
  if ((ha - hb) > 0x3c00000)
    {
      return a + b;
    }                                       /* x/y > 2**60 */
  k = 0;
  if (__glibc_unlikely (ha > 0x5f300000))                  /* a>2**500 */
    {
      if (ha >= 0x7ff00000)             /* Inf or NaN */
	{
	  u_int32_t low;
	  w = a + b;                    /* for sNaN */
	  if (issignaling (a) || issignaling (b))
	    return w;
	  GET_LOW_WORD (low, a);
	  if (((ha & 0xfffff) | low) == 0)
	    w = a;
	  GET_LOW_WORD (low, b);
	  if (((hb ^ 0x7ff00000) | low) == 0)
	    w = b;
	  return w;
	}
      /* scale a and b by 2**-600 */
      ha -= 0x25800000; hb -= 0x25800000;  k += 600;
      SET_HIGH_WORD (a, ha);
      SET_HIGH_WORD (b, hb);
    }
  if (__builtin_expect (hb < 0x23d00000, 0))            /* b < 2**-450 */
    {
      if (hb <= 0x000fffff)             /* subnormal b or 0 */
	{
	  u_int32_t low;
	  GET_LOW_WORD (low, b);
	  if ((hb | low) == 0)
	    return a;
	  t1 = 0;
	  SET_HIGH_WORD (t1, 0x7fd00000);       /* t1=2^1022 */
	  b *= t1;
	  a *= t1;
	  k -= 1022;
	  GET_HIGH_WORD (ha, a);
	  GET_HIGH_WORD (hb, b);
	  if (hb > ha)
	    {
	      t1 = a;
	      a = b;
	      b = t1;
	      j = ha;
	      ha = hb;
	      hb = j;
	    }
	}
      else                      /* scale a and b by 2^600 */
	{
	  ha += 0x25800000;             /* a *= 2^600 */
	  hb += 0x25800000;             /* b *= 2^600 */
	  k -= 600;
	  SET_HIGH_WORD (a, ha);
	  SET_HIGH_WORD (b, hb);
	}
    }
  /* medium size a and b */
  w = a - b;
  if (w > b)
    {
      t1 = 0;
      SET_HIGH_WORD (t1, ha);
      t2 = a - t1;
      w = __ieee754_sqrt (t1 * t1 - (b * (-b) - t2 * (a + t1)));
    }
  else
    {
      a = a + a;
      y1 = 0;
      SET_HIGH_WORD (y1, hb);
      y2 = b - y1;
      t1 = 0;
      SET_HIGH_WORD (t1, ha + 0x00100000);
      t2 = a - t1;
      w = __ieee754_sqrt (t1 * y1 - (w * (-w) - (t1 * y2 + t2 * b)));
    }
  if (k != 0)
    {
      u_int32_t high;
      t1 = 1.0;
      GET_HIGH_WORD (high, t1);
      SET_HIGH_WORD (t1, high + (k << 20));
      w *= t1;
      math_check_force_underflow_nonneg (w);
      return w;
    }
  else
    return w;
}
Ejemplo n.º 8
0
static int
test (const char str[])
{
  char *endp;
  int result = 0;

  puts (str);

  double d = strtod (str, &endp);
  if (!isnan (d))
    {
      puts ("strtod did not return NAN");
      result = 1;
    }
  if (issignaling (d))
    {
      puts ("strtod returned a sNAN");
      result = 1;
    }
  if (strcmp (endp, "something") != 0)
    {
      puts  ("strtod set incorrect end pointer");
      result = 1;
    }

  float f = strtof (str, &endp);
  if (!isnanf (f))
    {
      puts ("strtof did not return NAN");
      result = 1;
    }
  if (issignaling (f))
    {
      puts ("strtof returned a sNAN");
      result = 1;
    }
  if (strcmp (endp, "something") != 0)
    {
      puts  ("strtof set incorrect end pointer");
      result = 1;
    }

  long double ld = strtold (str, &endp);
  if (!isnan (ld))
    {
      puts ("strtold did not return NAN");
      result = 1;
    }
  if (issignaling (ld))
    {
      puts ("strtold returned a sNAN");
      result = 1;
    }
  if (strcmp (endp, "something") != 0)
    {
      puts  ("strtold set incorrect end pointer");
      result = 1;
    }

  return result;
}