예제 #1
0
파일: w_fmodf.c 프로젝트: AdvancedC/glibc
/* wrapper fmodf */
float
__fmodf (float x, float y)
{
  if (__builtin_expect (__isinf_nsf (x) || y == 0.0f, 0)
      && _LIB_VERSION != _IEEE_ && !__isnanf (y) && !__isnanf (x))
    /* fmod(+-Inf,y) or fmod(x,0) */
    return __kernel_standard_f (x, y, 127);

  return __ieee754_fmodf (x, y);
}
예제 #2
0
float
__ieee754_remainderf(float x, float p)
{
	int32_t hx,hp;
	u_int32_t sx;
	float p_half;

	GET_FLOAT_WORD(hx,x);
	GET_FLOAT_WORD(hp,p);
	sx = hx&0x80000000;
	hp &= 0x7fffffff;
	hx &= 0x7fffffff;

    /* purge off exception values */
	if((hp==0)||			 	/* p = 0 */
	  (hx>=0x7f800000)||			/* x not finite */
	  ((hp>0x7f800000)))			/* p is NaN */
	    return nan_mix_op(x, p, *)/nan_mix_op(x, p, *);


	if (hp<=0x7effffff) x = __ieee754_fmodf(x,p+p);	/* now x < 2p */
	if ((hx-hp)==0) return zero*x;
	x  = fabsf(x);
	p  = fabsf(p);
	if (hp<0x01000000) {
	    if(x+x>p) {
		x-=p;
		if(x+x>=p) x -= p;
	    }
	} else {
	    p_half = (float)0.5*p;
	    if(x>p_half) {
		x-=p;
		if(x>=p_half) x -= p;
	    }
	}
	GET_FLOAT_WORD(hx,x);
	if ((hx&0x7fffffff)==0) hx = 0;
	SET_FLOAT_WORD(x,hx^sx);
	return x;
}
예제 #3
0
float
__remquof (float x, float y, int *quo)
{
  int32_t hx,hy;
  u_int32_t sx;
  int cquo, qs;

  GET_FLOAT_WORD (hx, x);
  GET_FLOAT_WORD (hy, y);
  sx = hx & 0x80000000;
  qs = sx ^ (hy & 0x80000000);
  hy &= 0x7fffffff;
  hx &= 0x7fffffff;

  /* Purge off exception values.  */
  if (hy == 0)
    return (x * y) / (x * y); 			/* y = 0 */
  if ((hx >= 0x7f800000)			/* x not finite */
      || (hy > 0x7f800000))			/* y is NaN */
    return (x * y) / (x * y);

  if (hy <= 0x7dffffff)
    x = __ieee754_fmodf (x, 8 * y);		/* now x < 8y */

  if ((hx - hy) == 0)
    {
      *quo = qs ? -1 : 1;
      return zero * x;
    }

  x  = fabsf (x);
  y  = fabsf (y);
  cquo = 0;

  if (x >= 4 * y)
    {
      x -= 4 * y;
      cquo += 4;
    }
  if (x >= 2 * y)
    {
      x -= 2 * y;
      cquo += 2;
    }

  if (hy < 0x01000000)
    {
      if (x + x > y)
	{
	  x -= y;
	  ++cquo;
	  if (x + x >= y)
	    {
	      x -= y;
	      ++cquo;
	    }
	}
    }
  else
    {
      float y_half = 0.5 * y;
      if (x > y_half)
	{
	  x -= y;
	  ++cquo;
	  if (x >= y_half)
	    {
	      x -= y;
	      ++cquo;
	    }
	}
    }

  *quo = qs ? -cquo : cquo;

  if (sx)
    x = -x;
  return x;
}