
Le 31/05/12 22:10, Christopher Kormanyos a écrit :
Thank you for your comments, Vicente.
I have spent some hours reading the documentation. Here are some comments and a lot of questions. Did you get a chance to use it also? You always have such good comments, that we would benefit from some your experience with use-cases. I would like to create a backend for my fixed_point library before the review.
I have run the test and I'm getting a lot of errors for test_float_io_cpp_dec_float bjam toolset=clang-2.9,clang-2.9x -j2 ... Precision is: 13 Got: -987654312.0000000000000 Expected: -0.0000000008567 Testing value -8.5665356058806096939e-10 Formatting flags were: fixed showpos Precision is: 13 Got: -987654312.0000000000000 Expected: -0.0000000008567 9360 errors detected. EXIT STATUS: 1 ====== END OUTPUT ====== and others like darwin.compile.c++ bin/floating_point_examples.test/darwin-4.2.1/debug/floating_point_examples.o ../example/floating_point_examples.cpp:11:17: error: array: No such file or directory ../example/floating_point_examples.cpp: In function 'mp_type mysin(const mp_type&)': ../example/floating_point_examples.cpp:361: error: expected initializer before '<' token ../example/floating_point_examples.cpp:666: error: expected `}' at end of input "g++" -ftemplate-depth-128 -O0 -fno-inline -Wall -g -dynamic -gdwarf-2 -fexceptions -fPIC -I"../../.." -I"/Users/viboes/boost/trunk" -c -o "bin/floating_point_examples.test/darwin-4.2.1/debug/floating_point_examples.o" "../example/floating_point_examples.cpp"
* As all the classes are at the multi-precision namespace, why name the main class mp_number and not just number? typedef mp::number<mp::mpfr_float_backend<300> > my_float; Good question :) I don't have a particulary strong view whether it's "number" or "mp_number", but would like to know what others think. I actually *do* have a slight preference for "mp_number", with the *mp_* part. It simply reminds me that I'm actually doing something with multiple precision type. An experienced booster once told me that boost favors clarity over terseness. Perhaps this is a case thereof. OK. I see.
* I think that the fact that operands of different backends can not be mixed on the same operation limits some interesting operations: I understand your comment, Vicente. In my experience, the reduced error resulting from forbidding non-explicit mixing of back-ends far outweighs potential benefits from allowing them.
Of course, this is only an opinion. Others will disagree. When we discussed potential fixed-point types, you may remember my recommendation.
I usually recommend: * Do support seamless interaction with built-in types. * Forbid implicit conversion of non-same specialized types. * Potentially support explicit construction of one type from another.
Accordingly, we do support this:
boost::multiprecision::cpp_dec_float_100 a(boost::multiprecision::cpp_dec_float_100(123) / 100); boost::multiprecision::cpp_dec_float_50 b(boost::multiprecision::cpp_dec_float_50(456) / 100); boost::multiprecision::cpp_dec_float_50 c = boost::multiprecision::cpp_dec_float_50(a) * b;
But we do not support this:
boost::multiprecision::cpp_dec_float_100 a(boost::multiprecision::cpp_dec_float_100(123) / 100); boost::multiprecision::cpp_dec_float_50 b(boost::multiprecision::cpp_dec_float_50(456) / 100); boost::multiprecision::cpp_dec_float_50 c = a * b; This is OK as there is no implicit conversion from cpp_dec_float_100 to cpp_dec_float_50. But I would expect
boost::multiprecision::cpp_dec_float_100 d = a * b; to compile, but it doesn't. Why the implicit conversion from cpp_dec_float_50 to cpp_dec_float_100 doesn't helps?
* can we convert from a cpp_dec_float_100 to a cpp_dec_float_50? if yes, which rounding policy is applied? Do you plan to let the user configure the rounding policy? Yes you can convert, and the rounding is currently poorly defined :-( I'll let Chris answer about rounding policies, but basically it's a whole lot of work. The aim is not to try and compete with say MPFR, but be "good enough" for most purposes. For some suitable definition of "good enough" obviously ;-) Yes, I confirm John's statement. You can explicitly convert. Unfortunately, there simply is no support for rounding at this time in the cpp_dec_float back-end.
To be quite honest, I do not have the time to work out a sensible rounding scheme for the base-10 back-end in a reasonable time schedule. One of the difficulties of base-10 is its unruly nature regarding rounding.
I see the present review candidate of Boost.Multiprecision as a good start on a long-term development with many potential future improvements.
In particular, my long-term goal with a potential Boost.Multiprecision is to create a greatly improved base-2 floating-point back-end in the future. At that time, I would want to target vastly improved performance, sensible allocation/deallocation, clear rounding semantics, etc.
One of the advantages of John's architecture is that mp_number can be used with any back-end fulfilling the requirements. So one could potentially phase out cpp_dec_float via deprecation in the future and support a future cpp_bin_float. Yes, having a common interface is a good thing and it can be obtained with different approaches. I believe the main goal of mp_number is to
I understand your words as, the user can not configure the way rounding is done. But AFAIU it is valid to do a conversion, so the documentation should add which kind of rounding is applied. using namespace boost::multiprecision; { cpp_dec_float_50 a(cpp_dec_float_50(-1) / 3); cpp_dec_float_100 b=a; { boost::io::ios_precision_saver ifs( std::cout ); std::cout << "setprecision(N) " << std::setprecision(50) << a << std::endl; std::cout << "setprecision(max_digits10)= " << std::setprecision(std::numeric_limits<cpp_dec_float_50>::max_digits10) << a << std::endl; } { boost::io::ios_precision_saver ifs( std::cout ); std::cout << "setprecision(N) " << std::setprecision(100) << b << std::endl; std::cout << "setprecision(max_digits10)= " << std::setprecision(std::numeric_limits<cpp_dec_float_100>::max_digits10) << b << std::endl; } } std::cout << "*****************" << std::endl; { cpp_dec_float_100 a(cpp_dec_float_100(-1) / 3); cpp_dec_float_50 b=cpp_dec_float_50(a); { boost::io::ios_precision_saver ifs( std::cout ); std::cout << "setprecision(N) " << std::setprecision(100) << a << std::endl; std::cout << "setprecision(max_digits10)= " << std::setprecision(std::numeric_limits<cpp_dec_float_100>::max_digits10) << a << std::endl; } { boost::io::ios_precision_saver ifs( std::cout ); std::cout << "setprecision(N) " << std::setprecision(100) << b << std::endl; std::cout << "setprecision(max_digits10)= " << std::setprecision(std::numeric_limits<cpp_dec_float_50>::max_digits10) << b << std::endl; } } std::cout << "*****************" << std::endl; { cpp_dec_float_50 a(cpp_dec_float_50(1) / 3); cpp_dec_float_100 b=a; { boost::io::ios_precision_saver ifs( std::cout ); std::cout << "setprecision(N) " << std::setprecision(50) << a << std::endl; std::cout << "setprecision(max_digits10)= " << std::setprecision(std::numeric_limits<cpp_dec_float_50>::max_digits10) << a << std::endl; } { boost::io::ios_precision_saver ifs( std::cout ); std::cout << "setprecision(N) " << std::setprecision(100) << b << std::endl; std::cout << "setprecision(max_digits10)= " << std::setprecision(std::numeric_limits<cpp_dec_float_100>::max_digits10) << b << std::endl; } } std::cout << "*****************" << std::endl; { cpp_dec_float_100 a(cpp_dec_float_100(1) / 3); cpp_dec_float_50 b=cpp_dec_float_50(a); { boost::io::ios_precision_saver ifs( std::cout ); std::cout << "setprecision(N) " << std::setprecision(100) << a << std::endl; std::cout << "setprecision(max_digits10)= " << std::setprecision(std::numeric_limits<cpp_dec_float_100>::max_digits10) << a << std::endl; } { boost::io::ios_precision_saver ifs( std::cout ); std::cout << "setprecision(N) " << std::setprecision(100) << b << std::endl; std::cout << "setprecision(max_digits10)= " << std::setprecision(std::numeric_limits<cpp_dec_float_50>::max_digits10) << b << std::endl; } } gives setprecision(N) -0.33333333333333333333333333333333333333333333333333 setprecision(max_digits10)= -0.33333333333333333333333333333333333333333333333333333333333333333333333333333333 setprecision(N) -0.33333333333333333333333333333333333333333333333333333333333333333333333333333333 setprecision(max_digits10)= -0.33333333333333333333333333333333333333333333333333333333333333333333333333333333 ***************** setprecision(N) -0.3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333 setprecision(max_digits10)= -0.33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333 setprecision(N) -0.33333333333333333333333333333333333333333333333333333333333333333333333333333333 setprecision(max_digits10)= -0.33333333333333333333333333333333333333333333333333333333333333333333333333333333 ***************** setprecision(N) 0.33333333333333333333333333333333333333333333333333 setprecision(max_digits10)= 0.33333333333333333333333333333333333333333333333333333333333333333333333333333333 setprecision(N) 0.33333333333333333333333333333333333333333333333333333333333333333333333333333333 setprecision(max_digits10)= 0.33333333333333333333333333333333333333333333333333333333333333333333333333333333 ***************** setprecision(N) 0.3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333 setprecision(max_digits10)= 0.33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333 setprecision(N) 0.33333333333333333333333333333333333333333333333333333333333333333333333333333333 setprecision(max_digits10)= 0.33333333333333333333333333333333333333333333333333333333333333333333333333333333 so I guess the rounding is towards zero. put in a common class the expression templates.
If not, what about a mp_number_cast function taking as parameter a rounding policy? I think it would be very hard to a coherant set of rounding policies that were applicable to all backends... including third party ones that haven't been thought of yet. Basically ducking that issue at present :-( Yes, and keep ducking. We won't get it done correctly in a reasonable time scale. In my opinion, we can consider in association with an improved BPL base-2 floating-point back-end in the future. Backwards compatibility could be achieved with a potential rounding policy of *no rounding*. MPFR, GMP, MPIR and the rest will get the rounding that they have or don't have.
Or *round_to_zero* instead of *no rounding*.
* Do you plan to add constexpr and noexcept to the interface? After thinking a little bit I'm wondering if this is this possible when using 3pp libraries backends that don't provide them? I'm also not sure if it's possible, or even what we would gain - I can't offhand think of any interfaces that could use constexp for example. If you are aiming at compile-time constant mp_numbers, then I do not believe it is possible with the specified low-complexity constraints a constexpr functions and objects.
This works with state-of-the-art compilers today. constexpr double pi = 3.14159265358979323846
But this may not work soon, or ever. constexpr boost::multiprecision::cpp_dec_float_50 pi("3.14159265358979323846264338327950288419716939937510582097494"); Not all operations can be defined as constexpr but I will expect some to be.
constexpr boost::multiprecision::cpp_dec_float_50 pi(3.14159265358979323846); http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3352.html propose also to have some kind of literals through some factory methods. |to_nonnegative<2884,-4>()| will produce a |nonnegative| constant with a range and resolution just sufficient to hold the value 2884*2^-4 . I don't know if this kind of factories could be applicable to the current backends.
* How the performances of mp_number<this_trivial_adaptor<float>, false> will compare with float? No idea, might be interesting to find out, will investigate. I never tested it yet. It interests me as well for my research in generic numeric programming.
Let us know as soon as you have some results. Best, Vicente