Listing 2: The functions normalize and round

//    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;
        }
    }