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

📄 fp-bit.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 3 页
字号:
	  else	    {	      /* Add a one to the guards to round up */	      fraction += GARDROUND;	    }	  if (fraction >= IMPLICIT_2)	    {	      fraction >>= 1;	      exp += 1;	    }	  fraction >>= NGARDS;	}    }  /* We previously used bitfields to store the number, but this doesn't     handle little/big endian systems conveniently, so use shifts and     masks */#ifdef FLOAT_BIT_ORDER_MISMATCH  dst.bits.fraction = fraction;  dst.bits.exp = exp;  dst.bits.sign = sign;#else  dst.value_raw = fraction & ((((fractype)1) << FRACBITS) - (fractype)1);  dst.value_raw |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << FRACBITS;  dst.value_raw |= ((fractype) (sign & 1)) << (FRACBITS | EXPBITS);#endif#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)  {    halffractype tmp = dst.words[0];    dst.words[0] = dst.words[1];    dst.words[1] = tmp;  }#endif  return dst.value;}#endifextern void unpack_d (FLO_union_type *, fp_number_type *);#if defined(L_unpack_df) || defined(L_unpack_sf)voidunpack_d (FLO_union_type * src, fp_number_type * dst){  /* We previously used bitfields to store the number, but this doesn't     handle little/big endian systems conveniently, so use shifts and     masks */  fractype fraction;  int exp;  int sign;#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)  FLO_union_type swapped;  swapped.words[0] = src->words[1];  swapped.words[1] = src->words[0];  src = &swapped;#endif  #ifdef FLOAT_BIT_ORDER_MISMATCH  fraction = src->bits.fraction;  exp = src->bits.exp;  sign = src->bits.sign;#else  fraction = src->value_raw & ((((fractype)1) << FRACBITS) - (fractype)1);  exp = ((int)(src->value_raw >> FRACBITS)) & ((1 << EXPBITS) - 1);  sign = ((int)(src->value_raw >> (FRACBITS + EXPBITS))) & 1;#endif  dst->sign = sign;  if (exp == 0)    {      /* Hmm.  Looks like 0 */      if (fraction == 0)	{	  /* tastes like zero */	  dst->class = CLASS_ZERO;	}      else	{	  /* Zero exponent with non zero fraction - it's denormalized,	     so there isn't a leading implicit one - we'll shift it so	     it gets one.  */	  dst->normal_exp = exp - EXPBIAS + 1;	  fraction <<= NGARDS;	  dst->class = CLASS_NUMBER;#if 1	  while (fraction < IMPLICIT_1)	    {	      fraction <<= 1;	      dst->normal_exp--;	    }#endif	  dst->fraction.ll = fraction;	}    }  else if (exp == EXPMAX)    {      /* Huge exponent*/      if (fraction == 0)	{	  /* Attached to a zero fraction - means infinity */	  dst->class = CLASS_INFINITY;	}      else	{	  /* Non zero fraction, means nan */	  if (fraction & QUIET_NAN)	    {	      dst->class = CLASS_QNAN;	    }	  else	    {	      dst->class = CLASS_SNAN;	    }	  /* Keep the fraction part as the nan number */	  dst->fraction.ll = fraction;	}    }  else    {      /* Nothing strange about this number */      dst->normal_exp = exp - EXPBIAS;      dst->class = CLASS_NUMBER;      dst->fraction.ll = (fraction << NGARDS) | IMPLICIT_1;    }}#endif#if defined(L_addsub_sf) || defined(L_addsub_df)static fp_number_type *_fpadd_parts (fp_number_type * a,	      fp_number_type * b,	      fp_number_type * tmp){  intfrac tfraction;  /* Put commonly used fields in local variables.  */  int a_normal_exp;  int b_normal_exp;  fractype a_fraction;  fractype b_fraction;  if (isnan (a))    {      return a;    }  if (isnan (b))    {      return b;    }  if (isinf (a))    {      /* Adding infinities with opposite signs yields a NaN.  */      if (isinf (b) && a->sign != b->sign)	return nan ();      return a;    }  if (isinf (b))    {      return b;    }  if (iszero (b))    {      if (iszero (a))	{	  *tmp = *a;	  tmp->sign = a->sign & b->sign;	  return tmp;	}      return a;    }  if (iszero (a))    {      return b;    }  /* Got two numbers. shift the smaller and increment the exponent till     they're the same */  {    int diff;    a_normal_exp = a->normal_exp;    b_normal_exp = b->normal_exp;    a_fraction = a->fraction.ll;    b_fraction = b->fraction.ll;    diff = a_normal_exp - b_normal_exp;    if (diff < 0)      diff = -diff;    if (diff < FRAC_NBITS)      {	/* ??? This does shifts one bit at a time.  Optimize.  */	while (a_normal_exp > b_normal_exp)	  {	    b_normal_exp++;	    LSHIFT (b_fraction);	  }	while (b_normal_exp > a_normal_exp)	  {	    a_normal_exp++;	    LSHIFT (a_fraction);	  }      }    else      {	/* Somethings's up.. choose the biggest */	if (a_normal_exp > b_normal_exp)	  {	    b_normal_exp = a_normal_exp;	    b_fraction = 0;	  }	else	  {	    a_normal_exp = b_normal_exp;	    a_fraction = 0;	  }      }  }  if (a->sign != b->sign)    {      if (a->sign)	{	  tfraction = -a_fraction + b_fraction;	}      else	{	  tfraction = a_fraction - b_fraction;	}      if (tfraction >= 0)	{	  tmp->sign = 0;	  tmp->normal_exp = a_normal_exp;	  tmp->fraction.ll = tfraction;	}      else	{	  tmp->sign = 1;	  tmp->normal_exp = a_normal_exp;	  tmp->fraction.ll = -tfraction;	}      /* and renormalize it */      while (tmp->fraction.ll < IMPLICIT_1 && tmp->fraction.ll)	{	  tmp->fraction.ll <<= 1;	  tmp->normal_exp--;	}    }  else    {      tmp->sign = a->sign;      tmp->normal_exp = a_normal_exp;      tmp->fraction.ll = a_fraction + b_fraction;    }  tmp->class = CLASS_NUMBER;  /* Now the fraction is added, we have to shift down to renormalize the     number */  if (tmp->fraction.ll >= IMPLICIT_2)    {      LSHIFT (tmp->fraction.ll);      tmp->normal_exp++;    }  return tmp;}FLO_typeadd (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 = _fpadd_parts (&a, &b, &tmp);  return pack_d (res);}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);}#endif#if defined(L_mul_sf) || defined(L_mul_df)static INLINE 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 */  {#if defined(NO_DI_MODE)    {      fractype x = a->fraction.ll;      fractype ylow = b->fraction.ll;      fractype yhigh = 0;      int bit;      /* ??? 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);}#endif#if defined(L_div_sf) || defined(L_div_df)static INLINE fp_number_type *_fpdiv_parts (fp_number_type * a,	      fp_number_type * b){  fractype bit;  fractype numerator;  fractype denominator;

⌨️ 快捷键说明

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