From: Matt Gruenke (mgruenke_at_[hidden])
Date: 2008-08-01 04:21:12


Anthony Williams wrote:
> "John C. Femiani" <john.femiani_at_[hidden]> writes:
>

>> Also, do your implementations for /= and *= actually round? You
>> actually seem to be using the round policy for conversions, is that
>> right? Have you looked at the numeric/conversion stuff? (I haven't
>> grokked it yet).
>>
>
> The division throws away the lower "frac_bits" of the result:
>

Speaking of division, while I'd expect /= to return the same type as the
LHS operand, the way I've previously implemented fixed point division is
to return:
    result_int_bits = (numer_int_bits + denom_frac_bits + 1)
    result_frac_bits = (numer_frac_bits + denom_int_bits - 1)

It's a little easier to understand the rationale, if you separately
consider 1/x and x * y. For 1/x, returning the following avoids
overflow and is reversible (if the result happens to be exact):
    result_int_bits = input_frac_bits + 1
    result_frac_bits = denom_int_bits -1

The result of x * y is obviously:
    result_int_bits = x_int_bits + y_int_bits
    result_frac_bits = x_frac_bits + y_frac_bits

Then, x/y is simply viewed as multiplication by the inverse of y, but
computed in one shot.

I haven't implemented /=, but I'd be tempted to compute it with less
intermediate precision (i.e. only pre-scaling the numerator by
2^denom_frac_bits). I suppose, depending on rounding policy, you could
compute it with an extra bit that gets rounded off.

Matt