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

📄 fp-bit.c

📁 GUN开源阻止下的编译器GCC
💻 C
📖 第 1 页 / 共 2 页
字号:
FLO_typesub (FLO_type arg_a, FLO_type arg_b){  fp_number_type a;  fp_number_type b;  fp_number_type tmp;  fp_number_type *res;  unpack_d ((FLO_union_type *) & arg_a, &a);  unpack_d ((FLO_union_type *) & arg_b, &b);  b.sign ^= 1;  res = _fpadd_parts (&a, &b, &tmp);  return pack_d (res);}static fp_number_type *_fpmul_parts ( fp_number_type *  a,	       fp_number_type *  b,	       fp_number_type * tmp){  fractype low = 0;  fractype high = 0;  if (isnan (a))    {      a->sign = a->sign != b->sign;      return a;    }  if (isnan (b))    {      b->sign = a->sign != b->sign;      return b;    }  if (isinf (a))    {      if (iszero (b))	return nan ();      a->sign = a->sign != b->sign;      return a;    }  if (isinf (b))    {      if (iszero (a))	{	  return nan ();	}      b->sign = a->sign != b->sign;      return b;    }  if (iszero (a))    {      a->sign = a->sign != b->sign;      return a;    }  if (iszero (b))    {      b->sign = a->sign != b->sign;      return b;    }  /* Calculate the mantissa by multiplying both 64bit numbers to get a     128 bit number */  {    fractype x = a->fraction.ll;    fractype ylow = b->fraction.ll;    fractype yhigh = 0;    int bit;#if defined(NO_DI_MODE)    {      /* ??? This does multiplies one bit at a time.  Optimize.  */      for (bit = 0; bit < FRAC_NBITS; bit++)	{	  int carry;	  if (x & 1)	    {	      carry = (low += ylow) < ylow;	      high += yhigh + carry;	    }	  yhigh <<= 1;	  if (ylow & FRACHIGH)	    {	      yhigh |= 1;	    }	  ylow <<= 1;	  x >>= 1;	}    }#elif defined(FLOAT)     {      /* Multiplying two 32 bit numbers to get a 64 bit number  on         a machine with DI, so we're safe */      DItype answer = (DItype)(a->fraction.ll) * (DItype)(b->fraction.ll);            high = answer >> 32;      low = answer;    }#else    /* Doing a 64*64 to 128 */    {      UDItype nl = a->fraction.ll & 0xffffffff;      UDItype nh = a->fraction.ll >> 32;      UDItype ml = b->fraction.ll & 0xffffffff;      UDItype mh = b->fraction.ll >>32;      UDItype pp_ll = ml * nl;      UDItype pp_hl = mh * nl;      UDItype pp_lh = ml * nh;      UDItype pp_hh = mh * nh;      UDItype res2 = 0;      UDItype res0 = 0;      UDItype ps_hh__ = pp_hl + pp_lh;      if (ps_hh__ < pp_hl)	res2 += 0x100000000LL;      pp_hl = (ps_hh__ << 32) & 0xffffffff00000000LL;      res0 = pp_ll + pp_hl;      if (res0 < pp_ll)	res2++;      res2 += ((ps_hh__ >> 32) & 0xffffffffL) + pp_hh;      high = res2;      low = res0;    }#endif  }  tmp->normal_exp = a->normal_exp + b->normal_exp;  tmp->sign = a->sign != b->sign;#ifdef FLOAT  tmp->normal_exp += 2;		/* ??????????????? */#else  tmp->normal_exp += 4;		/* ??????????????? */#endif  while (high >= IMPLICIT_2)    {      tmp->normal_exp++;      if (high & 1)	{	  low >>= 1;	  low |= FRACHIGH;	}      high >>= 1;    }  while (high < IMPLICIT_1)    {      tmp->normal_exp--;      high <<= 1;      if (low & FRACHIGH)	high |= 1;      low <<= 1;    }  /* rounding is tricky. if we only round if it won't make us round later. */#if 0  if (low & FRACHIGH2)    {      if (((high & GARDMASK) != GARDMSB)	  && (((high + 1) & GARDMASK) == GARDMSB))	{	  /* don't round, it gets done again later. */	}      else	{	  high++;	}    }#endif  if ((high & GARDMASK) == GARDMSB)    {      if (high & (1 << NGARDS))	{	  /* half way, so round to even */	  high += GARDROUND + 1;	}      else if (low)	{	  /* but we really weren't half way */	  high += GARDROUND + 1;	}    }  tmp->fraction.ll = high;  tmp->class = CLASS_NUMBER;  return tmp;}FLO_typemultiply (FLO_type arg_a, FLO_type arg_b){  fp_number_type a;  fp_number_type b;  fp_number_type tmp;  fp_number_type *res;  unpack_d ((FLO_union_type *) & arg_a, &a);  unpack_d ((FLO_union_type *) & arg_b, &b);  res = _fpmul_parts (&a, &b, &tmp);  return pack_d (res);}static fp_number_type *_fpdiv_parts (fp_number_type * a,	      fp_number_type * b,	      fp_number_type * tmp){  fractype low = 0;  fractype high = 0;  fractype r0, r1, y0, y1, bit;  fractype q;  fractype numerator;  fractype denominator;  fractype quotient;  fractype remainder;  if (isnan (a))    {      return a;    }  if (isnan (b))    {      return b;    }  if (isinf (a) || iszero (a))    {      if (a->class == b->class)	return nan ();      return a;    }  a->sign = a->sign ^ b->sign;  if (isinf (b))    {      a->fraction.ll = 0;      a->normal_exp = 0;      return a;    }  if (iszero (b))    {      a->class = CLASS_INFINITY;      return b;    }  /* Calculate the mantissa by multiplying both 64bit numbers to get a     128 bit number */  {    int carry;    intfrac d0, d1;		/* weren't unsigned before ??? */    /* 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 tmp;  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, &tmp);  return pack_d (res);}/* according to the demo, fpcmp returns a comparison with 0... thus   a<b -> -1   a==b -> 0   a>b -> +1 */static 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;}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);}#ifndef US_SOFTWARE_GOFAST/* These should be optimized for their specific tasks someday.  */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) ;}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) ;}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);}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) ;}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);}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 /* ! US_SOFTWARE_GOFAST */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 == 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);}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 : (-MAX_SI_INT)-1;  /* 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);}#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;  /* get reasonable MAX_USI_INT... */  if (isinf (&a))    return a.sign ? MAX_USI_INT : 0;  /* it is a negative number */  if (a.sign)    return 0;  /* 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 << ((FRACBITS + NGARDS) - a.normal_exp);  else    return a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);}#endifFLO_typenegate (FLO_type arg_a){  fp_number_type a;  unpack_d ((FLO_union_type *) & arg_a, &a);  flip_sign (&a);  return pack_d (&a);}#ifdef FLOATSFtype__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);}#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);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#ifndef FLOATextern SFtype __make_fp (fp_class_type, unsigned int, int, USItype);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);}SFtypedf_to_sf (DFtype arg_a){  fp_number_type in;  unpack_d ((FLO_union_type *) & arg_a, &in);  return __make_fp (in.class, in.sign, in.normal_exp,		    in.fraction.ll >> F_D_BITOFF);}#endif

⌨️ 快捷键说明

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