Boost logo

Boost :

Subject: Re: [boost] [fixed_point] Request for interest in a binary fixed point library
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2012-04-16 18:38:29


Le 16/04/12 23:44, Christopher Kormanyos a écrit :
> <big snip>
>
>> Would this syntax be convenient? Or, do we need something intermediary as
>> f1 = convert(1.2345);
>> f2 = convert(f1 - 2);
>> f2 = convert(f1 / f2);
>> The template function convert will return a wrapper of its parameter that is accepted as an implicit conversion.
> <snip>
>> Best, Vicente
> As always, good luck with a project of such importance and complexity.
>
> I'm relatively new here. But I am concerned about the above-mentioned dialog.
>
> Perhaps I have not understood this dialog because the discussion was at
> a relatively high level of C++ abstraction. But boost already has a policy
> on mixing specialized numeric types with built-in types. As far as I know,
> a specialized type in boost is supposed to seamlessly interact with
> all built-in types on both the left-hand as well as the right-hand side
> of all expressions.
>
> I believe that boost mandates implicit conversion to built-in types
> *without* a conversion-wrapper. This means that if the user selects to
> lose performance by mixing, say, double with fixed_point, then
> the user did it---willingly, that is on purpose!
I'm seen the alternatives. How the user will use the library is explicit
conversion is needed each time there is a lost of range or resolution.

It is clear that coding with this rule and mixing builtins is
cumbersome. I could admit that mixin builtins could be take as some kind
of implicit conversion and

f1-2

could be interpreted as

f1 - (decltype(f1))(2)

But the conversion of f1 - (decltype(f1))(2) to f2 should be explicit in a open world and implicit in a closed world. (see below).

>
> About converting
>
> fixed_point<unsigned bits_mantissa,
> signed bits_fraction>
>
> from one mantissa/fraction representation to another, I say don't ever do
> it without explicit ctor call or assignment operator. If you don't do this,
> then the code amount blows up beyond what it reasonably should.
>
> You might have this:
> fixed_point<15, -16> radius<123, 100>(); // Ratio of approx. 1.23
>
> And you want to go to this:
> fixed_point<15, -16> result1 = pi_rep<15, -16>() * (radius * radius); // Should work!
>
> OK.
Well, it should or not. I think that it should work only if

A * A -> A

which I pretend is not always a good thing. I'm not saying that in other
contexts this is not acceptable.

I think that we have two kind of fixed-point arithmetic
* open A * A -> 2A
* close A * A -> A

Each one of these arithmetic should be supported by different class
families. We could use the same name in different namespaces. Users
using only one of this families will not see the naming difference just
adding a using declaration.

Do you expect this to work in the closed fixed point-world
   fixed_point<4, -14> result2 = pi_rep<2, -8>() * pi_rep<2, -6>();

Or should the user need to convert the parameters before to
fixed_point<4, -14>?
   fixed_point<4, -14> result2 = fixed_point<4, -14>(pi_rep<2, -8>()) *
fixed_point<4, -14>(pi_rep<2, -6>());

That is, does the closed fixed-point hierarchy define mixed fixed-point
arithmetic, other than the one with builtin?

A*B->C

In my opinion it will be confusing if

A*A->A
and
A*B->C
> But if you want to go to this:
> fixed_point<7, -8> result2 = pi_rep<15, -16>() * (radius * radius); // Should not work!
>
> In my opinion, it should not work. The user should explicitly convert
> to the other fixed-point type with copy-construct.
I agree this conversion must be explicit in any case.

>
> But this should work:
> fixed_point<15, -16> result3 = 3.141592654 * (radius * radius); // Should work!
>
>
In a closed world, yes.

Best,
Vicente


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk