コード例 #1
0
ファイル: s_truncl.c プロジェクト: apinski-cavium/glibc
long double
__truncl (long double x)
{
  double xh, xl, hi, lo;

  ldbl_unpack (x, &xh, &xl);

  /* Return Inf, Nan, +/-0 unchanged.  */
  if (__builtin_expect (xh != 0.0
			&& __builtin_isless (__builtin_fabs (xh),
					     __builtin_inf ()), 1))
    {
      hi = __trunc (xh);
      if (hi != xh)
	{
	  /* The high part is not an integer; the low part does not
	     affect the result.  */
	  xh = hi;
	  xl = 0;
	}
      else
	{
	  /* The high part is a nonzero integer.  */
	  lo = xh > 0 ? __floor (xl) : __ceil (xl);
	  xh = hi;
	  xl = lo;
	  ldbl_canonicalize_int (&xh, &xl);
	}
    }

  return ldbl_pack (xh, xl);
}
コード例 #2
0
ファイル: s_roundl.c プロジェクト: chenzhongtao/glibc
long double
__roundl (long double x)
{
  double xh, xl, hi, lo;

  ldbl_unpack (x, &xh, &xl);

  /* Return Inf, Nan, +/-0 unchanged.  */
  if (__builtin_expect (xh != 0.0
			&& __builtin_isless (__builtin_fabs (xh),
					     __builtin_inf ()), 1))
    {
      hi = __round (xh);
      if (hi != xh)
	{
	  /* The high part is not an integer; the low part only
	     affects the result if the high part is exactly half way
	     between two integers and the low part is nonzero with the
	     opposite sign.  */
	  if (fabs (hi - xh) == 0.5)
	    {
	      if (xh > 0 && xl < 0)
		xh = hi - 1;
	      else if (xh < 0 && xl > 0)
		xh = hi + 1;
	      else
		xh = hi;
	    }
	  else
	    xh = hi;
	  xl = 0;
	}
      else
	{
	  /* The high part is a nonzero integer.  */
	  lo = __round (xl);
	  if (fabs (lo - xl) == 0.5)
	    {
	      if (xh > 0 && xl < 0)
		xl = lo + 1;
	      else if (xh < 0 && lo > 0)
		xl = lo - 1;
	      else
		xl = lo;
	    }
	  else
	    xl = lo;
	  xh = hi;
	  ldbl_canonicalize_int (&xh, &xl);
	}
    }
  else
    /* Quiet signaling NaN arguments.  */
    xh += xh;

  return ldbl_pack (xh, xl);
}
コード例 #3
0
long double
__roundevenl (long double x)
{
  double xh, xl, hi;

  ldbl_unpack (x, &xh, &xl);

  if (xh != 0 && isfinite (xh))
    {
      hi = __roundeven (xh);
      if (hi != xh)
	{
	  /* The high part is not an integer; the low part only
	     affects the result if the high part is exactly half way
	     between two integers and the low part is nonzero in the
	     opposite direction to the rounding of the high part.  */
	  double diff = hi - xh;
	  if (fabs (diff) == 0.5)
	    {
	      if (xl < 0 && diff > 0)
		xh = hi - 1;
	      else if (xl > 0 && diff < 0)
		xh = hi + 1;
	      else
		xh = hi;
	    }
	  else
	    xh = hi;
	  xl = 0;
	}
      else
	{
	  /* The high part is a nonzero integer.  Rounding the low
	     part to nearest, ties round to even, is always correct,
	     as a high part that is an odd integer together with a low
	     part with magnitude 0.5 is not a valid long double.  */
	  xl = __roundeven (xl);
	  xh = hi;
	  ldbl_canonicalize_int (&xh, &xl);
	}
    }
  else
    /* Quiet signaling NaN arguments.  */
    xh += xh;

  return ldbl_pack (xh, xl);
}