// excerpts from fp.cpp
fp& fp::normalize(int e, long fr)
{ // set this object to normalized value of
// exponent e and fraction fr
if (fr == 0)
{ // handle zero specially
exp = 0;
frac = 0;
return *this;
}
is_neg = fr < 0;
fr = abs(fr);
if ((ONE << P) <= fr)
{ // handle fraction overflow
fr >>= 1;
++e;
}
else
while (fr < (MIN_NORM << P))
{ // scale left
fr <<= 1;
--e;
}
round(fr);
if ((ONE << P) <= fr)
{ // handle fraction overflow
fr >>= 1;
++e;
}
if (e < MIN_EXP)
exception(exp_underflow);
else if (MAX_EXP < e)
exception(exp_overflow);
exp = e;
frac = fr >> P;
return *this;
}
inline long low_bits(long fr)
{
return fr & ((1L << P) - 1);
}
void fp::round(long& fr)
{ // round infinite-precision result to fit representation
switch (rm)
{ // select appropriate code for rounding mode
case rm_zero:
// empty
break;
case rm_up:
if (!is_neg && low_bits(fr))
fr += 1L << P;
break;
case rm_down:
if (is_neg && low_bits(fr))
fr += 1L << P;
break;
case rm_nearest:
if ((fr & (1L << (P - 1))) == 0)
;
else if (low_bits(fr) == (1L << (P - 1))
&& ((fr & (1L << P)) == 0))
;
else
fr += 1L << P;
break;
}
}