📄 fp-bit.c
字号:
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 + -