⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fp-bit.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 3 页
字号:
  fractype quotient;  if (isnan (a))    {      return a;    }  if (isnan (b))    {      return b;    }  a->sign = a->sign ^ b->sign;  if (isinf (a) || iszero (a))    {      if (a->class == b->class)	return nan ();      return a;    }  if (isinf (b))    {      a->fraction.ll = 0;      a->normal_exp = 0;      return a;    }  if (iszero (b))    {      a->class = CLASS_INFINITY;      return a;    }  /* Calculate the mantissa by multiplying both 64bit numbers to get a     128 bit number */  {    /* quotient =       ( numerator / denominator) * 2^(numerator exponent -  denominator exponent)     */    a->normal_exp = a->normal_exp - b->normal_exp;    numerator = a->fraction.ll;    denominator = b->fraction.ll;    if (numerator < denominator)      {	/* Fraction will be less than 1.0 */	numerator *= 2;	a->normal_exp--;      }    bit = IMPLICIT_1;    quotient = 0;    /* ??? Does divide one bit at a time.  Optimize.  */    while (bit)      {	if (numerator >= denominator)	  {	    quotient |= bit;	    numerator -= denominator;	  }	bit >>= 1;	numerator *= 2;      }    if ((quotient & GARDMASK) == GARDMSB)      {	if (quotient & (1 << NGARDS))	  {	    /* half way, so round to even */	    quotient += GARDROUND + 1;	  }	else if (numerator)	  {	    /* but we really weren't half way, more bits exist */	    quotient += GARDROUND + 1;	  }      }    a->fraction.ll = quotient;    return (a);  }}FLO_typedivide (FLO_type arg_a, FLO_type arg_b){  fp_number_type a;  fp_number_type b;  fp_number_type *res;  unpack_d ((FLO_union_type *) & arg_a, &a);  unpack_d ((FLO_union_type *) & arg_b, &b);  res = _fpdiv_parts (&a, &b);  return pack_d (res);}#endifint __fpcmp_parts (fp_number_type * a, fp_number_type *b);#if defined(L_fpcmp_parts_sf) || defined(L_fpcmp_parts_df)/* according to the demo, fpcmp returns a comparison with 0... thus   a<b -> -1   a==b -> 0   a>b -> +1 */int__fpcmp_parts (fp_number_type * a, fp_number_type * b){#if 0  /* either nan -> unordered. Must be checked outside of this routine. */  if (isnan (a) && isnan (b))    {      return 1;			/* still unordered! */    }#endif  if (isnan (a) || isnan (b))    {      return 1;			/* how to indicate unordered compare? */    }  if (isinf (a) && isinf (b))    {      /* +inf > -inf, but +inf != +inf */      /* b    \a| +inf(0)| -inf(1)       ______\+--------+--------       +inf(0)| a==b(0)| a<b(-1)       -------+--------+--------       -inf(1)| a>b(1) | a==b(0)       -------+--------+--------       So since unordered must be non zero, just line up the columns...       */      return b->sign - a->sign;    }  /* but not both... */  if (isinf (a))    {      return a->sign ? -1 : 1;    }  if (isinf (b))    {      return b->sign ? 1 : -1;    }  if (iszero (a) && iszero (b))    {      return 0;    }  if (iszero (a))    {      return b->sign ? 1 : -1;    }  if (iszero (b))    {      return a->sign ? -1 : 1;    }  /* now both are "normal". */  if (a->sign != b->sign)    {      /* opposite signs */      return a->sign ? -1 : 1;    }  /* same sign; exponents? */  if (a->normal_exp > b->normal_exp)    {      return a->sign ? -1 : 1;    }  if (a->normal_exp < b->normal_exp)    {      return a->sign ? 1 : -1;    }  /* same exponents; check size. */  if (a->fraction.ll > b->fraction.ll)    {      return a->sign ? -1 : 1;    }  if (a->fraction.ll < b->fraction.ll)    {      return a->sign ? 1 : -1;    }  /* after all that, they're equal. */  return 0;}#endif#if defined(L_compare_sf) || defined(L_compare_df)CMPtypecompare (FLO_type arg_a, FLO_type arg_b){  fp_number_type a;  fp_number_type b;  unpack_d ((FLO_union_type *) & arg_a, &a);  unpack_d ((FLO_union_type *) & arg_b, &b);  return __fpcmp_parts (&a, &b);}#endif#ifndef US_SOFTWARE_GOFAST/* These should be optimized for their specific tasks someday.  */#if defined(L_eq_sf) || defined(L_eq_df)CMPtype_eq_f2 (FLO_type arg_a, FLO_type arg_b){  fp_number_type a;  fp_number_type b;  unpack_d ((FLO_union_type *) & arg_a, &a);  unpack_d ((FLO_union_type *) & arg_b, &b);  if (isnan (&a) || isnan (&b))    return 1;			/* false, truth == 0 */  return __fpcmp_parts (&a, &b) ;}#endif#if defined(L_ne_sf) || defined(L_ne_df)CMPtype_ne_f2 (FLO_type arg_a, FLO_type arg_b){  fp_number_type a;  fp_number_type b;  unpack_d ((FLO_union_type *) & arg_a, &a);  unpack_d ((FLO_union_type *) & arg_b, &b);  if (isnan (&a) || isnan (&b))    return 1;			/* true, truth != 0 */  return  __fpcmp_parts (&a, &b) ;}#endif#if defined(L_gt_sf) || defined(L_gt_df)CMPtype_gt_f2 (FLO_type arg_a, FLO_type arg_b){  fp_number_type a;  fp_number_type b;  unpack_d ((FLO_union_type *) & arg_a, &a);  unpack_d ((FLO_union_type *) & arg_b, &b);  if (isnan (&a) || isnan (&b))    return -1;			/* false, truth > 0 */  return __fpcmp_parts (&a, &b);}#endif#if defined(L_ge_sf) || defined(L_ge_df)CMPtype_ge_f2 (FLO_type arg_a, FLO_type arg_b){  fp_number_type a;  fp_number_type b;  unpack_d ((FLO_union_type *) & arg_a, &a);  unpack_d ((FLO_union_type *) & arg_b, &b);  if (isnan (&a) || isnan (&b))    return -1;			/* false, truth >= 0 */  return __fpcmp_parts (&a, &b) ;}#endif#if defined(L_lt_sf) || defined(L_lt_df)CMPtype_lt_f2 (FLO_type arg_a, FLO_type arg_b){  fp_number_type a;  fp_number_type b;  unpack_d ((FLO_union_type *) & arg_a, &a);  unpack_d ((FLO_union_type *) & arg_b, &b);  if (isnan (&a) || isnan (&b))    return 1;			/* false, truth < 0 */  return __fpcmp_parts (&a, &b);}#endif#if defined(L_le_sf) || defined(L_le_df)CMPtype_le_f2 (FLO_type arg_a, FLO_type arg_b){  fp_number_type a;  fp_number_type b;  unpack_d ((FLO_union_type *) & arg_a, &a);  unpack_d ((FLO_union_type *) & arg_b, &b);  if (isnan (&a) || isnan (&b))    return 1;			/* false, truth <= 0 */  return __fpcmp_parts (&a, &b) ;}#endif#endif /* ! US_SOFTWARE_GOFAST */#if defined(L_si_to_sf) || defined(L_si_to_df)FLO_typesi_to_float (SItype arg_a){  fp_number_type in;  in.class = CLASS_NUMBER;  in.sign = arg_a < 0;  if (!arg_a)    {      in.class = CLASS_ZERO;    }  else    {      in.normal_exp = FRACBITS + NGARDS;      if (in.sign) 	{	  /* Special case for minint, since there is no +ve integer	     representation for it */	  if (arg_a == (SItype) 0x80000000)	    {	      return -2147483648.0;	    }	  in.fraction.ll = (-arg_a);	}      else	in.fraction.ll = arg_a;      while (in.fraction.ll < (1LL << (FRACBITS + NGARDS)))	{	  in.fraction.ll <<= 1;	  in.normal_exp -= 1;	}    }  return pack_d (&in);}#endif#if defined(L_sf_to_si) || defined(L_df_to_si)SItypefloat_to_si (FLO_type arg_a){  fp_number_type a;  SItype tmp;  unpack_d ((FLO_union_type *) & arg_a, &a);  if (iszero (&a))    return 0;  if (isnan (&a))    return 0;  /* get reasonable MAX_SI_INT... */  if (isinf (&a))    return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;  /* it is a number, but a small one */  if (a.normal_exp < 0)    return 0;  if (a.normal_exp > 30)    return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;  tmp = a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);  return a.sign ? (-tmp) : (tmp);}#endif#if defined(L_sf_to_usi) || defined(L_df_to_usi)#ifdef US_SOFTWARE_GOFAST/* While libgcc2.c defines its own __fixunssfsi and __fixunsdfsi routines,   we also define them for GOFAST because the ones in libgcc2.c have the   wrong names and I'd rather define these here and keep GOFAST CYG-LOC's   out of libgcc2.c.  We can't define these here if not GOFAST because then   there'd be duplicate copies.  */USItypefloat_to_usi (FLO_type arg_a){  fp_number_type a;  unpack_d ((FLO_union_type *) & arg_a, &a);  if (iszero (&a))    return 0;  if (isnan (&a))    return 0;  /* it is a negative number */  if (a.sign)    return 0;  /* get reasonable MAX_USI_INT... */  if (isinf (&a))    return MAX_USI_INT;  /* it is a number, but a small one */  if (a.normal_exp < 0)    return 0;  if (a.normal_exp > 31)    return MAX_USI_INT;  else if (a.normal_exp > (FRACBITS + NGARDS))    return a.fraction.ll << (a.normal_exp - (FRACBITS + NGARDS));  else    return a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);}#endif#endif#if defined(L_negate_sf) || defined(L_negate_df)FLO_typenegate (FLO_type arg_a){  fp_number_type a;  unpack_d ((FLO_union_type *) & arg_a, &a);  flip_sign (&a);  return pack_d (&a);}#endif#ifdef FLOAT#if defined(L_make_sf)SFtype__make_fp(fp_class_type class,	     unsigned int sign,	     int exp, 	     USItype frac){  fp_number_type in;  in.class = class;  in.sign = sign;  in.normal_exp = exp;  in.fraction.ll = frac;  return pack_d (&in);}#endif#ifndef FLOAT_ONLY/* This enables one to build an fp library that supports float but not double.   Otherwise, we would get an undefined reference to __make_dp.   This is needed for some 8-bit ports that can't handle well values that   are 8-bytes in size, so we just don't support double for them at all.  */extern DFtype __make_dp (fp_class_type, unsigned int, int, UDItype frac);#if defined(L_sf_to_df)DFtypesf_to_df (SFtype arg_a){  fp_number_type in;  unpack_d ((FLO_union_type *) & arg_a, &in);  return __make_dp (in.class, in.sign, in.normal_exp,		    ((UDItype) in.fraction.ll) << F_D_BITOFF);}#endif#endif#endif#ifndef FLOATextern SFtype __make_fp (fp_class_type, unsigned int, int, USItype);#if defined(L_make_df)DFtype__make_dp (fp_class_type class, unsigned int sign, int exp, UDItype frac){  fp_number_type in;  in.class = class;  in.sign = sign;  in.normal_exp = exp;  in.fraction.ll = frac;  return pack_d (&in);}#endif#if defined(L_df_to_sf)SFtypedf_to_sf (DFtype arg_a){  fp_number_type in;  USItype sffrac;  unpack_d ((FLO_union_type *) & arg_a, &in);  sffrac = in.fraction.ll >> F_D_BITOFF;  /* We set the lowest guard bit in SFFRAC if we discarded any non     zero bits.  */  if ((in.fraction.ll & (((USItype) 1 << F_D_BITOFF) - 1)) != 0)    sffrac |= 1;  return __make_fp (in.class, in.sign, in.normal_exp, sffrac);}#endif#endif#endif /* !EXTENDED_FLOAT_STUBS */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -