$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Matt Gruenke (mgruenke_at_[hidden])
Date: 2008-08-01 13:52:43
John C. Femiani wrote:
> Matt Gruenke wrote:
>> John C. Femiani wrote:
>>> Matt Gruenke wrote:
>>>> 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)
>>> So then what happens to the value of X after I say Z = X /=Y?
>>> Do you mean '/', instead of '/='?
>>
>> Yes, I was describing the behavior of my operator/(). I hadn't
>> written an operator/=().
>>
> I think perhaps the issue with division is that rounding policy should
> be rethought. Also:
>> base_type tmp = (base_type)val / (base_type)x.val;
>> val = tmp << (frac_bits);
> should be something like
>
> static const int DENOMINATOR= 1 << frac_bits;
> base_type tmp = rounding_policy::divide(val * DENOMINATOR, x.val);
>
> I think the old way lost a lot of precision because it divided before
> multiplying.e.g.
By replying to my message, it seems like you might be confusing two
implementations. The one I was describing is my own private code, which
worked the way you're suggesting.
> Then for multiplying:
>
>> base_type tmp = (base_type)val * (base_type)x.val;
>> val = tmp >> (frac_bits);
> could possibly be:
>
> val = rounding_policy::divide( val * x.val, DENOMINATOR);
The approach I took for operator*() was to return a larger type that
lost no precision or range from the multiplication. Then the rounding
happens when you assign the result to a smaller type. This both gives
the user a natural way to control how much precision is preserved and
avoids overhead from any unnecessary rounding (i.e. rounding more
frequently than the user might want or need).
Matt