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-17 17:44:53


Le 17/04/12 22:48, Christopher Kormanyos a écrit :
>>> 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
> It is a lot of coding. It was previously, in fact, my preference to
> require explicit construction and disallow and implicit mixing
> of the specialized number type with built-in types.
> But I later learned that boost.math follows the other strategy.
> This is the only reason why I keep mentioning this point,
> because of compatibility with boost.math and a potential
> boost.multiprecision.
I think I will implement both, depending on the family (see below).
>
>>> About converting
>>> 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.
>> Well, it should or not. I think that it should work only if
>> A * A -> A
> You can never please all of the people all of the time. But my
> preference is exclusively supporting the closed world. I personally
> do not like it if results grow-to-size. There will certainly be
> varying opinions on this.
Well, the fact is that I need the open world in my application, and I
see that other use to work with the closed world with satisfaction.
>
>> I think that we have two kind of fixed-point arithmetic
>> * open A * A -> 2A
>> * close A * A -> A
> It just scares me to think of all the coding you will need.
> Explicit ctor conversion from one size fixed-point to another
> and assignment operator should be enough. And you can keep
> the code amount down. But, again, there will be different
> opinions on this in the community.
>
>> 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 really want to put yourself through this kind of pain?
I have started to add a Family parameter to my prototype. This family
gives some properties as
* if builtins are implicit/explicitly convertible to/from fixed-points,
* if the fixed-point number is implicit/explicitly convertible from
other fixed-points when there is a possible loss of information,
* whether the its arithmetic operations are closed or open,
* whether there is a bound for the underlying type or it is unbounded
and uses chunks when needed.

Users of a fixed-point class could then use template aliases (if
supported) to define the fixed-point numbers adapted to its domain if
the family is always the same.

Note that operations between different families could be possible. We
need just to decide when this has a sense ;-)
IMO closed+open should be open and bounded+unbounded->unbounded. The
conversion axes takes in account just one fixed-point, so there is no
issue for them.

I recognize that this makes more complex the library, but not so much,
but I guess that this will help to provide a fixed-point library that
should please most of people.

Any better name for the family parameter is welcome. Domain?
For example the family/domain I need is explicits conversions even for
builtins, open arithmetic and bounded underlying type even smaller than
the intmax type of the machine.

>
>> 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>();
> I do. Others might not.
>
> After all I posted, perhaps a simple summary of my thoughts might help.
> Basically, I recommend the following:
>
> * Do support implicit conversion from built-in types (compatibility with strategy of boost.math).
> * Do not support result resizing or mixed fixed-point *intelligence*.
So you don't expect the preceding to work

    fixed_point<4, -14> result2 = pi_rep<2, -8>() * pi_rep<2, -6>();

> * Do support explicit conversion of mixed fixed-point but *only* via explicit ctor and copy-assign.
Do you find the implicit conversion when there is no loss of information
not useful?
> If you take a moment to consider these top-level design choices,
> you will find that they, in general, lead to the simplest code and
> reduce the sources of error for both author and users alike.
As you can see my needs are different. I understand yours also.

In order to get your design you will need to use implicit builtin
conversion, explicit fixed-points conversions, closed arithmetic and I
don't know if you need bounded or unbounded fixed-points.
>
> I finally adopted this strategy with my *third* formal fixed-point class.
>
> But again, one person alone can never be right and many experienced
> developers will have other opinions and, eventually, find the right
> mix in cooperation.
>
Thanks for all your comments that encourage myself to try to make a
better library. Even if at some points in time it could seem that the
library could be to complex and that I'm building a cathedral I hope at
the end of the walk it will easy of use and efficient.

Best,
Vicnte