
Paul: Thanks for taking the time to make such a detailed review! On Sat, Jun 9, 2012 at 2:40 AM, Paul A. Bristow <pbristow@hetp.u-net.com>wrote:
-----Original Message----- From: boost-bounces@lists.boost.org [mailto: boost-bounces@lists.boost.org] On Behalf Of Jeffrey Lee Hellrung, Jr. Sent: Friday, June 08, 2012 3:28 PM To: boost@lists.boost.org; boost-announce@lists.boost.org; boost-users@lists.boost.org Subject: [boost] [review] Multiprecision review (June 8th - 17th, 2012)
-------- "The Multiprecision Library provides *User-defined* integer, rational and floating-point C++ types which try to emulate as closely as practicable the C++ built-in types, but provide for more range and precision. C++ Depending upon the number type, precision may be arbitrarily large (limited only by available memory), fixed at compile time values, for example 50 decimal digits, or a variable controlled at run-time by member functions. The types are expression-template-enabled for better performance than naive user-defined types." --------
What is your evaluation of the design?
Boost.Multiprecision is an exciting development because it provides two items that Boost has long needed in its toolkit: fixed and arbitrary precision integer types, and fixed and arbitrary precision floating-point types.
That Boost.Math functions can be called directly is a massive step forward - even just for 'trivial' tasks like pre-computing math constants.
Wheee! - we can now use brute force and effortlessly hurl heaps of bits at any recalcitrant problems.
Suddenly, we can do all sorts of tricks at altogether monstrous precision and range! Getting more precision for some of the calculation is suddenly painless.
(Of course limiting the hundreds-of-digits calculations to the nitty-bitty bits will reduce the speed penalty).
(Not to mention random and rational, and that complex and fixed-point might also finally be made fully generic is looking distinctly possible and that would be even more wonderful).
What is your evaluation of the implementation?
License and backend ================= Allowing a choice of backend has crucial license advantages, allowing the 'gold standard' optimised GMP, but also allowing the Boost licensed version with remarkably little loss of speed. (I note the price we are paying for the commercial greed and patent abuse that has made maintaining the GPL license status of GMP such a quasi-religious issue).
Crucially, the implementation works hard to be as near as possible plug-in for C++ built-in types including providing std::numeric_limits (where these - mostly- make sense). In general, all the iostream functions do what you could (reasonably) expect. And it is a very strong plus-point that fpclassify and all the usual suspects of regular C99 functions exist: this should mean that most moves from built-in floating-point to multiprecision should 'just work'.
(Any potential license problems from copyright of Christopher Kormanyos's e_float by the ACM have been resolved).
Speed =====
Fast enough for many purposes, especially if it is possible to use a GPL backend. Optional expression-template-enable is cool.
Testing ======
There is a big suite of test programs written by Christopher Kormanyos to test his e_float type (which engine was hi-jacked by John Maddock to extend it to (optionally) use expression templates). These provide a good assurance that the underlying integer and floating point types work correctly and that it is going to work when used in anger.
Unsurprisingly, I was able to run the test package using MSVC VS 10 OK. Don't hold your breath!
(Testing iostream is, of course, a nightmare - there are an infinity of possible I/O combinations and the standard is sketchy in places and there are some differences between major platforms, so portability is never going to be 100%. But I got the impression that it works as expected).
Writing a simple loopback stream output and re-input, I found that using Boost.Test to compare values can mislead.
A patch is at https://svn.boost.org/trac/boost/ticket/5758 #5758: Boost.Test Floating-point comparison diagnostic output does not support radix 10 (not enough digits displayed)
For example, it leads to nonsensical reports from a loopback test like [1e+2776234983093287513 != 1e+2776234983093287513] when the true situation should be obvious from this [1e+2776234983093287513 !=
9.99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 9999999999999999999999e+2776234983093287512]
However the underlying Boost.Test macros appeared to work fine and are used by a comprehensive set of tests provided (dealing with complications of multiple backend and error handling policies).
What is your evaluation of the documentation?
I was able to write some trivia before I needed to dig in. Nice. Convincing user examples. Warns of some dragons waiting to burn the unwary. (Very few typos - nice proof-reading ;-))
What is your evaluation of the potential usefulness of the library?
When you need it, you need it very badly. So essential.
Did you try to use the library? With what compiler?
Used with MSVC 10 for a few experiments and to calculate high precision constants.
Did 'what it said on the tin', and agreed with Mathematica and other sources.
Did you have any problems?
Shamefacedly, I fell into the pits noted below and was duly singed by the dragons lurking therein :-(
How much effort did you put into your evaluation?
Reasonable, including playing with e_float.
I wrote a simple loopback stream output and re-input using the random package. ss << std::setprecision(std::numeric_limits<cpp_dec_float_100>::max_digits10) << b << std::endl; It was essential to use max_digits10, not just digits10. This ran until I got bored.
Careful reading of docs.
Enough use to be confident it works OK.
Are you knowledgeable about the problem domain?
Faintly.
Do you think the library should be accepted as a Boost library?
Definitely YES.
Lastly, please consider that John and Christopher have compiled a TODO list [1] based on pre-review comments. Feel free to comment on the priority and necessity of such TODO items, and whether any might be show-stoppers or warrant conditional acceptance of the library.
No showstoppers. ============== It is ready for use.
I am sure that the library will be refined in the light of wider user experience (and that will only really come when it is issued as a Boost library).
Implicit conversion =============== Initially e_float (like NTL - used during development of Boost.Math as an example of a multiprecision type, and for calculation of constants) both forbade implicit conversion. But it soon became clear that it was impractical to make everything explicit and we patched NTL to permit this (and to provide the usual suspects of std::numeric_limits and functions too).
This leaves some dragons waiting for the unwary, so those who write
cpp_dec_float_100 v1234567890 =
1.23456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 012345678901234567890;
will get what they asked for, and deserve - the catastrophic loss of accuracy starting at the 17th decimal digit! (`std::numeric_limits<double>::max_digits10` = 17 for the common 64-bit representation).
This loss of accuracy will rarely jump out at you :-(
(If I get a £1, $1, or 1 euro for everyone who makes this mistake (or one of the many other complex pits discussed in the docs), I believe I will become rich ;-)
It would be nice to catch these mistakes, but not at the price of losing use of all the Boost.Math functionality (and much more). (I fantasize about a macro that can switch intelligently between explicit and implicit to protect the hapless user from his folly, but advising on loss of accuracy is probably really a compiler task).
On the old hand, it is really, really cool that using a string works: cpp_dec_float_50 df = "3.14159265358979323846264338327950288419716939937510";
Guard digits ========== The existence and (surprising) number of these has already been discussed and I see no problem with the way it works. It will be an exceptional program that really needs to use max_digits10 rather than digits10. (Boost.Test is an example, to avoid nonsensical display of [2 != 2] when guard digits differ - see above).
Paul
--- Paul A. Bristow, Prizet Farmhouse, Kendal LA8 8AB UK +44 1539 561830 07714330204 pbristow@hetp.u-net.com
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost