
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