]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/multiprecision/doc/multiprecision.qbk
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / multiprecision / doc / multiprecision.qbk
CommitLineData
7c673cae
FG
1[/
2 Copyright 2011, 2013 John Maddock.
3 Copyright 2013 Paul A. Bristow.
4 Copyright 2013 Christopher Kormanyos.
5
6 Distributed under the Boost Software License, Version 1.0.
7 (See accompanying file LICENSE_1_0.txt or copy at
8 http://www.boost.org/LICENSE_1_0.txt).
9]
10
11[library Boost.Multiprecision
12 [quickbook 1.7]
13 [copyright 2002-2013 John Maddock and Christopher Kormanyos]
14 [purpose Multiprecision Number library]
15 [license
16 Distributed under the Boost Software License, Version 1.0.
17 (See accompanying file LICENSE_1_0.txt or copy at
18 [@http://www.boost.org/LICENSE_1_0.txt])
19 ]
20 [authors [Maddock, John], [Kormanyos, Christopher]]
21 [/last-revision $Date: 2011-07-08 18:51:46 +0100 (Fri, 08 Jul 2011) $]
22]
23
24[import html4_symbols.qbk]
25
26[import ../example/gmp_snips.cpp]
27[import ../example/mpfr_snips.cpp]
28[import ../example/mpfi_snips.cpp]
29[import ../example/float128_snips.cpp]
30[import ../example/cpp_dec_float_snips.cpp]
31[import ../example/cpp_bin_float_snips.cpp]
32[import ../example/cpp_int_import_export.cpp]
33[import ../example/cpp_bin_float_import_export.cpp]
34[import ../example/tommath_snips.cpp]
35[import ../example/cpp_int_snips.cpp]
36[import ../example/random_snips.cpp]
37[import ../example/safe_prime.cpp]
38[import ../example/mixed_integer_arithmetic.cpp]
39[import ../example/logged_adaptor.cpp]
40[import ../example/numeric_limits_snips.cpp]
41[import ../example/hashing_examples.cpp]
42
43[template mpfr[] [@http://www.mpfr.org MPFR]]
44[template mpfi[] [@http://perso.ens-lyon.fr/nathalie.revol/software.html MPFI]]
45[template gmp[] [@http://gmplib.org GMP]]
46[template mpf_class[] [@http://gmplib.org/manual/C_002b_002b-Interface-Floats.html#C_002b_002b-Interface-Floats mpf_class]]
47[template mpfr_class[] [@http://math.berkeley.edu/~wilken/code/gmpfrxx/ mpfr_class]]
48[template mpreal[] [@http://www.holoborodko.com/pavel/mpfr/ mpreal]]
49[template mpir[] [@http://mpir.org/ MPIR]]
50[template tommath[] [@http://libtom.org/?page=features&newsitems=5&whatfile=ltm libtommath]]
51[template quadmath[] [@http://gcc.gnu.org/onlinedocs/libquadmath/ libquadmath]]
52
53[template super[x]'''<superscript>'''[x]'''</superscript>''']
54[template sub[x]'''<subscript>'''[x]'''</subscript>''']
55
56[template equation[name] '''<inlinemediaobject>
57<imageobject role="html">
58<imagedata fileref="../'''[name]'''.png"></imagedata>
59</imageobject>
60<imageobject role="print">
61<imagedata fileref="../'''[name]'''.svg"></imagedata>
62</imageobject>
63</inlinemediaobject>''']
64
65[def __cpp_int [link boost_multiprecision.tut.ints.cpp_int cpp_int]]
66[def __gmp_int [link boost_multiprecision.tut.ints.gmp_int gmp_int]]
67[def __tom_int [link boost_multiprecision.tut.ints.tom_int tom_int]]
68[def __gmp_float [link boost_multiprecision.tut.floats.gmp_float gmp_float]]
69[def __mpf_float [link boost_multiprecision.tut.floats.gmp_float gmp_float]]
70[def __mpfr_float_backend [link boost_multiprecision.tut.floats.mpfr_float mpfr_float]]
71[def __cpp_bin_float [link boost_multiprecision.tut.floats.cpp_bin_float cpp_bin_float]]
72[def __cpp_dec_float [link boost_multiprecision.tut.floats.cpp_dec_float cpp_dec_float]]
73[def __gmp_rational [link boost_multiprecision.tut.rational.gmp_rational gmp_rational]]
74[def __cpp_rational [link boost_multiprecision.tut.rational.cpp_rational cpp_rational]]
75[def __tommath_rational [link boost_multiprecision.tut.rational.tommath_rational tommath_rational]]
76[def __number [link boost_multiprecision.ref.number number]]
77[def __float128 [link boost_multiprecision.tut.floats.float128 float128]]
78[def __debug_adaptor [link boost_multiprecision.tut.misc.debug_adaptor debug_adaptor]]
79[def __logged_adaptor [link boost_multiprecision.tut.misc.logged_adaptor logged_adaptor]]
80[def __rational_adaptor [link boost_multiprecision.tut.rational.rational_adaptor rational_adaptor]]
81
82[section:intro Introduction]
83
84The Multiprecision Library provides [link boost_multiprecision.tut.ints integer],
85[link boost_multiprecision.tut.rational rational]
86and [link boost_multiprecision.tut.floats floating-point] types in C++ that have more
87range and precision than C++'s ordinary built-in types.
88The big number types in Multiprecision can be used with a wide
89selection of basic mathematical operations, elementary transcendental
90functions as well as the functions in Boost.Math.
91The Multiprecision types can also interoperate with the
92built-in types in C++ using clearly defined conversion rules.
93This allows Boost.Multiprecision to be used for all
94kinds of mathematical calculations involving integer,
95rational and floating-point types requiring extended
96range and precision.
97
98Multiprecision consists of a generic interface to the
99mathematics of large numbers as well as a selection of
100big number back ends, with support for integer, rational and
101floating-point types. Boost.Multiprecision provides a selection
102of back ends provided off-the-rack in including
103interfaces to GMP, MPFR, MPIR, TomMath as well as
104its own collection of Boost-licensed, header-only back ends for
105integers, rationals and floats. In addition, user-defined back ends
106can be created and used with the interface of Multiprecision,
107provided the class implementation adheres to the necessary
108[link boost_multiprecision.ref.backendconc concepts].
109
110Depending upon the number type, precision may be arbitrarily large
111(limited only by available memory), fixed at compile time
112(for example 50 or 100 decimal digits), or a variable controlled at run-time
113by member functions. The types are expression-template-enabled for
114better performance than naive user-defined types.
115
116The Multiprecision library comes in two distinct parts:
117
118* An expression-template-enabled front-end `number`
119that handles all the operator overloading, expression evaluation optimization, and code reduction.
120* A selection of back-ends that implement the actual arithmetic operations, and need conform only to the
121reduced interface requirements of the front-end.
122
123Separation of front-end and back-end allows use of highly refined, but restricted license libraries
124where possible, but provides Boost license alternatives for users who must have a portable
125unconstrained license. Which is to say some back-ends rely on 3rd party libraries, but a header-only Boost license version is always
126available (if somewhat slower).
127
128Should you just wish to cut to the chase and use a fully Boost-licensed number type, then skip to
129__cpp_int for multiprecision integers, __cpp_dec_float for multiprecision floating-point types
130and __cpp_rational for rational types.
131
132The library is often used via one of the predefined typedefs: for example if you wanted an
133[@http://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic arbitrary precision]
134integer type using [gmp] as the underlying implementation then you could use:
135
136 #include <boost/multiprecision/gmp.hpp> // Defines the wrappers around the GMP library's types
137
138 boost::multiprecision::mpz_int myint; // Arbitrary precision integer type.
139
140Alternatively, you can compose your own multiprecision type, by combining `number` with one of the
141predefined back-end types. For example, suppose you wanted a 300 decimal digit floating-point type
142based on the [mpfr] library. In this case, there's no predefined typedef with that level of precision,
143so instead we compose our own:
144
145 #include <boost/multiprecision/mpfr.hpp> // Defines the Backend type that wraps MPFR
146
147 namespace mp = boost::multiprecision; // Reduce the typing a bit later...
148
149 typedef mp::number<mp::mpfr_float_backend<300> > my_float;
150
151 my_float a, b, c; // These variables have 300 decimal digits precision
152
153We can repeat the above example, but with the expression templates disabled (for faster compile times, but slower runtimes)
154by passing a second template argument to `number`:
155
156 #include <boost/multiprecision/mpfr.hpp> // Defines the Backend type that wraps MPFR
157
158 namespace mp = boost::multiprecision; // Reduce the typing a bit later...
159
160 typedef mp::number<mp::mpfr_float_backend<300>, et_off> my_float;
161
162 my_float a, b, c; // These variables have 300 decimal digits precision
163
164We can also mix arithmetic operations between different types, provided there is an unambiguous implicit conversion from one
165type to the other:
166
167 #include <boost/multiprecision/cpp_int.hpp>
168
169 namespace mp = boost::multiprecision; // Reduce the typing a bit later...
170
171 mp::int128_t a(3), b(4);
172 mp::int512_t c(50), d;
173
174 d = c * a; // OK, result of mixed arithmetic is an int512_t
175
176Conversions are also allowed:
177
178 d = a; // OK, widening conversion.
179 d = a * b; // OK, can convert from an expression template too.
180
181However conversions that are inherently lossy are either declared explicit or else forbidden altogether:
182
183 d = 3.14; // Error implicit conversion from float not allowed.
184 d = static_cast<mp::int512_t>(3.14); // OK explicit construction is allowed
185
186Mixed arithmetic will fail if the conversion is either ambiguous or explicit:
187
188 number<cpp_int_backend<>, et_off> a(2);
189 number<cpp_int_backend<>, et_on> b(3);
190
191 b = a * b; // Error, implicit conversion could go either way.
192 b = a * 3.14; // Error, no operator overload if the conversion would be explicit.
193
194[h4 Move Semantics]
195
196On compilers that support rvalue-references, class `number` is move-enabled if the underlying backend is.
197
198In addition the non-expression template operator overloads (see below) are move aware and have overloads
199that look something like:
200
201 template <class B>
202 number<B, et_off> operator + (number<B, et_off>&& a, const number<B, et_off>& b)
203 {
204 return std::move(a += b);
205 }
206
207These operator overloads ensure that many expressions can be evaluated without actually generating any temporaries.
208However, there are still many simple expressions such as:
209
210 a = b * c;
211
212Which don't noticeably benefit from move support. Therefore, optimal performance comes from having both
213move-support, and expression templates enabled.
214
215Note that while "moved-from" objects are left in a sane state, they have an unspecified value, and the only permitted
216operations on them are destruction or the assignment of a new value. Any other operation should be considered
217a programming error and all of our backends will trigger an assertion if any other operation is attempted. This behavior
218allows for optimal performance on move-construction (i.e. no allocation required, we just take ownership of the existing
219object's internal state), while maintaining usability in the standard library containers.
220
221[h4 Expression Templates]
222
223Class `number` is expression-template-enabled: that means that rather than having a multiplication
224operator that looks like this:
225
226 template <class Backend>
227 number<Backend> operator * (const number<Backend>& a, const number<Backend>& b)
228 {
229 number<Backend> result(a);
230 result *= b;
231 return result;
232 }
233
234Instead the operator looks more like this:
235
236 template <class Backend>
237 ``['unmentionable-type]`` operator * (const number<Backend>& a, const number<Backend>& b);
238
239Where the "unmentionable" return type is an implementation detail that, rather than containing the result
240of the multiplication, contains instructions on how to compute the result. In effect it's just a pair
241of references to the arguments of the function, plus some compile-time information that stores what the operation
242is.
243
244The great advantage of this method is the ['elimination of temporaries]: for example the "naive" implementation
245of `operator*` above, requires one temporary for computing the result, and at least another one to return it. It's true
246that sometimes this overhead can be reduced by using move-semantics, but it can't be eliminated completely. For example,
247lets suppose we're evaluating a polynomial via Horner's method, something like this:
248
249 T a[7] = { /* some values */ };
250 //....
251 y = (((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0];
252
253If type `T` is a `number`, then this expression is evaluated ['without creating a single temporary value]. In contrast,
254if we were using the [mpfr_class] C++ wrapper for [mpfr] - then this expression would result in no less than 11
255temporaries (this is true even though [mpfr_class] does use expression templates to reduce the number of temporaries somewhat). Had
256we used an even simpler wrapper around [mpfr] like [mpreal] things would have been even worse and no less that 24 temporaries
257are created for this simple expression (note - we actually measure the number of memory allocations performed rather than
258the number of temporaries directly, note also that the [mpf_class] wrapper that will be supplied with GMP-5.1 reduces the number of
259temporaries to pretty much zero). Note that if we compile with expression templates disabled and rvalue-reference support
260on, then actually still have no wasted memory allocations as even though temporaries are created, their contents are moved
261rather than copied.
262[footnote The actual number generated will depend on the compiler, how well it optimises the code, and whether it supports
263rvalue references. The number of 11 temporaries was generated with Visual C++ 10]
264
265[important
266Expression templates can radically reorder the operations in an expression, for example:
267
268 a = (b * c) * a;
269
270Will get transformed into:
271
272 a *= c;
273 a *= b;
274
275If this is likely to be an issue for a particular application, then they should be disabled.
276]
277
278This library also extends expression template support to standard library functions like `abs` or `sin` with `number`
279arguments. This means that an expression such as:
280
281 y = abs(x);
282
283can be evaluated without a single temporary being calculated. Even expressions like:
284
285 y = sin(x);
286
287get this treatment, so that variable 'y' is used as "working storage" within the implementation of `sin`,
288thus reducing the number of temporaries used by one. Of course, should you write:
289
290 x = sin(x);
291
292Then we clearly can't use `x` as working storage during the calculation, so then a temporary variable
293is created in this case.
294
295Given the comments above, you might be forgiven for thinking that expression-templates are some kind of universal-panacea:
296sadly though, all tricks like this have their downsides. For one thing, expression template libraries
297like this one, tend to be slower to compile than their simpler cousins, they're also harder to debug
298(should you actually want to step through our code!), and rely on compiler optimizations being turned
299on to give really good performance. Also, since the return type from expressions involving `number`s
300is an "unmentionable implementation detail", you have to be careful to cast the result of an expression
301to the actual number type when passing an expression to a template function. For example, given:
302
303 template <class T>
304 void my_proc(const T&);
305
306Then calling:
307
308 my_proc(a+b);
309
310Will very likely result in obscure error messages inside the body of `my_proc` - since we've passed it
311an expression template type, and not a number type. Instead we probably need:
312
313 my_proc(my_number_type(a+b));
314
315Having said that, these situations don't occur that often - or indeed not at all for non-template functions.
316In addition, all the functions in the Boost.Math library will automatically convert expression-template arguments
317to the underlying number type without you having to do anything, so:
318
319 mpfr_float_100 a(20), delta(0.125);
320 boost::math::gamma_p(a, a + delta);
321
322Will work just fine, with the `a + delta` expression template argument getting converted to an `mpfr_float_100`
323internally by the Boost.Math library.
324
325One other potential pitfall that's only possible in C++11: you should never store an expression template using:
326
327 auto my_expression = a + b - c;
328
329unless you're absolutely sure that the lifetimes of `a`, `b` and `c` will outlive that of `my_expression`.
330
331And finally... the performance improvements from an expression template library like this are often not as
332dramatic as the reduction in number of temporaries would suggest. For example if we compare this library with
333[mpfr_class] and [mpreal], with all three using the underlying [mpfr] library at 50 decimal digits precision then
334we see the following typical results for polynomial execution:
335
336[table Evaluation of Order 6 Polynomial.
337[[Library] [Relative Time] [Relative number of memory allocations]]
338[[number] [1.0 (0.00957s)] [1.0 (2996 total)]]
339[[[mpfr_class]] [1.1 (0.0102s)] [4.3 (12976 total)]]
340[[[mpreal]] [1.6 (0.0151s)] [9.3 (27947 total)]]
341]
342
343As you can see, the execution time increases a lot more slowly than the number of memory allocations. There are
344a number of reasons for this:
345
346* The cost of extended-precision multiplication and division is so great, that the times taken for these tend to
347swamp everything else.
348* The cost of an in-place multiplication (using `operator*=`) tends to be more than an out-of-place
349`operator*` (typically `operator *=` has to create a temporary workspace to carry out the multiplication, where
350as `operator*` can use the target variable as workspace). Since the expression templates carry out their
351magic by converting out-of-place operators to in-place ones, we necessarily take this hit. Even so the
352transformation is more efficient than creating the extra temporary variable, just not by as much as
353one would hope.
354
355Finally, note that `number` takes a second template argument, which, when set to `et_off` disables all
356the expression template machinery. The result is much faster to compile, but slower at runtime.
357
358We'll conclude this section by providing some more performance comparisons between these three libraries,
359again, all are using [mpfr] to carry out the underlying arithmetic, and all are operating at the same precision
360(50 decimal digits):
361
362[table Evaluation of Boost.Math's Bessel function test data
363[[Library] [Relative Time] [Relative Number of Memory Allocations]]
364[[mpfr_float_50] [1.0 (5.78s)] [1.0 (1611963)]]
365[[number<mpfr_float_backend<50>, et_off>[br](but with rvalue reference support)]
366 [1.1 (6.29s)] [2.64 (4260868)]]
367[[[mpfr_class]] [1.1 (6.28s)] [2.45 (3948316)]]
368[[[mpreal]] [1.65 (9.54s)] [8.21 (13226029)]]
369]
370
371[table Evaluation of Boost.Math's Non-Central T distribution test data
372[[Library][Relative Time][Relative Number of Memory Allocations]]
373[[number] [1.0 (263s)][1.0 (127710873)]]
374[[number<mpfr_float_backend<50>, et_off>[br](but with rvalue reference support)]
375 [1.0 (260s)][1.2 (156797871)]]
376[[[mpfr_class]] [1.1 (287s)][2.1 (268336640)]]
377[[[mpreal]] [1.5 (389s)][3.6 (466960653)]]
378]
379
380The above results were generated on Win32 compiling with Visual C++ 2010, all optimizations on (/Ox),
381with MPFR 3.0 and MPIR 2.3.0.
382
383[endsect] [/section:intro Introduction]
384
385[section:tut Tutorial]
386
387In order to use this library you need to make two choices:
388
389* What kind of number do I want ([link boost_multiprecision.tut.ints integer],
390[link boost_multiprecision.tut.floats floating-point] or [link boost_multiprecision.tut.rational rational]).
391* Which back-end do I want to perform the actual arithmetic (Boost-supplied, GMP, MPFR, Tommath etc)?
392
393[section:ints Integer Types]
394
395The following back-ends provide integer arithmetic:
396
397[table
398[[Backend Type][Header][Radix][Dependencies][Pros][Cons]]
399[[`cpp_int`][boost/multiprecision/cpp_int.hpp][2][None]
400 [Very versatile, Boost licensed, all C++ integer type which support both [@http://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic arbitrary precision] and fixed precision integer types.][Slower than [gmp], though typically not as slow as [tommath]]]
401[[`gmp_int`][boost/multiprecision/gmp.hpp][2][[gmp]][Very fast and efficient back-end.][Dependency on GNU licensed [gmp] library.]]
402[[`tom_int`][boost/multiprecision/tommath.hpp][2][[tommath]][Public domain back-end with no licence restrictions.][Slower than [gmp].]]
403]
404
405[section:cpp_int cpp_int]
406
407`#include <boost/multiprecision/cpp_int.hpp>`
408
409 namespace boost{ namespace multiprecision{
410
411 typedef unspecified-type limb_type;
412
413 enum cpp_integer_type { signed_magnitude, unsigned_magnitude };
414 enum cpp_int_check_type { checked, unchecked };
415
416 template <unsigned MinBits = 0,
417 unsigned MaxBits = 0,
418 cpp_integer_type SignType = signed_magnitude,
419 cpp_int_check_type Checked = unchecked,
420 class Allocator = std::allocator<limb_type> >
421 class cpp_int_backend;
422 //
423 // Expression templates default to et_off if there is no allocator:
424 //
425 template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked>
426 struct expression_template_default<cpp_int_backend<MinBits, MaxBits, SignType, Checked, void> >
427 { static const expression_template_option value = et_off; };
428
429 typedef number<cpp_int_backend<> > cpp_int; // arbitrary precision integer
430 typedef rational_adaptor<cpp_int_backend<> > cpp_rational_backend;
431 typedef number<cpp_rational_backend> cpp_rational; // arbitrary precision rational number
432
433 // Fixed precision unsigned types:
434 typedef number<cpp_int_backend<128, 128, unsigned_magnitude, unchecked, void> > uint128_t;
435 typedef number<cpp_int_backend<256, 256, unsigned_magnitude, unchecked, void> > uint256_t;
436 typedef number<cpp_int_backend<512, 512, unsigned_magnitude, unchecked, void> > uint512_t;
437 typedef number<cpp_int_backend<1024, 1024, unsigned_magnitude, unchecked, void> > uint1024_t;
438
439 // Fixed precision signed types:
440 typedef number<cpp_int_backend<128, 128, signed_magnitude, unchecked, void> > int128_t;
441 typedef number<cpp_int_backend<256, 256, signed_magnitude, unchecked, void> > int256_t;
442 typedef number<cpp_int_backend<512, 512, signed_magnitude, unchecked, void> > int512_t;
443 typedef number<cpp_int_backend<1024, 1024, signed_magnitude, unchecked, void> > int1024_t;
444
445 // Over again, but with checking enabled this time:
446 typedef number<cpp_int_backend<0, 0, signed_magnitude, checked> > checked_cpp_int;
447 typedef rational_adaptor<cpp_int_backend<0, 0, signed_magnitude, checked> > checked_cpp_rational_backend;
448 typedef number<cpp_rational_backend> checked_cpp_rational;
449
450 // Checked fixed precision unsigned types:
451 typedef number<cpp_int_backend<128, 128, unsigned_magnitude, checked, void> > checked_uint128_t;
452 typedef number<cpp_int_backend<256, 256, unsigned_magnitude, checked, void> > checked_uint256_t;
453 typedef number<cpp_int_backend<512, 512, unsigned_magnitude, checked, void> > checked_uint512_t;
454 typedef number<cpp_int_backend<1024, 1024, unsigned_magnitude, checked, void> > checked_uint1024_t;
455
456 // Fixed precision signed types:
457 typedef number<cpp_int_backend<128, 128, signed_magnitude, checked, void> > checked_int128_t;
458 typedef number<cpp_int_backend<256, 256, signed_magnitude, checked, void> > checked_int256_t;
459 typedef number<cpp_int_backend<512, 512, signed_magnitude, checked, void> > checked_int512_t;
460 typedef number<cpp_int_backend<1024, 1024, signed_magnitude, checked, void> > checked_int1024_t;
461
462 }} // namespaces
463
464The `cpp_int_backend` type is normally used via one of the convenience typedefs given above.
465
466This back-end is the "Swiss Army Knife" of integer types as it can represent both fixed and
467[@http://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic arbitrary precision]
468integer types, and both signed and unsigned types. There are five template arguments:
469
470[variablelist
471[[MinBits][Determines the number of Bits to store directly within the object before resorting to dynamic memory
472 allocation. When zero, this field is determined automatically based on how many bits can be stored
473 in union with the dynamic storage header: setting a larger value may improve performance as larger integer
474 values will be stored internally before memory allocation is required.]]
475[[MaxBits][Determines the maximum number of bits to be stored in the type: resulting in a fixed precision type.
476 When this value is the same as MinBits, then the Allocator parameter is ignored, as no dynamic
477 memory allocation will ever be performed: in this situation the Allocator parameter should be set to
478 type `void`. Note that this parameter should not be used simply to prevent large memory
479 allocations, not only is that role better performed by the allocator, but fixed precision
480 integers have a tendency to allocate all of MaxBits of storage more often than one would expect.]]
481[[SignType][Determines whether the resulting type is signed or not. Note that for
482[@http://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic arbitrary precision] types
483 this parameter must be `signed_magnitude`. For fixed precision
484 types then this type may be either `signed_magnitude` or `unsigned_magnitude`.]]
485[[Checked][This parameter has two values: `checked` or `unchecked`. See below.]]
486[[Allocator][The allocator to use for dynamic memory allocation, or type `void` if MaxBits == MinBits.]]
487]
488
489When the template parameter Checked is set to `checked` then the result is a ['checked-integer], checked
490and unchecked integers have the following properties:
491
492[table
493[[Condition][Checked-Integer][Unchecked-Integer]]
494[[Numeric overflow in fixed precision arithmetic][Throws a `std::overflow_error`.][Performs arithmetic modulo 2[super MaxBits]]]
495[[Constructing an integer from a value that can not be represented in the target type][Throws a `std::range_error`.]
496[Converts the value modulo 2[super MaxBits], signed to unsigned conversions extract the last MaxBits bits of the
4972's complement representation of the input value.]]
498[[Unsigned subtraction yielding a negative value.][Throws a `std::range_error`.][Yields the value that would
499result from treating the unsigned type as a 2's complement signed type.]]
500[[Attempting a bitwise operation on a negative value.][Throws a `std::range_error`][Yields the value, but not the bit pattern,
501that would result from performing the operation on a 2's complement integer type.]]
502]
503
504Things you should know when using this type:
505
506* Default constructed `cpp_int_backend`s have the value zero.
507* Division by zero results in a `std::overflow_error` being thrown.
508* Construction from a string that contains invalid non-numeric characters results in a `std::runtime_error` being thrown.
509* Since the precision of `cpp_int_backend` is necessarily limited when the allocator parameter is void,
510care should be taken to avoid numeric overflow when using this type
511unless you actually want modulo-arithmetic behavior.
512* The type uses a sign-magnitude representation internally, so type `int128_t` has 128-bits of precision plus an extra sign bit.
513In this respect the behaviour of these types differs from built-in 2's complement types. In might be tempting to use a
514127-bit type instead, and indeed this does work, but behaviour is still slightly different from a 2's complement built-in type
515as the min and max values are identical (apart from the sign), where as they differ by one for a true 2's complement type.
516That said it should be noted that there's no requirement for built-in types to be 2's complement either - it's simply that this
517is the most common format by far.
518* Attempting to print negative values as either an Octal or Hexadecimal string results in a `std::runtime_error` being thrown,
519this is a direct consequence of the sign-magnitude representation.
520* The fixed precision types `[checked_][u]intXXX_t` have expression template support turned off - it seems to make little
521difference to the performance of these types either way - so we may as well have the faster compile times by turning
522the feature off.
523* Unsigned types support subtraction - the result is "as if" a 2's complement operation had been performed as long as they are not
524 ['checked-integers] (see above).
525 In other words they behave pretty much as a built in integer type would in this situation. So for example if we were using
526 `uint128_t` then `uint128_t(1)-4` would result in the value `0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD`
527 of type `uint128_t`. However, had this operation been performed on `checked_uint128_t` then a `std::range_error` would have
528 been thrown.
529* Unary negation of unsigned types results in a compiler error (static assertion).
530* This backend supports rvalue-references and is move-aware, making instantiations of `number` on this backend move aware.
531* When used at fixed precision, the size of this type is always one machine word larger than you would expect for an N-bit integer:
532the extra word stores both the sign, and how many machine words in the integer are actually in use.
533The latter is an optimisation for larger fixed precision integers, so that a 1024-bit integer has almost the same performance
534characteristics as a 128-bit integer, rather than being 4 times slower for addition and 16 times slower for multiplication
535 (assuming the values involved would always fit in 128 bits).
536Typically this means you can use
537an integer type wide enough for the "worst case scenario" with only minor performance degradation even if most of the time
538the arithmetic could in fact be done with a narrower type.
539* When used at fixed precision and MaxBits is smaller than the number of bits in the largest native integer type, then
540internally `cpp_int_backend` switches to a "trivial" implementation where it is just a thin wrapper around a single
541integer. Note that it will still be slightly slower than a bare native integer, as it emulates a
542signed-magnitude representation rather than simply using the platforms native sign representation: this ensures
543there is no step change in behavior as a cpp_int grows in size.
544* Fixed precision `cpp_int`'s have some support for `constexpr` values and user-defined literals, see
545[link boost_multiprecision.tut.lits here] for the full description. For example `0xfffff_cppi1024`
546specifies a 1024-bit integer with the value 0xffff. This can be used to generate compile time constants that are
547too large to fit into any built in number type.
548* You can import/export the raw bits of a __cpp_int to and from external storage via the `import_bits` and `export_bits`
549functions. More information is in the [link boost_multiprecision.tut.import_export section on import/export].
550
551[h5 Example:]
552
553[cpp_int_eg]
554
555[endsect] [/section:cpp_int cpp_int]
556
557[section:gmp_int gmp_int]
558
559`#include <boost/multiprecision/gmp.hpp>`
560
561 namespace boost{ namespace multiprecision{
562
563 class gmp_int;
564
565 typedef number<gmp_int > mpz_int;
566
567 }} // namespaces
568
569The `gmp_int` back-end is used via the typedef `boost::multiprecision::mpz_int`. It acts as a thin wrapper around the [gmp] `mpz_t`
570to provide an integer type that is a drop-in replacement for the native C++ integer types, but with unlimited precision.
571
572As well as the usual conversions from arithmetic and string types, type `mpz_int` is copy constructible and assignable from:
573
574* The [gmp] native types: `mpf_t`, `mpz_t`, `mpq_t`.
575* Instances of `number<T>` that are wrappers around those types: `number<gmp_float<N> >`, `number<gmp_rational>`.
576
577It's also possible to access the underlying `mpz_t` via the `data()` member function of `gmp_int`.
578
579Things you should know when using this type:
580
581* No changes are made to the GMP library's global settings - so you can safely mix this type with
582existing code that uses [gmp].
583* Default constructed `gmp_int`s have the value zero (this is GMP's default behavior).
584* Formatted IO for this type does not support octal or hexadecimal notation for negative values,
585as a result performing formatted output on this type when the argument is negative and either of the flags
586`std::ios_base::oct` or `std::ios_base::hex` are set, will result in a `std::runtime_error` will be thrown.
587* Conversion from a string results in a `std::runtime_error` being thrown if the string can not be interpreted
588as a valid integer.
589* Division by zero results in a `std::overflow_error` being thrown.
590* Although this type is a wrapper around [gmp] it will work equally well with [mpir]. Indeed use of [mpir]
591is recommended on Win32.
592* This backend supports rvalue-references and is move-aware, making instantiations of `number` on this backend move aware.
593
594[h5 Example:]
595
596[mpz_eg]
597
598[endsect]
599
600[section:tom_int tom_int]
601
602`#include <boost/multiprecision/tommath.hpp>`
603
604 namespace boost{ namespace multiprecision{
605
606 class tommath_int;
607
608 typedef number<tommath_int > tom_int;
609
610 }} // namespaces
611
612The `tommath_int` back-end is used via the typedef `boost::multiprecision::tom_int`. It acts as a thin wrapper around the [tommath] `tom_int`
613to provide an integer type that is a drop-in replacement for the native C++ integer types, but with unlimited precision.
614
615Things you should know when using this type:
616
617* Default constructed objects have the value zero (this is [tommath]'s default behavior).
618* Although `tom_int` is mostly a drop in replacement for the builtin integer types, it should be noted that it is a
619rather strange beast as it's a signed type that is not a 2's complement type. As a result the bitwise operations
620`| & ^` will throw a `std::runtime_error` exception if either of the arguments is negative. Similarly the complement
621operator`~` is deliberately not implemented for this type.
622* Formatted IO for this type does not support octal or hexadecimal notation for negative values,
623as a result performing formatted output on this type when the argument is negative and either of the flags
624`std::ios_base::oct` or `std::ios_base::hex` are set, will result in a `std::runtime_error` will be thrown.
625* Conversion from a string results in a `std::runtime_error` being thrown if the string can not be interpreted
626as a valid integer.
627* Division by zero results in a `std::overflow_error` being thrown.
628
629[h5 Example:]
630
631[tommath_eg]
632
633[endsect] [/section:tom_int tom_int]
634
635[section:egs Examples]
636
637[import ../example/integer_examples.cpp]
638
639[section:factorials Factorials]
640[FAC1]
641[endsect] [/section:factorials Factorials]
642
643
644[section:bitops Bit Operations]
645[BITOPS]
646[endsect] [/section:bitops Bit Operations]
647
648
649[endsect]
650
651[endsect]
652
653[section:floats floating-point Numbers]
654
655The following back-ends provide floating-point arithmetic:
656
657[table
658[[Backend Type][Header][Radix][Dependencies][Pros][Cons]]
659[[`cpp_bin_float<N>`][boost/multiprecision/cpp_bin_float.hpp][2][None][Header only, all C++ implementation. Boost licence.][Approximately 2x slower than the [mpfr] or [gmp] libraries.]]
660[[`cpp_dec_float<N>`][boost/multiprecision/cpp_dec_float.hpp][10][None][Header only, all C++ implementation. Boost licence.][Approximately 2x slower than the [mpfr] or [gmp] libraries.]]
661[[`mpf_float<N>`][boost/multiprecision/gmp.hpp][2][[gmp]][Very fast and efficient back-end.][Dependency on GNU licensed [gmp] library.]]
662[[`mpfr_float<N>`][boost/multiprecision/mpfr.hpp][2][[gmp] and [mpfr]][Very fast and efficient back-end, with its own standard library implementation.][Dependency on GNU licensed [gmp] and [mpfr] libraries.]]
663[[`float128`][boost/multiprecision/float128.hpp][2][Either [quadmath] or the Intel C++ Math library.][Very fast and efficient back-end for 128-bit floating-point values (113-bit mantissa, equivalent to FORTRAN's QUAD real)][Depends on the compiler being either recent GCC or Intel C++ versions.]]
664]
665
666[section:cpp_bin_float cpp_bin_float]
667
668`#include <boost/multiprecision/cpp_bin_float.hpp>`
669
670 namespace boost{ namespace multiprecision{
671
672 enum digit_base_type
673 {
674 digit_base_2 = 2,
675 digit_base_10 = 10
676 };
677
678 template <unsigned Digits, digit_base_type base = digit_base_10, class Allocator = void, class Exponent = int, ExponentMin = 0, ExponentMax = 0>
679 class cpp_bin_float;
680
681 typedef number<cpp_bin_float<50> > cpp_bin_float_50;
682 typedef number<cpp_bin_float<100> > cpp_bin_float_100;
683
684 typedef number<backends::cpp_bin_float<24, backends::digit_base_2, void, boost::int16_t, -126, 127>, et_off> cpp_bin_float_single;
685 typedef number<backends::cpp_bin_float<53, backends::digit_base_2, void, boost::int16_t, -1022, 1023>, et_off> cpp_bin_float_double;
686 typedef number<backends::cpp_bin_float<64, backends::digit_base_2, void, boost::int16_t, -16382, 16383>, et_off> cpp_bin_float_double_extended;
687 typedef number<backends::cpp_bin_float<113, backends::digit_base_2, void, boost::int16_t, -16382, 16383>, et_off> cpp_bin_float_quad;
688
689 }} // namespaces
690
691The `cpp_bin_float` back-end is used in conjunction with `number`: It acts as an entirely C++ (header only and dependency free)
692floating-point number type that is a drop-in replacement for the native C++ floating-point types, but with
693much greater precision.
694
695Type `cpp_bin_float` can be used at fixed precision by specifying a non-zero `Digits` template parameter.
696The typedefs `cpp_bin_float_50` and `cpp_bin_float_100` provide arithmetic types at 50 and 100 decimal digits precision
697respectively.
698
699Optionally, you can specify whether the precision is specified in decimal digits or binary bits - for example
700to declare a `cpp_bin_float` with exactly the same precision as `double` one would use
701`number<cpp_bin_float<53, digit_base_2> >`. The typedefs `cpp_bin_float_single`, `cpp_bin_float_double`,
702`cpp_bin_float_quad` and `cpp_bin_float_double_extended` provide
703software analogues of the IEEE single, double and quad float data types, plus the Intel-extended-double type respectively.
704Note that while these types are functionally equivalent to the native IEEE types, but they do not have the same size
705or bit-layout as true IEEE compatible types.
706
707Normally `cpp_bin_float` allocates no memory: all of the space required for its digits are allocated
708directly within the class. As a result care should be taken not to use the class with too high a digit count
709as stack space requirements can grow out of control. If that represents a problem then providing an allocator
710as a template parameter causes `cpp_bin_float` to dynamically allocate the memory it needs: this
711significantly reduces the size of `cpp_bin_float` and increases the viable upper limit on the number of digits
712at the expense of performance. However, please bear in mind that arithmetic operations rapidly become ['very] expensive
713as the digit count grows: the current implementation really isn't optimized or designed for large digit counts.
714Note that since the actual type of the objects allocated
715is completely opaque, the suggestion would be to use an allocator with `void` `value_type`, for example:
716`number<cpp_bin_float<1000, digit_base_10, std::allocator<void> > >`.
717
718The final template parameters determine the type and range of the exponent: parameter `Exponent` can be
719any signed integer type, but note that `MinExponent` and `MaxExponent` can not go right up to the limits
720of the `Exponent` type as there has to be a little extra headroom for internal calculations. You will
721get a compile time error if this is the case. In addition if MinExponent or MaxExponent are zero, then
722the library will choose suitable values that are as large as possible given the constraints of the type
723and need for extra headroom for internal calculations.
724
725There is full standard library and `numeric_limits` support available for this type.
726
727Things you should know when using this type:
728
729* Default constructed `cpp_bin_float`s have a value of zero.
730* The radix of this type is 2, even when the precision is specified as decimal digits.
731* The type supports both infinities and NaN's. An infinity is generated whenever the result would overflow,
732and a NaN is generated for any mathematically undefined operation.
733* There is a `std::numeric_limits` specialisation for this type.
734* Any `number` instantiated on this type, is convertible to any other `number` instantiated on this type -
735for example you can convert from `number<cpp_bin_float<50> >` to `number<cpp_bin_float<SomeOtherValue> >`.
736Narrowing conversions round to nearest and are `explicit`.
737* Conversion from a string results in a `std::runtime_error` being thrown if the string can not be interpreted
738as a valid floating-point number.
739* All arithmetic operations are correctly rounded to nearest. String conversions and the `sqrt` function
740are also correctly rounded, but transcendental functions (sin, cos, pow, exp etc) are not.
741
742[h5 cpp_bin_float example:]
743
744[cpp_bin_float_eg]
745
746[endsect]
747
748[section:cpp_dec_float cpp_dec_float]
749
750`#include <boost/multiprecision/cpp_dec_float.hpp>`
751
752 namespace boost{ namespace multiprecision{
753
754 template <unsigned Digits10, class ExponentType = boost::int32_t, class Allocator = void>
755 class cpp_dec_float;
756
757 typedef number<cpp_dec_float<50> > cpp_dec_float_50;
758 typedef number<cpp_dec_float<100> > cpp_dec_float_100;
759
760 }} // namespaces
761
762The `cpp_dec_float` back-end is used in conjunction with `number`: It acts as an entirely C++ (header only and dependency free)
763floating-point number type that is a drop-in replacement for the native C++ floating-point types, but with
764much greater precision.
765
766Type `cpp_dec_float` can be used at fixed precision by specifying a non-zero `Digits10` template parameter.
767The typedefs `cpp_dec_float_50` and `cpp_dec_float_100` provide arithmetic types at 50 and 100 decimal digits precision
768respectively. Optionally, you can specify an integer type to use for the exponent, this defaults to a 32-bit integer type
769which is more than large enough for the vast majority of use cases, but larger types such as `long long` can also be specified
770if you need a truly huge exponent range. In any case the ExponentType must be a built in signed integer type at least 2 bytes
771and 16-bits wide.
772
773Normally `cpp_dec_float` allocates no memory: all of the space required for its digits are allocated
774directly within the class. As a result care should be taken not to use the class with too high a digit count
775as stack space requirements can grow out of control. If that represents a problem then providing an allocator
776as the final template parameter causes `cpp_dec_float` to dynamically allocate the memory it needs: this
777significantly reduces the size of `cpp_dec_float` and increases the viable upper limit on the number of digits
778at the expense of performance. However, please bear in mind that arithmetic operations rapidly become ['very] expensive
779as the digit count grows: the current implementation really isn't optimized or designed for large digit counts.
780
781There is full standard library and `numeric_limits` support available for this type.
782
783Things you should know when using this type:
784
785* Default constructed `cpp_dec_float`s have a value of zero.
786* The radix of this type is 10. As a result it can behave subtly differently from base-2 types.
787* The type has a number of internal guard digits over and above those specified in the template argument.
788Normally these should not be visible to the user.
789* The type supports both infinities and NaN's. An infinity is generated whenever the result would overflow,
790and a NaN is generated for any mathematically undefined operation.
791* There is a `std::numeric_limits` specialisation for this type.
792* Any `number` instantiated on this type, is convertible to any other `number` instantiated on this type -
793for example you can convert from `number<cpp_dec_float<50> >` to `number<cpp_dec_float<SomeOtherValue> >`.
794Narrowing conversions are truncating and `explicit`.
795* Conversion from a string results in a `std::runtime_error` being thrown if the string can not be interpreted
796as a valid floating-point number.
797* The actual precision of a `cpp_dec_float` is always slightly higher than the number of digits specified in
798the template parameter, actually how much higher is an implementation detail but is always at least 8 decimal
799digits.
800* Operations involving `cpp_dec_float` are always truncating. However, note that since their are guard digits
801in effect, in practice this has no real impact on accuracy for most use cases.
802
803[h5 cpp_dec_float example:]
804
805[cpp_dec_float_eg]
806
807[endsect]
808
809[section:gmp_float gmp_float]
810
811`#include <boost/multiprecision/gmp.hpp>`
812
813 namespace boost{ namespace multiprecision{
814
815 template <unsigned Digits10>
816 class gmp_float;
817
818 typedef number<gmp_float<50> > mpf_float_50;
819 typedef number<gmp_float<100> > mpf_float_100;
820 typedef number<gmp_float<500> > mpf_float_500;
821 typedef number<gmp_float<1000> > mpf_float_1000;
822 typedef number<gmp_float<0> > mpf_float;
823
824 }} // namespaces
825
826The `gmp_float` back-end is used in conjunction with `number` : it acts as a thin wrapper around the [gmp] `mpf_t`
827to provide an real-number type that is a drop-in replacement for the native C++ floating-point types, but with
828much greater precision.
829
830Type `gmp_float` can be used at fixed precision by specifying a non-zero `Digits10` template parameter, or
831at variable precision by setting the template argument to zero. The typedefs mpf_float_50, mpf_float_100,
832mpf_float_500, mpf_float_1000 provide arithmetic types at 50, 100, 500 and 1000 decimal digits precision
833respectively. The typedef mpf_float provides a variable precision type whose precision can be controlled via the
834`number`s member functions.
835
836[note This type only provides standard library and `numeric_limits` support when the precision is fixed at compile time.]
837
838As well as the usual conversions from arithmetic and string types, instances of `number<mpf_float<N> >` are
839copy constructible and assignable from:
840
841* The [gmp] native types `mpf_t`, `mpz_t`, `mpq_t`.
842* The `number` wrappers around those types: `number<mpf_float<M> >`, `number<gmp_int>`, `number<gmp_rational>`.
843
844It's also possible to access the underlying `mpf_t` via the `data()` member function of `gmp_float`.
845
846Things you should know when using this type:
847
848* Default constructed `gmp_float`s have the value zero (this is the [gmp] library's default behavior).
849* No changes are made to the [gmp] library's global settings, so this type can be safely mixed with
850existing [gmp] code.
851* This backend supports rvalue-references and is move-aware, making instantiations of `number` on this backend move aware.
852* It is not possible to round-trip objects of this type to and from a string and get back
853exactly the same value. This appears to be a limitation of [gmp].
854* Since the underlying [gmp] types have no notion of infinities or NaN's, care should be taken
855to avoid numeric overflow or division by zero. That latter will result in a std::overflow_error being thrown,
856while generating excessively large exponents may result in instability of the underlying [gmp]
857library (in testing, converting a number with an excessively large or small exponent
858to a string caused [gmp] to segfault).
859* This type can equally be used with [mpir] as the underlying implementation - indeed that is
860the recommended option on Win32.
861* Conversion from a string results in a `std::runtime_error` being thrown if the string can not be interpreted
862as a valid floating-point number.
863* Division by zero results in a `std::overflow_error` being thrown.
864
865[h5 [gmp] example:]
866
867[mpf_eg]
868
869[endsect]
870
871[section:mpfr_float mpfr_float]
872
873`#include <boost/multiprecision/mpfr.hpp>`
874
875 namespace boost{ namespace multiprecision{
876
877 enum mpfr_allocation_type
878 {
879 allocate_stack,
880 allocate_dynamic
881 };
882
883 template <unsigned Digits10, mpfr_allocation_type AllocateType = allocate_dynamic>
884 class mpfr_float_backend;
885
886 typedef number<mpfr_float_backend<50> > mpfr_float_50;
887 typedef number<mpfr_float_backend<100> > mpfr_float_100;
888 typedef number<mpfr_float_backend<500> > mpfr_float_500;
889 typedef number<mpfr_float_backend<1000> > mpfr_float_1000;
890 typedef number<mpfr_float_backend<0> > mpfr_float;
891
892 typedef number<mpfr_float_backend<50, allocate_stack> > static_mpfr_float_50;
893 typedef number<mpfr_float_backend<100, allocate_stack> > static_mpfr_float_100;
894
895 }} // namespaces
896
897The `mpfr_float_backend` type is used in conjunction with `number`: It acts as a thin wrapper around the [mpfr] `mpfr_t`
898to provide an real-number type that is a drop-in replacement for the native C++ floating-point types, but with
899much greater precision.
900
901Type `mpfr_float_backend` can be used at fixed precision by specifying a non-zero `Digits10` template parameter, or
902at variable precision by setting the template argument to zero. The typedefs mpfr_float_50, mpfr_float_100,
903mpfr_float_500, mpfr_float_1000 provide arithmetic types at 50, 100, 500 and 1000 decimal digits precision
904respectively. The typedef mpfr_float provides a variable precision type whose precision can be controlled via the
905`number`s member functions.
906
907In addition the second template parameter lets you choose between dynamic allocation (the default,
908and uses MPFR's normal allocation routines),
909or stack allocation (where all the memory required for the underlying data types is stored
910within `mpfr_float_backend`). The latter option can result in significantly faster code, at the
911expense of growing the size of `mpfr_float_backend`. It can only be used at fixed precision, and
912should only be used for lower digit counts. Note that we can not guarantee that using `allocate_stack`
913won't cause any calls to mpfr's allocation routines, as mpfr may call these inside it's own code.
914The following table gives an idea of the performance tradeoff's at 50 decimal digits
915precision[footnote Compiled with VC++10 and /Ox, with MPFR-3.0.0 and MPIR-2.3.0]:
916
917[table
918[[Type][Bessel function evaluation, relative times]]
919[[`number<mpfr_float_backend<50, allocate_static>, et_on>`][1.0 (5.5s)]]
920[[`number<mpfr_float_backend<50, allocate_static>, et_off>`][1.05 (5.8s)]]
921[[`number<mpfr_float_backend<50, allocate_dynamic>, et_on>`][1.05 (5.8s)]]
922[[`number<mpfr_float_backend<50, allocate_dynamic>, et_off>`][1.16 (6.4s)]]
923]
924
925[note This type only provides `numeric_limits` support when the precision is fixed at compile time.]
926
927As well as the usual conversions from arithmetic and string types, instances of `number<mpfr_float_backend<N> >` are
928copy constructible and assignable from:
929
930* The [gmp] native types `mpf_t`, `mpz_t`, `mpq_t`.
931* The [mpfr] native type `mpfr_t`.
932* The `number` wrappers around those types: `number<mpfr_float_backend<M> >`, `number<mpf_float<M> >`, `number<gmp_int>`, `number<gmp_rational>`.
933
934It's also possible to access the underlying `mpfr_t` via the data() member function of `mpfr_float_backend`.
935
936Things you should know when using this type:
937
938* A default constructed `mpfr_float_backend` is set to zero (['Note that this is [*not] the default [mpfr] behavior]).
939* All operations use round to nearest.
940* No changes are made to [gmp] or [mpfr] global settings, so this type can coexist with existing
941[mpfr] or [gmp] code.
942* The code can equally use [mpir] in place of [gmp] - indeed that is the preferred option on Win32.
943* This backend supports rvalue-references and is move-aware, making instantiations of `number` on this backend move aware.
944* Conversion from a string results in a `std::runtime_error` being thrown if the string can not be interpreted
945as a valid floating-point number.
946* Division by zero results in an infinity.
947
948[h5 [mpfr] example:]
949
950[mpfr_eg]
951
952[endsect]
953
954[section:float128 float128]
955
956`#include <boost/multiprecision/float128.hpp>`
957
958 namespace boost{ namespace multiprecision{
959
960 class float128_backend;
961
962 typedef number<float128_backend, et_off> float128;
963
964 }} // namespaces
965
966The `float128` number type is a very thin wrapper around GCC's `__float128` or Intel's `_Quad` data types
967and provides an real-number type that is a drop-in replacement for the native C++ floating-point types, but with
968a 113 bit mantissa, and compatible with FORTRAN's 128-bit QUAD real.
969
970All the usual standard library and `numeric_limits` support are available, performance should be equivalent
971to the underlying native types: for example the LINPACK benchmarks for GCC's `__float128` and
972`boost::multiprecision::float128` both achieved 5.6 MFLOPS[footnote On 64-bit Ubuntu 11.10, GCC-4.8.0, Intel Core 2 Duo T5800.].
973
974As well as the usual conversions from arithmetic and string types, instances of `float128` are
975copy constructible and assignable from GCC's `__float128` and Intel's `_Quad` data types.
976
977It's also possible to access the underlying `__float128` or `_Quad` type via the `data()` member
978function of `float128_backend`.
979
980Things you should know when using this type:
981
982* Default constructed `float128`s have the value zero.
983* This backend supports rvalue-references and is move-aware, making instantiations of `number` on this backend move aware.
984* It is not possible to round-trip objects of this type to and from a string and get back
985exactly the same value when compiled with Intel's C++ compiler and using `_Quad` as the underlying type: this is a current limitation of
986our code. Round tripping when using `__float128` as the underlying type is possible (both for GCC and Intel).
987* Conversion from a string results in a `std::runtime_error` being thrown if the string can not be interpreted
988as a valid floating-point number.
989* Division by zero results in an infinity being produced.
990* Type `float128` can be used as a literal type (constexpr support).
991* When using the Intel compiler, the underlying type defaults to `__float128` if it's available and `_Quad` if not. You can override
992the default by defining either `BOOST_MP_USE_FLOAT128` or `BOOST_MP_USE_QUAD`.
993* When the underlying type is Intel's `_Quad` type, the code must be compiled with the compiler option `-Qoption,cpp,--extended_float_type`.
994
995[h5 float128 example:]
996
997[float128_eg]
998
999[endsect]
1000
1001[section:fp_eg Examples]
1002
1003[import ../example/floating_point_examples.cpp]
1004
1005[section:aos Area of Circle]
1006
1007[AOS1]
1008[AOS2]
1009[AOS3]
1010
1011[endsect]
1012
1013[section:jel Defining a Special Function.]
1014
1015[JEL]
1016
1017[endsect]
1018
1019[section:nd Calculating a Derivative]
1020
1021[ND1]
1022[ND2]
1023[ND3]
1024
1025[endsect]
1026
1027[section:gi Calculating an Integral]
1028
1029[GI1]
1030[GI2]
1031
1032[endsect]
1033
1034[section:poly_eg Polynomial Evaluation]
1035
1036[POLY]
1037
1038[endsect] [/section:poly_eg Polynomial Evaluation]
1039
1040[endsect] [/section:fp_eg Examples]
1041
1042[endsect] [/section:floats floating-point Numbers]
1043
1044[section:interval Interval Number Types]
1045
1046There is one currently only one interval number type supported - [mpfi].
1047
1048[section:mpfi mpfi_float]
1049
1050`#include <boost/multiprecision/mpfi.hpp>`
1051
1052 namespace boost{ namespace multiprecision{
1053
1054 template <unsigned Digits10>
1055 class mpfi_float_backend;
1056
1057 typedef number<mpfi_float_backend<50> > mpfi_float_50;
1058 typedef number<mpfi_float_backend<100> > mpfifloat_100;
1059 typedef number<mpfi_float_backend<500> > mpfifloat_500;
1060 typedef number<mpfi_float_backend<1000> > mpfi_float_1000;
1061 typedef number<mpfi_float_backend<0> > mpfi_float;
1062
1063 }} // namespaces
1064
1065The `mpfi_float_backend` type is used in conjunction with `number`: It acts as a thin wrapper around the [mpfi] `mpfi_t`
1066to provide an real-number type that is a drop-in replacement for the native C++ floating-point types, but with
1067much greater precision and implementing interval arithmetic.
1068
1069Type `mpfi_float_backend` can be used at fixed precision by specifying a non-zero `Digits10` template parameter, or
1070at variable precision by setting the template argument to zero. The typedefs mpfi_float_50, mpfi_float_100,
1071mpfi_float_500, mpfi_float_1000 provide arithmetic types at 50, 100, 500 and 1000 decimal digits precision
1072respectively. The typedef mpfi_float provides a variable precision type whose precision can be controlled via the
1073`number`s member functions.
1074
1075[note This type only provides `numeric_limits` support when the precision is fixed at compile time.]
1076
1077As well as the usual conversions from arithmetic and string types, instances of `number<mpfi_float_backend<N> >` are
1078copy constructible and assignable from:
1079
1080* The [mpfi] native type `mpfi_t`.
1081* The `number` wrappers around [mpfi] or [mpfr]: `number<mpfi_float_backend<M> >` and `number<mpfr_float<M> >`.
1082* There is a two argument constructor taking two `number<mpfr_float<M> >` arguments specifying the interval.
1083
1084It's also possible to access the underlying `mpfi_t` via the data() member function of `mpfi_float_backend`.
1085
1086Things you should know when using this type:
1087
1088* A default constructed `mpfi_float_backend` is set to zero (['Note that this is [*not] the default [mpfi] behavior]).
1089* No changes are made to [gmp] or [mpfr] global settings, so this type can coexist with existing
1090[mpfr] or [gmp] code.
1091* The code can equally use [mpir] in place of [gmp] - indeed that is the preferred option on Win32.
1092* This backend supports rvalue-references and is move-aware, making instantiations of `number` on this backend move aware.
1093* Conversion from a string results in a `std::runtime_error` being thrown if the string can not be interpreted
1094as a valid floating-point number.
1095* Division by zero results in an infinity.
1096
1097There are some additional non member functions for working on intervals:
1098
1099 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1100 number<mpfr_float_backend<Digits10>, ExpressionTemplates> lower(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& val);
1101
1102Returns the lower end of the interval.
1103
1104 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1105 number<mpfr_float_backend<Digits10>, ExpressionTemplates> upper(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& val);
1106
1107Returns the upper end of the interval.
1108
1109 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1110 number<mpfr_float_backend<Digits10>, ExpressionTemplates> median(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& val);
1111
1112Returns the mid point of the interval.
1113
1114 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1115 number<mpfr_float_backend<Digits10>, ExpressionTemplates> width(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& val);
1116
1117Returns the absolute width of the interval.
1118
1119 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1120 number<mpfi_float_backend<Digits10>, ExpressionTemplates> intersect(
1121 const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a,
1122 const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b);
1123
1124Returns the interval which is the intersection of the ['a] and ['b]. Returns an
1125unspecified empty interval if there is no such intersection.
1126
1127 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1128 number<mpfi_float_backend<Digits10>, ExpressionTemplates> hull(
1129 const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a,
1130 const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b);
1131
1132Returns the interval which is the union of ['a] and ['b].
1133
1134 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1135 bool overlap(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a,
1136 const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b);
1137
1138Returns `true` only if the intervals ['a] and ['b] overlap.
1139
1140 template <unsigned Digits10, expression_template_option ExpressionTemplates1, expression_template_option ExpressionTemplates2>
1141 bool in(const number<mpfr_float_backend<Digits10>, ExpressionTemplates1>& a,
1142 const number<mpfi_float_backend<Digits10>, ExpressionTemplates2>& b);
1143
1144Returns `true` only if point ['a] is contained within the interval ['b].
1145
1146 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1147 bool zero_in(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a);
1148
1149Returns `true` only if the interval ['a] contains the value zero.
1150
1151 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1152 bool subset(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a,
1153 const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b);
1154
1155Returns `true` only if ['a] is a subset of ['b].
1156
1157 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1158 bool proper_subset(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a,
1159 const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b);
1160
1161Returns `true` only if ['a] is a proper subset of ['b].
1162
1163 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1164 bool empty(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a);
1165
1166Returns `true` only if ['a] is an empty interval, equivalent to `upper(a) < lower(a)`.
1167
1168 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1169 bool singleton(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a);
1170
1171Returns `true` if `lower(a) == upper(a)`.
1172
1173[h5 [mpfi] example:]
1174
1175[mpfi_eg]
1176
1177[endsect]
1178
1179[endsect]
1180
1181[section:rational Rational Number Types]
1182
1183The following back-ends provide rational number arithmetic:
1184
1185[table
1186[[Backend Type][Header][Radix][Dependencies][Pros][Cons]]
1187[[`cpp_rational`][boost/multiprecision/cpp_int.hpp][2][None][An all C++ Boost-licensed implementation.][Slower than [gmp].]]
1188[[`gmp_rational`][boost/multiprecision/gmp.hpp][2][[gmp]][Very fast and efficient back-end.][Dependency on GNU licensed [gmp] library.]]
1189[[`tommath_rational`][boost/multiprecision/tommath.hpp][2][[tommath]][All C/C++ implementation that's Boost Software Licence compatible.][Slower than [gmp].]]
1190[[`rational_adaptor`][boost/multiprecision/rational_adaptor.hpp][N/A][none][All C++ adaptor that allows any integer back-end type to be used as a rational type.][Requires an underlying integer back-end type.]]
1191[[`boost::rational`][boost/rational.hpp][N/A][None][A C++ rational number type that can used with any `number` integer type.][The expression templates used by `number` end up being "hidden" inside `boost::rational`: performance may well suffer as a result.]]
1192]
1193
1194[section:cpp_rational cpp_rational]
1195
1196`#include <boost/multiprecision/cpp_int.hpp>`
1197
1198 namespace boost{ namespace multiprecision{
1199
1200 typedef rational_adaptor<cpp_int_backend<> > cpp_rational_backend;
1201
1202 typedef number<cpp_rational_backend> cpp_rational;
1203
1204 }} // namespaces
1205
1206The `cpp_rational_backend` type is used via the typedef `boost::multiprecision::cpp_rational`. It provides
1207a rational number type that is a drop-in replacement for the native C++ number types, but with unlimited precision.
1208
1209As well as the usual conversions from arithmetic and string types, instances of `cpp_rational` are copy constructible
1210and assignable from type `cpp_int`.
1211
1212There is also a two argument constructor that accepts a numerator and denominator: both of type `cpp_int`.
1213
1214There are also non-member functions:
1215
1216 cpp_int numerator(const cpp_rational&);
1217 cpp_int denominator(const cpp_rational&);
1218
1219which return the numerator and denominator of the number.
1220
1221Things you should know when using this type:
1222
1223* Default constructed `cpp_rational`s have the value zero.
1224* Division by zero results in a `std::overflow_error` being thrown.
1225* Conversion from a string results in a `std::runtime_error` being thrown if the string can not be
1226interpreted as a valid rational number.
1227
1228[h5 Example:]
1229
1230[cpp_rational_eg]
1231
1232[endsect]
1233
1234[section:gmp_rational gmp_rational]
1235
1236`#include <boost/multiprecision/gmp.hpp>`
1237
1238 namespace boost{ namespace multiprecision{
1239
1240 class gmp_rational;
1241
1242 typedef number<gmp_rational > mpq_rational;
1243
1244 }} // namespaces
1245
1246The `gmp_rational` back-end is used via the typedef `boost::multiprecision::mpq_rational`. It acts as a thin wrapper around the [gmp] `mpq_t`
1247to provide a rational number type that is a drop-in replacement for the native C++ number types, but with unlimited precision.
1248
1249As well as the usual conversions from arithmetic and string types, instances of `number<gmp_rational>` are copy constructible
1250and assignable from:
1251
1252* The [gmp] native types: `mpz_t`, `mpq_t`.
1253* `number<gmp_int>`.
1254
1255There is also a two-argument constructor that accepts a numerator and denominator (both of type `number<gmp_int>`).
1256
1257There are also non-member functions:
1258
1259 mpz_int numerator(const mpq_rational&);
1260 mpz_int denominator(const mpq_rational&);
1261
1262which return the numerator and denominator of the number.
1263
1264It's also possible to access the underlying `mpq_t` via the `data()` member function of `mpq_rational`.
1265
1266Things you should know when using this type:
1267
1268* Default constructed `mpq_rational`s have the value zero (this is the [gmp] default behavior).
1269* Division by zero results in a `std::overflow_error` being thrown.
1270* Conversion from a string results in a `std::runtime_error` being thrown if the string can not be
1271interpreted as a valid rational number.
1272* No changes are made to the [gmp] library's global settings, so this type can coexist with existing
1273[gmp] code.
1274* The code can equally be used with [mpir] as the underlying library - indeed that is the preferred option on Win32.
1275
1276[h5 Example:]
1277
1278[mpq_eg]
1279
1280[endsect]
1281
1282[section:tommath_rational tommath_rational]
1283
1284`#include <boost/multiprecision/tommath.hpp>`
1285
1286 namespace boost{ namespace multiprecision{
1287
1288 typedef rational_adpater<tommath_int> tommath_rational;
1289 typedef number<tommath_rational > tom_rational;
1290
1291 }} // namespaces
1292
1293The `tommath_rational` back-end is used via the typedef `boost::multiprecision::tom_rational`. It acts as a thin wrapper around
1294`boost::rational<tom_int>`
1295to provide a rational number type that is a drop-in replacement for the native C++ number types, but with unlimited precision.
1296
1297The advantage of using this type rather than `boost::rational<tom_int>` directly, is that it is expression-template enabled,
1298greatly reducing the number of temporaries created in complex expressions.
1299
1300There are also non-member functions:
1301
1302 tom_int numerator(const tom_rational&);
1303 tom_int denominator(const tom_rational&);
1304
1305which return the numerator and denominator of the number.
1306
1307Things you should know when using this type:
1308
1309* Default constructed `tom_rational`s have the value zero (this the inherited Boost.Rational behavior).
1310* Division by zero results in a `std::overflow_error` being thrown.
1311* Conversion from a string results in a `std::runtime_error` being thrown if the string can not be
1312interpreted as a valid rational number.
1313* No changes are made to [tommath]'s global state, so this type can safely coexist with other [tommath] code.
1314* Performance of this type has been found to be pretty poor - this need further investigation - but it appears that Boost.Rational
1315needs some improvement in this area.
1316
1317[h5 Example:]
1318
1319[mp_rat_eg]
1320
1321[endsect]
1322
1323[section:br Use With Boost.Rational]
1324
1325All of the integer types in this library can be used as template arguments to `boost::rational<IntType>`.
1326
1327Note that using the library in this way largely negates the effect of the expression templates in `number`.
1328
1329[endsect]
1330
1331[section:rational_adaptor rational_adaptor]
1332
1333 namespace boost{ namespace multiprecision{
1334
1335 template <class IntBackend>
1336 class rational_adpater;
1337
1338 }}
1339
1340The class template `rational_adaptor` is a back-end for `number` which converts any existing integer back-end
1341into a rational-number back-end.
1342
1343So for example, given an integer back-end type `MyIntegerBackend`, the use would be something like:
1344
1345 typedef number<MyIntegerBackend> MyInt;
1346 typedef number<rational_adaptor<MyIntegerBackend> > MyRational;
1347
1348 MyRational r = 2;
1349 r /= 3;
1350 MyInt i = numerator(r);
1351 assert(i == 2);
1352
1353[endsect]
1354
1355[endsect]
1356
1357[section:misc Miscellaneous Number Types.]
1358
1359Backend types listed in this section are predominantly designed to aid debugging.
1360
1361[section:logged_adaptor logged_adaptor]
1362
1363`#include <boost/multiprecision/logged_adaptor.hpp>`
1364
1365 namespace boost{ namespace multiprecision{
1366
1367 template <class Backend>
1368 void log_postfix_event(const Backend& result, const char* event_description);
1369 template <class Backend, class T>
1370 void log_postfix_event(const Backend& result1, const T& result2, const char* event_description);
1371
1372 template <class Backend>
1373 void log_prefix_event(const Backend& arg1, const char* event_description);
1374 template <class Backend, class T>
1375 void log_prefix_event(const Backend& arg1, const T& arg2, const char* event_description);
1376 template <class Backend, class T, class U>
1377 void log_prefix_event(const Backend& arg1, const T& arg2, const U& arg3, const char* event_description);
1378 template <class Backend, class T, class U, class V>
1379 void log_prefix_event(const Backend& arg1, const T& arg2, const U& arg3, const V& arg4, const char* event_description);
1380
1381 template <Backend>
1382 class logged_adaptor;
1383
1384 }} // namespaces
1385
1386The `logged_adaptor` type is used in conjunction with `number` and some other backend type: it acts as a thin wrapper around
1387some other backend to class `number` and logs all the events that take place on that object. Before any number operation takes
1388place, it calls `log_prefix_event` with the arguments to the operation (up to 4), plus a string describing the operation.
1389Then after the operation it calls `log_postfix_event` with the result of the operation, plus a string describing the operation.
1390Optionally, `log_postfix_event` takes a second result argument: this occurs when the result of the operation is not a `number`,
1391for example when `fpclassify` is called, `log_postfix_event` will be called with `result1` being the argument to the function, and
1392`result2` being the integer result of `fpclassify`.
1393
1394The default versions of `log_prefix_event` and `log_postfix_event` do nothing, it is therefore up to the user to overload these
1395for the particular backend being observed.
1396
1397This type provides `numeric_limits` support whenever the template argument Backend does so.
1398
1399This type is particularly useful when combined with an interval number type - in this case we can use `log_postfix_event`
1400to monitor the error accumulated after each operation. We could either set some kind of trap whenever the accumulated error
1401exceeds some threshold, or simply print out diagnostic information. Using this technique we can quickly locate the cause of
1402numerical instability in a particular routine. The following example demonstrates this technique in a trivial algorithm
1403that deliberately introduces cancellation error:
1404
1405[logged_adaptor]
1406
1407When we examine program output we can clearly see that the diameter of the interval increases after each subtraction:
1408
1409[logged_adaptor_output]
1410
1411[endsect]
1412
1413[section:debug_adaptor debug_adaptor]
1414
1415`#include <boost/multiprecision/debug_adaptor.hpp>`
1416
1417 namespace boost{ namespace multiprecision{
1418
1419 template <Backend>
1420 class debug_adaptor;
1421
1422 }} // namespaces
1423
1424The `debug_adaptor` type is used in conjunction with `number` and some other backend type: it acts as a thin wrapper around
1425some other backend to class `number` and intercepts all operations on that object storing the result as a string within itself.
1426
1427This type provides `numeric_limits` support whenever the template argument Backend does so.
1428
1429This type is particularly useful when your debugger provides a good view of `std::string`: when this is the case
1430multiprecision values can easily be inspected in the debugger by looking at the `debug_value` member of `debug_adaptor`.
1431The down side of this approach is that runtimes are much slower when using this type. Set against that it can make
1432debugging very much easier, certainly much easier than sprinkling code with `printf` statements.
1433
1434When used in conjunction with the Visual C++ debugger visualisers, the value of a multiprecision type that uses this
1435backend is displayed in the debugger just a builtin value would be, here we're inspecting a value of type
1436`number<debug_adaptor<cpp_dec_float<50> > >`:
1437
1438[$../debugger1.png]
1439
1440Otherwise you will need to expand out the view and look at the "debug_value" member:
1441
1442[$../debugger2.png]
1443
1444It works for all the backend types equally too, here it is inspecting a `number<debug_adaptor<gmp_rational> >`:
1445
1446[$../debugger3.png]
1447
1448
1449[endsect]
1450
1451[section:visualizers Visual C++ Debugger Visualizers]
1452
1453Let's face it debugger multiprecision numbers is hard - simply because we can't easily inspect the value of the numbers.
1454Visual C++ provides a partial solution in the shape of "visualizers" which provide improved views of complex data structures,
1455these visualizers need to be added to the `[Visualizer]` section of `autoexp.dat` located in the `Common7/Packages/Debugger`
1456directory of your Visual Studio installation. The actual visualizer code is in the sandbox
1457[@https://svn.boost.org/svn/boost/sandbox/boost_docs/subprojects/DebuggerVisualizers/multiprecision.vis.txt here] - just cut and paste the code
1458into your `autoexp.dat` file.
1459
1460[note These visualizers have only been tested with VC10, also given the ability of buggy visualizers to crash your Visual C++
1461debugger, make sure you back up `autoexp.dat` file before using these!!]
1462
1463The first visualizer provides improved views of `debug_adaptor`:
1464
1465[$../debugger1.png]
1466
1467The next visualizer provides improved views of cpp_int: small numbers are displayed as actual values, while larger numbers are
1468displayed as an array of hexadecimal parts, with the most significant part first.
1469
1470Here's what it looks like for small values:
1471
1472[$../debugger4.png]
1473
1474And for larger values:
1475
1476[$../debugger5.png]
1477
1478There is also a `~raw` child member that
1479lets you see the actual members of the class:
1480
1481[$../debugger6.png]
1482
1483The visualizer for `cpp_dec_float` shows the first few digits of the value in the preview field, and the full array of digits
1484when you expand the view. As before the `~raw` child gives you access to the actual data members:
1485
1486[$../debugger7.png]
1487
1488[endsect]
1489
1490[endsect]
1491
1492[section:conversions Constructing and Interconverting Between Number Types]
1493
1494All of the number types that are based on `number` have certain conversion rules in common.
1495In particular:
1496
1497* Any number type can be constructed (or assigned) from any builtin arithmetic type, as long
1498 as the conversion isn't lossy (for example float to int conversion):
1499
1500 cpp_dec_float_50 df(0.5); // OK construction from double
1501 cpp_int i(450); // OK constructs from signed int
1502 cpp_int j = 3.14; // Error, lossy conversion.
1503
1504* A number can be explicitly constructed from an arithmetic type, even when the conversion is lossy:
1505
1506 cpp_int i(3.14); // OK explicit conversion
1507 i = static_cast<cpp_int>(3.14) // OK explicit conversion
1508 i.assign(3.14); // OK, explicit assign and avoid a temporary from the cast above
1509 i = 3.14; // Error, no implicit assignment operator for lossy conversion.
1510 cpp_int j = 3.14; // Error, no implicit constructor for lossy conversion.
1511
1512* A `number` can be converted to any built in type, via the `convert_to` member function:
1513
1514 mpz_int z(2);
1515 int i = z.template convert_to<int>(); // sets i to 2
1516
1517* Conversions to rational numbers from floating-point ones are always allowed, and are exact and implicit
1518as long as the rational number uses an unbounded integer type. Please be aware that constructing a rational
1519number from an extended precision floating-point type with a large exponent range can effectively run the system
1520out of memory, as in the extreme case ['2[super max_exponent] / CHAR_BITS] bytes of storage may be required. This
1521does not represent a problem for built in floating-point types however, as the exponent range for these is rather
1522limited.
1523
1524* Conversions to floating-point numbers from rational ones are rounded to nearest (less than 0.5ulp error)
1525as long as the floating-point number is binary, and the integer type used by the rational number is unbounded.
1526
1527Additional conversions may be supported by particular backends.
1528
1529* A `number` can be converted to any built in type, via an explicit conversion operator:
1530this functionality is only available on compilers supporting C++11's explicit conversion syntax.
1531
1532 mpz_int z(2);
1533 int i = z; // Error, implicit conversion not allowed.
1534 int j = static_cast<int>(z); // OK explicit conversion.
1535
1536* Any number type can be ['explicitly] constructed (or assigned) from a `const char*` or a `std::string`:
1537
1538 // pi to 50 places from a string:
1539 cpp_dec_float_50 df("3.14159265358979323846264338327950288419716939937510");
1540 // Integer type will automatically detect "0x" and "0" prefixes and parse the string accordingly:
1541 cpp_int i("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000");
1542 // Invalid input always results in a std::runtime_error being thrown:
1543 i = static_cast<cpp_int>("3.14");
1544 // implicit conversions from strings are not allowed:
1545 i = "23"; // Error, no assignment operator for implicit conversion from string
1546 // assign member function, avoids having to create a temporary via a static_cast:
1547 i.assign("23"); // OK
1548
1549* Any number type will interoperate with the builtin types in arithmetic expressions as long as the conversions
1550are not lossy:
1551
1552 // pi to 50 places from a string:
1553 cpp_dec_float_50 df = "3.14159265358979323846264338327950288419716939937510";
1554 // Multiply by 2 - using an integer literal here is usually more efficient
1555 // than constructing a temporary:
1556 df *= 2;
1557
1558 // You can't mix integer types with floats though:
1559 cpp_int i = 2;
1560 i *= 3.14; // Error, no *= operator will be found.
1561
1562* Any number type can be streamed to and from the C++ iostreams:
1563
1564 cpp_dec_float_50 df = "3.14159265358979323846264338327950288419716939937510";
1565 // Now print at full precision:
1566 std::cout << std::setprecision(std::numeric_limits<cpp_dec_float_50>::max_digits10)
1567 << df << std::endl
1568 cpp_int i = 1;
1569 i <<= 256;
1570 // Now print in hex format with prefix:
1571 std::cout << std::hex << std::showbase << i << std::endl;
1572
1573* Interconversions between number types of the same family are allowed and are implicit conversions if no
1574loss of precision is involved, and explicit if it is:
1575
1576 int128_t i128 = 0;
1577 int266_t i256 = i128; // OK implicit widening conversion
1578 i128_t = i256; // Error, no assignment operator found, narrowing conversion is explicit.
1579 i128_t = static_cast<int128_t>(i256); // OK, explicit narrowing conversion.
1580
1581 mpz_int z = 0;
1582 mpf_float f = z; // OK, GMP handles this conversion natively, and it's not lossy and therefore implicit.
1583
1584 mpf_float_50 f50 = 2;
1585 f = f50; // OK, conversion from fixed to variable precision, f will have 50 digits precision.
1586 f50 = f; // Error, conversion from variable to fixed precision is potentially lossy, explicit cast required.
1587
1588* Some interconversions between number types are completely generic, and are always available, albeit the conversions are always ['explicit]:
1589
1590 cpp_int cppi(2);
1591 // We can always convert between numbers of the same category -
1592 // int to int, rational to rational, or float to float, so this is OK
1593 // as long as we use an explicit conversion:
1594 mpz_int z(cppi);
1595 // We can always promote from int to rational, int to float, or rational to float:
1596 cpp_rational cppr(cppi); // OK, int to rational
1597 cpp_dec_float_50 df(cppi); // OK, int to float
1598 df = static_cast<cpp_dec_float_50>(cppr); // OK, explicit rational to float conversion
1599 // However narrowing and/or implicit conversions always fail:
1600 cppi = df; // Compiler error, conversion not allowed
1601
1602* Other interconversions may be allowed as special cases, whenever the backend allows it:
1603
1604 mpf_t m; // Native GMP type.
1605 mpf_init_set_ui(m, 0); // set to a value;
1606 mpf_float i(m); // copies the value of the native type.
1607
1608More information on what additional types a backend supports conversions from are given in the tutorial for each backend.
1609The converting constructor will be implicit if the backend's converting constructor is also implicit, and explicit if the
1610backends converting constructor is also explicit.
1611
1612[endsect]
1613
1614[section:random Generating Random Numbers]
1615
1616Random numbers are generated in conjunction with Boost.Random.
1617
1618There is a single generator that supports generating random integers with large bit counts:
1619[@http://www.boost.org/doc/html/boost/random/independent_bits_engine.html `independent_bits_engine`].
1620This type can be used with either ['unbounded] integer types, or with ['bounded] (ie fixed precision) unsigned integers:
1621
1622[random_eg1]
1623
1624Program output is:
1625
1626[random_eg1_out]
1627
1628In addition, the generator adaptors [@http://www.boost.org/doc/html/boost/random/discard_block_engine.html `discard_block`],
1629[@http://www.boost.org/doc/html/boost/random/xor_combine_engine.html `xor_combine_engine`] and
1630[@http://www.boost.org/doc/html/boost/random/discrete_distribution.html `discrete_distribution`] can be used
1631with multiprecision types. Note that if you seed an `independent_bits_engine`, then you are actually seeding
1632the underlying generator, and should therefore provide a sequence of unsigned 32-bit values as the seed.
1633
1634Alternatively we can generate integers in a given range using
1635[@http://www.boost.org/doc/html/boost/random/uniform_int_distribution.html `uniform_int_distribution`], this will
1636invoke the underlying engine multiple times to build up the required number of bits in the result:
1637
1638[random_eg2]
1639
1640[random_eg2_out]
1641
1642It is also possible to use [@http://www.boost.org/doc/html/boost/random/uniform_int_distribution.html `uniform_int_distribution`]
1643with a multiprecision generator such as [@http://www.boost.org/doc/html/boost/random/independent_bits_engine.html `independent_bits_engine`].
1644Or to use [@http://www.boost.org/doc/html/boost/random/uniform_smallint.html `uniform_smallint`] or
1645[@http://www.boost.org/doc/html/boost/random/random_number_generator.html `random_number_generator`] with multiprecision types.
1646
1647floating-point values in \[0,1) are most easily generated using [@http://www.boost.org/doc/html/boost/random/generate_canonical.html `generate_canonical`],
1648note that `generate_canonical` will call the generator multiple times to produce the requested number of bits, for example we can use
1649it with a regular generator like so:
1650
1651[random_eg3]
1652
1653[random_eg3_out]
1654
1655Note however, the distributions do not invoke the generator multiple times to fill up the mantissa of a multiprecision floating-point type
1656with random bits. For these therefore, we should probably use a multiprecision generator (ie `independent_bits_engine`) in combination
1657with the distribution:
1658
1659[random_eg4]
1660
1661[random_eg4_out]
1662
1663And finally, it is possible to use the floating-point generators [@http://www.boost.org/doc/html/boost/random/lagged_fibonacci_01_engine.html `lagged_fibonacci_01_engine`]
1664and [@http://www.boost.org/doc/html/boost/random/subtract_with_idp144360752.html `subtract_with_carry_01_engine`] directly with multiprecision floating-point types.
1665It's worth noting however, that there is a distinct lack of literature on generating high bit-count random numbers, and therefore a lack of "known good" parameters to
1666use with these generators in this situation. For this reason, these should probably be used for research purposes only:
1667
1668[random_eg5]
1669
1670[endsect]
1671
1672[section:primetest Primality Testing]
1673
1674The library implements a Miller-Rabin test for primality:
1675
1676 #include <boost/multiprecision/miller_rabin.hpp>
1677
1678 template <class Backend, expression_template_option ExpressionTemplates, class Engine>
1679 bool miller_rabin_test(const number<Backend, ExpressionTemplates>& n, unsigned trials, Engine& gen);
1680
1681 template <class Backend, expression_template_option ExpressionTemplates, class Engine>
1682 bool miller_rabin_test(const number<Backend, ExpressionTemplates>& n, unsigned trials);
1683
1684These functions perform a Miller-Rabin test for primality, if the result is `false` then /n/ is definitely composite,
1685while if the result is true then n is probably prime. The probability to declare a composite n as probable prime is
1686at most 0.25[super trials]. Note that this does not allow a statement about the probability of n being actually
1687prime (for that, the prior probability would have to be known). The algorithm used performs some
1688trial divisions to exclude small prime factors, does one Fermat test to exclude many more composites, and then
1689uses the Miller-Rabin algorithm straight out of
1690Knuth Vol 2, which recommends 25 trials for a pretty strong likelihood that /n/ is prime.
1691
1692The third optional argument is for a Uniform Random Number Generator from Boost.Random. When not provided the `mt19937`
1693generator is used. Note that when producing random primes then you should probably use a different random number generator
1694to produce candidate prime numbers for testing, than is used internally by `miller_rabin_test` for determining
1695whether the value is prime. It also helps of course to seed the generators with some source of randomness.
1696
1697The following example searches for a prime `p` for which `(p-1)/2` is also probably prime:
1698
1699[safe_prime]
1700
1701[endsect]
1702
1703[section:lits Literal Types and `constexpr` Support]
1704
1705[note The features described in this section make heavy use of C++11 language features, currently
1706(as of May 2013) only
1707GCC-4.7 and later, and Clang 3.3 and later have the support required to make these features work.]
1708
1709There is limited support for `constexpr` and user-defined literals in the library, currently the
1710`number` front end supports `constexpr`
1711on default construction and all forwarding constructors, but not on any of the non-member operators. So if
1712some type `B` is a literal type, then `number<B>` is also a literal type, and you will be able to
1713compile-time-construct such a type from any literal that `B` is compile-time-constructible from.
1714However, you will not be able to perform compile-time arithmetic on such types.
1715
1716Currently the only backend type provided by the library that is also a literal type are instantiations
1717of `cpp_int_backend` where the Allocator parameter is type `void`, and the Checked parameter is
1718`boost::multiprecision::unchecked`.
1719
1720For example:
1721
1722 using namespace boost::multiprecision;
1723
1724 constexpr int128_t i = 0; // OK, fixed precision int128_t has no allocator.
1725 constexpr uint1024_t j = 0xFFFFFFFF00000000uLL; // OK, fixed precision uint1024_t has no allocator.
1726
1727 constexpr checked_uint128_t k = -1; // Error, checked type is not a literal type as we need runtime error checking.
1728 constexpr cpp_int l = 2; // Error, type is not a literal as it performs memory management.
1729
1730There is also limited support for user defined-literals - these are limited to unchecked, fixed precision `cpp_int`'s
1731which are specified in hexadecimal notation. The suffixes supported are:
1732
1733[table
1734[[Suffix][Meaning]]
1735[[_cppi][Specifies a value of type: `number<cpp_int_backend<N,N,signed_magnitude,unchecked,void> >`, where N is chosen
1736to contain just enough digits to hold the number specified.]]
1737[[_cppui][Specifies a value of type: `number<cpp_int_backend<N,N,unsigned_magnitude,unchecked,void> >`, where N is chosen
1738to contain just enough digits to hold the number specified.]]
1739[[_cppi['N]][Specifies a value of type `number<cpp_int_backend<N,N,signed_magnitude,unchecked,void> >`.]]
1740[[_cppui['N]][Specifies a value of type `number<cpp_int_backend<N,N,signed_magnitude,unchecked,void> >`.]]
1741]
1742
1743In each case, use of these suffixes with hexadecimal values produces a `constexpr` result.
1744
1745Examples:
1746
1747 //
1748 // Any use of user defined literals requires that we import the literal-operators
1749 // into current scope first:
1750 using namespace boost::multiprecision::literals;
1751 //
1752 // To keep things simple in the example, we'll make our types used visible to this scope as well:
1753 using namespace boost::multiprecision;
1754 //
1755 // The value zero as a number<cpp_int_backend<4,4,signed_magnitude,unchecked,void> >:
1756 constexpr auto a = 0x0_cppi;
1757 // The type of each constant has 4 bits per hexadecimal digit,
1758 // so this is of type uint256_t (ie number<cpp_int_backend<256,256,unsigned_magnitude,unchecked,void> >):
1759 constexpr auto b = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_cppui;
1760 //
1761 // Smaller values can be assigned to larger values:
1762 int256_t c = 0x1234_cppi; // OK
1763 //
1764 // However, this does not currently work in constexpr contexts:
1765 constexpr int256_t d = 0x1_cppi; // Compiler error
1766 //
1767 // Constants can be padded out with leading zeros to generate wider types:
1768 constexpr uint256_t e = 0x0000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFF_cppui; // OK
1769 //
1770 // However, specific width types are best produced with specific-width suffixes,
1771 // ones supported by default are `_cpp[u]i128`, `_cpp[u]i256`, `_cpp[u]i512`, `_cpp[u]i1024`.
1772 //
1773 constexpr int128_t f = 0x1234_cppi128; // OK, always produces an int128_t as the result.
1774 constexpr uint1024_t g = 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccc_cppui1024;
1775 //
1776 // If other specific width types are required, then there is a macro for generating the operators
1777 // for these. The macro can be used at namespace scope only:
1778 //
1779 BOOST_MP_DEFINE_SIZED_CPP_INT_LITERAL(2048);
1780 //
1781 // Now we can create 2048-bit literals as well:
1782 constexpr auto h = 0xff_cppi2048; // h is of type number<cpp_int_backend<2048,2048,signed_magnitude,unchecked,void> >
1783 //
1784 // Finally negative values are handled via the unary minus operator:
1785 //
1786 constexpr int1024_t i = -0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_cppui1024;
1787 //
1788 // Which means this also works:
1789 constexpr int1024_t j = -g; // OK: unary minus operator is constexpr.
1790
1791[endsect]
1792
1793[section:import_export Importing and Exporting Data to and from cpp_int and cpp_bin_float]
1794
1795Any integer number type that uses `cpp_int_backend` as it's implementation layer can import or export it's bits via two non-member functions:
1796
1797 template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator,
1798 expression_template_option ExpressionTemplates, class OutputIterator>
1799 OutputIterator export_bits(
1800 const number<const cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates>& val,
1801 OutputIterator out,
1802 unsigned chunk_size,
1803 bool msv_first = true);
1804
1805 template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator,
1806 expression_template_option ExpressionTemplates, class Iterator>
1807 number<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates>&
1808 import_bits(
1809 number<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates>& val,
1810 Iterator i,
1811 Iterator j,
1812 unsigned chunk_size = 0,
1813 bool msv_first = true);
1814
1815These functions are designed for data-interchange with other storage formats, and since __cpp_bin_float uses __cpp_int internally,
1816by extension they can be used for floating point numbers based on that backend as well (see example below). Parameters and use are as follows:
1817
1818 template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator,
1819 expression_template_option ExpressionTemplates, class OutputIterator>
1820 OutputIterator export_bits(
1821 const number<const cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates>& val,
1822 OutputIterator out,
1823 unsigned chunk_size,
1824 bool msv_first = true);
1825
1826Exports the absolute value of `val` to OutputIterator `out`. The function will write `chunk_size` bits at a time
1827to the OutputIterator, and if `msv_first` is true, will write the most-significant block first. Byte and bit order
1828within each `chunk_size` block is always in the machines native format. Further, each block is stored in a
1829`boost::uintmax_t` when it's assigned to `*out`.
1830
1831[note Unfortunately, the standard's OutputIterator concept provides no means of deducing the type to output since
1832`std::iterator_traits<OutputIteratorType>::value_type` is type `void`. This is why the bit count for each block
1833has to be specified manually. It may also result in compiler warnings about the value being narrowed.]
1834
1835[tip If you're exporting to non-native byte layout, then use
1836[@http://www.boost.org/doc/libs/release/libs/endian/doc/index.html
1837Boost.Endian] to create a custom OutputIterator that
1838reverses the byte order of each chunk prior to actually storing the result.]
1839
1840 template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator,
1841 expression_template_option ExpressionTemplates, class ForwardIterator>
1842 number<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates>&
1843 import_bits(
1844 number<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates>& val,
1845 ForwardIterator i,
1846 ForwardIterator j,
1847 unsigned chunk_size = 0,
1848 bool msv_first = true);
1849
1850Imports bits from the iterator range ['\[i,j)] and stores them in `val` to produce an unsigned result (if the result
1851is to be signed you will need to handle that separately). When `msv_first` is true, takes `*i` as the most significant
1852chunk. Assumes there are `chunk_size` bits in each value read from the iterator range, and that these are in machine native
1853bit/byte order. When `chunk_size` is zero, then assumes that each chunk contains
1854`std::numeric_limits<std::iterator_traits<ForwardIterator>::value_type>::digits`, note that this will give the wrong result
1855if dereferencing the iterators leads to a signed-integer type, [*and] the sign bit is significant (be particularly careful
1856if you expect type `char` to contain 8-bit values, as by default it will extract only 7-bits at a time if `char` is signed).
1857As with exporting, if the external data is to be in a non-native byte order (within each chunk), then you will need to create an iterator adaptor
1858that presents it in native order (see [@http://www.boost.org/doc/libs/release/libs/endian/doc/index.html Boost.Endian]).
1859
1860[note
1861Note that this function is optimized for the case where the data can be memcpy'ed from the source to the integer - in this case both
1862iterators much be pointers, and everything must be little-endian.]
1863
1864[h4 Examples]
1865
1866[IE1]
1867
1868[IE2]
1869
1870[endsect]
1871
1872[section:rounding Rounding Rules for Conversions]
1873
1874As a general rule, all conversions between unrelated types are performed using basic arithmetic operations, therefore
1875conversions are either exact, or follow the same rounding rules as arithmetic for the type in question.
1876
1877The following table summarises the situation for conversions from native types:
1878
1879[table
1880[[Backend][Rounding Rules]]
1881[[__cpp_int][Conversions from integer types are exact if the target has sufficient precision, otherwise they
1882 truncate to the first 2^MaxBits bits (modulo arithmetic). Conversions from floating-point types
1883 are truncating to the nearest integer.]]
1884[[__gmp_int][Conversions are performed by the GMP library except for conversion from `long double` which is truncating.]]
1885[[__tom_int][Conversions from floating-point types are truncating, all others are performed by libtommath and are exact.]]
1886[[__gmp_float][Conversions are performed by the GMP library except for conversion from `long double` which should be exact
1887 provided the target type has as much precision as a `long double`.]]
1888[[__mpfr_float_backend][All conversions are performed by the underlying MPFR library.]]
1889[[__cpp_dec_float][All conversions are performed using basic arithmetic operations and are truncating.]]
1890[[__gmp_rational][See __gmp_int]]
1891[[__cpp_rational][See __cpp_int]]
1892[[__tommath_rational][See __tom_int]]
1893]
1894
1895[endsect]
1896
1897[section:mixed Mixed Precision Arithmetic]
1898
1899Mixed precision arithmetic is fully supported by the library.
1900
1901There are two different forms:
1902
1903* Where the operands are of different precision.
1904* Where the operands are of the same precision, but yield a higher precision result.
1905
1906[h4 Mixing Operands of Differing Precision]
1907
1908If the arguments to a binary operator are of different precision, then the operation is allowed
1909as long as there is an unambiguous implicit conversion from one argument type to the other.
1910In all cases the arithmetic is performed "as if" the lower precision type is promoted to the
1911higher precision type before applying the operator. However, particular backends may optimise
1912this and avoid actually creating a temporary if they are able to do so.
1913
1914For example:
1915
1916 mpfr_float_50 a(2), b;
1917 mpfr_float_100 c(3), d;
1918 static_mpfr_float_50 e(5), f;
1919 mpz_int i(20);
1920
1921 d = a * c; // OK, result of operand is an mpfr_float_100.
1922 b = a * c; // Error, can't convert the result to an mpfr_float_50 as it will lose digits.
1923 f = a * e; // Error, operator is ambiguous, result could be of either type.
1924 f = e * i; // OK, unambiguous conversion from mpz_int to static_mpfr_float_50
1925
1926[h4 Operands of the Same Precision]
1927
1928Sometimes you want to apply an operator to two arguments of the same precision in
1929such a way as to obtain a result of higher precision. The most common situation
1930occurs with fixed precision integers, where you want to multiply two N-bit numbers
1931to obtain a 2N-bit result. This is supported in this library by the following
1932free functions:
1933
1934 template <class ResultType, class Source1 class Source2>
1935 ResultType& add(ResultType& result, const Source1& a, const Source2& b);
1936
1937 template <class ResultType, class Source1 class Source2>
1938 ResultType& subtract(ResultType& result, const Source1& a, const Source2& b);
1939
1940 template <class ResultType, class Source1 class Source2>
1941 ResultType& multiply(ResultType& result, const Source1& a, const Source2& b);
1942
1943These functions apply the named operator to the arguments ['a] and ['b] and store the
1944result in ['result], returning ['result]. In all cases they behave "as if"
1945arguments ['a] and ['b] were first promoted to type `ResultType` before applying the
1946operator, though particular backends may well avoid that step by way of an optimization.
1947
1948The type `ResultType` must be an instance of class `number`, and the types `Source1` and `Source2`
1949may be either instances of class `number` or native integer types. The latter is an optimization
1950that allows arithmetic to be performed on native integer types producing an extended precision result.
1951
1952For example:
1953
1954[mixed_eg]
1955
1956Produces the output:
1957
1958[mixed_output]
1959
1960[h4 Backends With Optimized Mixed Precision Arithmetic]
1961
1962The following backends have at least some direct support for mixed precision arithmetic,
1963and therefore avoid creating unnecessary temporaries when using the interfaces above.
1964Therefore when using these types it's more efficient to use mixed precision arithmetic,
1965than it is to explicitly cast the operands to the result type:
1966
1967__mpfr_float_backend, __mpf_float, __cpp_int.
1968
1969[endsect]
1970
1971[section:gen_int Generic Integer Operations]
1972
1973All of the [link boost_multiprecision.ref.number.integer_functions non-member integer operations] are overloaded for the
1974built in integer types in
1975`<boost/multiprecision/integer.hpp>`.
1976Where these operations require a temporary increase in precision (such as for powm), then
1977if no built in type is available, a __cpp_int of appropriate precision will be used.
1978
1979Some of these functions are trivial, others use compiler intrinsics (where available) to ensure optimal
1980evaluation.
1981
1982The overloaded functions are:
1983
1984 template <class Integer, class I2>
1985 Integer& multiply(Integer& result, const I2& a, const I2& b);
1986
1987Multiplies two `I2` values, to produce a wider `Integer` result.
1988
1989Returns `result = a * b` without overflow or loss of precision in the multiplication.
1990
1991 template <class Integer, class I2>
1992 Integer& add(Integer& result, const I2& a, const I2& b);
1993
1994Adds two `I2` values, to produce a wider `Integer` result.
1995
1996Returns `result = a + b` without overflow or loss of precision in the addition.
1997
1998 template <class Integer, class I2>
1999 Integer& subtract(Integer& result, const I2& a, const I2& b);
2000
2001Subtracts two `I2` values, to produce a wider `Integer` result.
2002
2003Returns `result = a - b` without overflow or loss of precision in the subtraction.
2004
2005 template <class Integer>
2006 Integer powm(const Integer& b, const Integer& p, const Integer& m);
2007
2008Returns b[super p] % m.
2009
2010 template <class Integer>
2011 void divide_qr(const Integer& x, const Integer& y, Integer& q, Integer& r);
2012
2013Sets `q = x / y` and `r = x % y`.
2014
2015 template <class Integer1, class Integer2>
2016 Integer2 integer_modulus(const Integer1& x, Integer2 val);
2017
2018Returns x % val;
2019
2020 template <class Integer>
2021 unsigned lsb(const Integer& x);
2022
2023Returns the (zero-based) index of the least significant bit of `x`.
2024
2025Throws a `std::domain_error` if `x <= 0`.
2026
2027 template <class Integer>
2028 unsigned msb(const Integer& x);
2029
2030Returns the (zero-based) index of the most significant bit of `x`.
2031
2032Throws a `std::domain_error` if `x <= 0`.
2033
2034 template <class Integer>
2035 bool bit_test(const Integer& val, unsigned index);
2036
2037Returns `true` if bit `index` is set in `val`.
2038
2039 template <class Integer>
2040 Integer& bit_set(Integer& val, unsigned index);
2041
2042Sets the `index` bit in `val`.
2043
2044 template <class Integer>
2045 Integer& bit_unset(Integer& val, unsigned index);
2046
2047Unsets the `index` bit in `val`.
2048
2049 template <class Integer>
2050 Integer& bit_flip(Integer& val, unsigned index);
2051
2052Flips the `index` bit in `val`.
2053
2054 template <class Integer>
2055 Integer sqrt(const Integer& x);
2056 template <class Integer>
2057 Integer sqrt(const Integer& x, Integer& r);
2058
2059Returns the integer square root `s` of x and sets `r` to the remainder ['x - s[super 2]].
2060
2061 template <class Engine>
2062 bool miller_rabin_test(const number-or-expression-template-type& n, unsigned trials, Engine& gen);
2063 bool miller_rabin_test(const number-or-expression-template-type& n, unsigned trials);
2064
2065The regular Miller-Rabin functions in `<boost/multiprecision/miller_rabin.hpp>` are defined in terms of the above
2066generic operations, and so function equally well for built in and multiprecision types.
2067
2068[endsect]
2069
2070[section:serial Boost.Serialization Support]
2071
2072Support for serialization comes in two forms:
2073
2074* Classes __number, __debug_adaptor, __logged_adaptor and __rational_adaptor have "pass through" serialization
2075support which requires the underlying backend to be serializable.
2076* Backends __cpp_int, __cpp_bin_float, __cpp_dec_float and __float128 have full support for Boost.Serialization.
2077
2078[endsect] [/section:serialization Boost Serialization]
2079
2080[section:limits Numeric Limits]
2081
2082Boost.Multiprecision tries hard to implement `std::numeric_limits` for all types
2083as far as possible and meaningful because experience with Boost.Math
2084has shown that this aids portability.
2085
2086The [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3690.pdf C++ standard library]
2087defines `std::numeric_limits` in section 18.3.2.
2088
2089This in turn refers to the C standard
2090[@http://www.open-std.org/jtc1/sc22/wg11/docs/n507.pdf SC22/WG11 N507 DRAFT INTERNATIONAL ISO/IEC STANDARD
2091 WD 10967-1]
2092Information technology Language independent arithmetic Part 1: Integer and floating-point arithmetic.
2093
2094That C Standard in turn refers to
2095
2096[@http://754r.ucbtest.org/standards/754.pdf IEEE754 IEEE Standard for Binary
2097Floating-Point Arithmetic]
2098
2099There is a useful summary at
2100[@http://www.cplusplus.com/reference/limits/numeric_limits/ C++ reference].
2101
2102The chosen backend often determines how completely `std::numeric_limits` is available.
2103
2104Compiler options, processor type, and definition of macros or assembler instructions to control denormal numbers will alter
2105the values in the tables given below.
2106
2107[warning GMP's `mpf_t` does not have a concept of overflow:
2108operations that lead to overflow eventually run of out of resources
2109and terminate with stack overflow (often after several seconds).]
2110
2111[section:constants std::numeric_limits<> constants]
2112
2113[h4 is_specialized]
2114
2115`true` for all arithmetic types (integer, floating and fixed-point)
2116for which `std::numeric_limits<T>::numeric_limits` is specialized.
2117
2118A typical test is
2119
2120 if (std::numeric_limits<T>::is_specialized == false)
2121 {
2122 std::cout << "type " << typeid(T).name() << " is not specialized for std::numeric_limits!" << std::endl;
2123 // ...
2124 }
2125
2126Typically `numeric_limits<T>::is_specialized` is `true` for all `T` where the compile-time constant
2127members of `numeric_limits` are indeed known at compile time, and don't vary at runtime. For example
2128floating-point types with runtime-variable precision such as `mpfr_float` have no `numeric_limits`
2129specialization as it would be impossible to define all the members at compile time. In contrast
2130the precision of a type such as `mpfr_float_50` is known at compile time, and so it ['does] have a
2131`numeric_limits` specialization.
2132
2133Note that not all the `std::numeric_limits` member constants and functions are meaningful for all user-defined types (UDT),
2134such as the decimal and binary multiprecision types provided here. More information on this is given in the sections below.
2135
2136[h4 infinity]
2137
2138For floating-point types, [infin] is defined wherever possible,
2139but clearly infinity is meaningless for __arbitrary_precision arithmetic backends,
2140and there is one floating-point type (GMP's `mpf_t`, see __mpf_float) which has no notion
2141of infinity or NaN at all.
2142
2143A typical test whether infinity is implemented is
2144
2145 if(std::numeric_limits<T>::has_infinity)
2146 {
2147 std::cout << std::numeric_limits<T>::infinity() << std::endl;
2148 }
2149
2150and using tests like this is strongly recommended to improve portability.
2151
2152If the backend is switched to a type that does not support infinity then,
2153without checks like this, there will be trouble.
2154
2155[h4 is_signed]
2156
2157`std::numeric_limits<T>::is_signed == true` if the type `T` is signed.
2158
2159For built-in binary types, the sign is held in a single bit,
2160but for other types (cpp_dec_float and cpp_bin_float)
2161it may be a separate storage element, usually `bool`.
2162
2163[h4 is_exact]
2164
2165`std::numeric_limits<T>::is_exact == true` if type T uses exact representations.
2166
2167This is defined as `true` for all integer types and `false` for floating-point types.
2168
2169[@http://stackoverflow.com/questions/14203654/stdnumeric-limitsis-exact-what-is-a-usable-definition A usable definition]
2170has been discussed.
2171
2172ISO/IEC 10967-1, Language independent arithmetic, noted by the C++ Standard defines
2173
2174 A floating-point type F shall be a finite subset of [real].
2175
2176The important practical distinction is that all integers (up to `max()`) can be stored exactly.
2177
2178[@http://en.wikipedia.org/wiki/Rational_number Rational]
2179types using two integer types are also exact.
2180
2181Floating-point types [*cannot store all real values]
2182(those in the set of [real]) [*exactly].
2183For example, 0.5 can be stored exactly in a binary floating-point, but 0.1 cannot.
2184What is stored is the nearest representable real value, that is, rounded to nearest.
2185
2186Fixed-point types (usually decimal) are also defined as exact, in that they only
2187store a [*fixed precision], so half cents or pennies (or less) cannot be stored.
2188The results of computations are rounded up or down,
2189just like the result of integer division stored as an integer result.
2190
2191There are number of proposals to
2192[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3407.html
2193add Decimal floating-point Support to C++].
2194
2195[@http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2849.pdf Decimal TR].
2196
2197And also
2198[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3352.html
2199C++ Binary Fixed-Point Arithmetic].
2200
2201[h4 is_bounded]
2202
2203`std::numeric_limits<T>::is_bounded == true` if the set of values represented by the type `T` is finite.
2204
2205This is `true` for all built-in integer, fixed and floating-point types,
2206and most multi-precision types.
2207
2208It is only `false` for a few __arbitrary_precision types like `cpp_int`.
2209
2210Rational and fixed-exponent representations are exact but not integer.
2211
2212[h4 is_modulo]
2213
2214`std::numeric_limits<T>::is_modulo` is defined as `true` if adding two positive values of type T
2215can yield a result less than either value.
2216
2217`is_modulo == true` means that the type does not overflow, but, for example,
2218'wraps around' to zero, when adding one to the `max()` value.
2219
2220For most built-in integer types, `std::numeric_limits<>::is_modulo` is `true`.
2221
2222`bool` is the only exception.
2223
2224The modulo behaviour is sometimes useful,
2225but also can be unexpected, and sometimes undesired, behaviour.
2226
2227Overflow of signed integers can be especially unexpected,
2228possibly causing change of sign.
2229
2230Boost.Multiprecision integer type `cpp_int` is not modulo
2231because as an __arbitrary_precision types,
2232it expands to hold any value that the machine resources permit.
2233
2234However fixed precision __cpp_int's may be modulo if they are unchecked
2235(i.e. they behave just like built in integers), but not if they are checked
2236(overflow causes an exception to be raised).
2237
2238Built-in and multi-precision floating-point types are normally not modulo.
2239
2240Where possible, overflow is to `std::numeric_limits<>::infinity()`,
2241provided `std::numeric_limits<>::has_infinity == true`.
2242
2243[h4 radix]
2244
2245Constant `std::numeric_limits<T>::radix` returns either 2 (for built-in and binary types)
2246or 10 (for decimal types).
2247
2248[h4 digits]
2249
2250The number of `radix` digits that be represented without change:
2251
2252* for integer types, the number of [*non-sign bits] in the significand.
2253* for floating types, the number of [*radix digits] in the significand.
2254
2255The values include any implicit bit, so for example, for the ubiquious
2256`double` using 64 bits
2257([@http://en.wikipedia.org/wiki/Double_precision_floating-point_format IEEE binary64 ]),
2258`digits` == 53, even though there are only 52 actual bits of the significand stored in the representation.
2259The value of `digits` reflects the fact that there is one implicit bit which is always set to 1.
2260
2261The Boost.Multiprecision binary types do not use an implicit bit, so the
2262`digits` member reflects exactly how many bits of precision were requested:
2263
2264 typedef number<cpp_bin_float<53, digit_base_2> > float64;
2265 typedef number<cpp_bin_float<113, digit_base_2> > float128;
2266 std::numeric_limits<float64>::digits == 53.
2267 std::numeric_limits<float128>::digits == 113.
2268
2269For the most common case of `radix == 2`,
2270`std::numeric_limits<T>::digits` is the number of bits in the representation,
2271not counting any sign bit.
2272
2273For a decimal integer type, when `radix == 10`, it is the number of decimal digits.
2274
2275[h4 digits10]
2276
2277Constant `std::numeric_limits<T>::digits10` returns the number of
2278decimal digits that can be represented without change or loss.
2279
2280For example, `numeric_limits<unsigned char>::digits10` is 2.
2281
2282This somewhat inscrutable definition means that an `unsigned char`
2283can hold decimal values `0..99`
2284without loss of precision or accuracy, usually from truncation.
2285
2286Had the definition been 3 then that would imply it could hold 0..999,
2287but as we all know, an 8-bit `unsigned char` can only hold 0..255,
2288and an attempt to store 256 or more will involve loss or change.
2289
2290For bounded integers, it is thus [*one less] than number of decimal digits
2291you need to display the biggest integer `std::numeric_limits<T>::max()`.
2292This value can be used to predict the layout width required for
2293
2294[digits10_1]
2295
2296For example, `unsigned short` is often stored in 16 bits,
2297so the maximum value is 0xFFFF or 65535.
2298
2299[digits10_2]
2300
2301
2302For bounded floating-point types,
2303if we create a `double` with a value with `digits10` (usually 15) decimal digits,
2304`1e15` or `1000000000000000` :
2305
2306[digits10_3]
2307
2308and we can increment this value to `1000000000000001`
2309as expected and show the difference too.
2310
2311But if we try to repeat this with more than `digits10` digits,
2312
2313[digits10_4]
2314
2315then we find that when we add one it has no effect,
2316and display show that there is loss of precision. See
2317[@http://en.wikipedia.org/wiki/Loss_of_significance Loss of significance or cancellation error].
2318
2319So `digits10` is the number of decimal digits [*guaranteed] to be correct.
2320
2321For example, 'round-tripping' for `double`:
2322
2323* If a decimal string with at most `digits10`( == 15) significant decimal digits
2324is converted to `double` and then converted back to the
2325same number of significant decimal digits,
2326then the final string will match the original 15 decimal digit string.
2327* If a `double` floating-point number is converted to a decimal string
2328with at least 17 decimal digits
2329and then converted back to `double`,
2330then the result will be binary identical to the original `double` value.
2331
2332For most purposes, you will much more likely want
2333`std::numeric_limits<>::max_digits10`,
2334the number of decimal digits that ensure that a change of one least significant bit (ULP)
2335produces a different decimal digits string.
2336
2337For the most common `double` floating-point type,`max_digits10` is `digits10+2`,
2338but you should use C++11 `max_digits10`
2339where possible (see [link boost_multiprecision.tut.limits.constants.max_digits10 below]).
2340
2341[h4:max_digits10 max_digits10]
2342
2343`std::numeric_limits<T>::max_digits10` was added for floating-point
2344because `digits10` decimal digits are insufficient to show
2345a least significant bit (ULP) change giving puzzling displays like
2346
2347 0.666666666666667 != 0.666666666666667
2348
2349from failure to 'round-trip', for example:
2350
2351[max_digits10_2]
2352
2353If you wish to ensure that a change of one least significant bit (ULP)
2354produces a different decimal digits string,
2355then `max_digits10` is the precision to use.
2356
2357For example:
2358
2359[max_digits10_3]
2360
2361will display [pi] to the maximum possible precision using a `double`.
2362
2363[max_digits10_4]
2364
2365For integer types, `max_digits10` is implementation-dependent,
2366but is usually `digits10 + 2`.
2367This is the output field-width required for the maximum value of the type T
2368`std::numeric_limits<T>::max()` ['including a sign and a space].
2369
2370So this will produce neat columns.
2371
2372 std::cout << std::setw(std::numeric_limits<int>::max_digits10) ...
2373
2374The extra two or three least-significant digits are 'noisy' and may be junk,
2375but if you want to 'round-trip' - printing a value out as a decimal digit string and reading it back in -
2376(most commonly during serialization and de-serialization)
2377you must use `os.precision(std::numeric_limits<T>::max_digits10)`.
2378
2379[note For Microsoft Visual Studio 2010,
2380`std::numeric_limits<float>::max_digits10` is wrongly defined as 8. It should be 9.
2381]
2382
2383[note For Microsoft Visual Studio before 2013, and default float format,
2384a small range of values approximately 0.0001 to 0.004, with exponent values of 3F2 to 3F6,
2385are wrongly input by one least significant bit,
2386probably every third value of significand.
2387
2388A workaround is using scientific or exponential format `<< std::scientific`.
2389]
2390
2391[note BOOST_NO_CXX11_NUMERIC_LIMITS is a suitable feature-test macro to determine if
2392`std::numeric_limits<float>::max_digits10` is implemented on any platform.
2393] [/note]
2394
2395If `max_digits10` is not available, you should use the
2396[@http://www.cs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF Kahan formula for floating-point type T].
2397
2398In C++, the equations for what Kahan (on page 4) describes as 'at least' and 'at most' are:
2399
2400 static long double const log10Two = 0.30102999566398119521373889472449L; // log10(2.)
2401
2402 static_cast<int>(floor((significand_digits - 1) * log10Two)); // == digits10 - 'at least' .
2403 static_cast<int>(ceil(1 + significand_digits * log10Two)); // == max_digits10 - 'at most'.
2404
2405Unfortunately, these cannot be evaluated (at least by C++03) at [*compile-time].
2406So the following expression is often used instead.
2407
2408 max_digits10 = 2 + std::numeric_limits<T>::digits * 3010U/10000U;
2409
2410 // == 2 + std::numeric_limits<T>::digits for double and 64-bit long double.
2411 // == 3 + std::numeric_limits<T>::digits for float, 80-bit long-double and __float128.
2412
2413often the actual values are computed for the C limits macros:
2414
2415 #define FLT_MAXDIG10 (2+FLT_MANT_DIG * 3010U/10000U) // 9
2416 #define DBL_MAXDIG10 (2+ (DBL_MANT_DIG * 3010U)/10000U) // 17
2417 #define LDBL_MAXDIG10 (2+ (LDBL_MANT_DIG * 3010U)/10000U) // 17 for MSVC, 18 for others.
2418
2419The factor 3010U/10000U is ['log[sub 10](2) = 0.3010]
2420that can be evaluated at compile-time using only `short unsigned int`s to be a desirable `const` or `constexpr` (and usually also `static`).
2421
2422Boost macros allow this to be done portably, see
2423[@http://www.boost.org/doc/libs/1_58_0/libs/config/doc/html/boost_config/boost_macro_reference.html BOOST_CONSTEXPR_OR_CONST or BOOST_STATIC_CONSTEXPR].
2424
2425(See also
2426[@http://www.loria.fr/~zimmerma/mca/mca-cup-0.5.9.pdf Richard P. Brent and Paul Zimmerman, Modern Computer Arithmetic]
2427Equation 3.8 on page 116).
2428
2429[max_digits10_1] [/ example for using max_digits10]
2430
2431[h4 round_style]
2432
2433The rounding style determines how the result of floating-point operations
2434is treated when the result cannot be [*exactly represented] in the significand.
2435Various rounding modes may be provided:
2436
2437* round to nearest up or down (default for floating-point types).
2438* round up (toward positive infinity).
2439* round down (toward negative infinity).
2440* round toward zero (integer types).
2441* no rounding (if decimal radix).
2442* rounding mode is not determinable.
2443
2444For integer types, `std::numeric_limits<T>::round_style` is always towards zero, so
2445
2446 std::numeric_limits<T>::round_style == std::round_to_zero;
2447
2448A decimal type, `cpp_dec_float` rounds in no particular direction,
2449which is to say it doesn't round at all.
2450And since there are several guard digits,
2451it's not really the same as truncation (round toward zero) either.
2452
2453For floating-point types, it is normal to round to nearest.
2454
2455 std::numeric_limits<T>::round_style == std::round_to_nearest;
2456
2457See function `std::numeric_limits<T>::round_error` for the maximum error (in ULP)
2458that rounding can cause.
2459
2460[h4 has_denorm_loss]
2461
2462`true` if a loss of precision is detected as a
2463[@http://en.wikipedia.org/wiki/Denormalization denormalization] loss,
2464rather than an inexact result.
2465
2466Always `false` for integer types.
2467
2468`false` for all types which do not have `has_denorm` == `std::denorm_present`.
2469
2470[h4 denorm_style]
2471
2472[@http://en.wikipedia.org/wiki/Denormal_number Denormalized values] are
2473representations with a variable number of exponent bits that can permit
2474gradual underflow, so that, if type T is `double`.
2475
2476 std::numeric_limits<T>::denorm_min() < std::numeric_limits<T>::min()
2477
2478A type may have any of the following `enum float_denorm_style` values:
2479
2480* `std::denorm_absent`, if it does not allow denormalized values.
2481(Always used for all integer and exact types).
2482* `std::denorm_present`, if the floating-point type allows denormalized values.
2483*`std::denorm_indeterminate`, if indeterminate at compile time.
2484
2485[h4 Tinyness before rounding]
2486
2487`bool std::numeric_limits<T>::tinyness_before`
2488
2489`true` if a type can determine that a value is too small
2490to be represent as a normalized value before rounding it.
2491
2492Generally true for `is_iec559` floating-point built-in types,
2493but false for integer types.
2494
2495Standard-compliant IEEE 754 floating-point implementations may detect the floating-point underflow at three predefined moments:
2496
2497# After computation of a result with absolute value smaller than
2498`std::numeric_limits<T>::min()`,
2499such implementation detects ['tinyness before rounding] (e.g. UltraSparc).
2500
2501# After rounding of the result to `std::numeric_limits<T>::digits` bits,
2502if the result is tiny, such implementation detects ['tinyness after rounding]
2503(e.g. SuperSparc).
2504
2505# If the conversion of the rounded tiny result to subnormal form
2506resulted in the loss of precision, such implementation detects ['denorm loss].
2507
2508[endsect] [/section:constants std::numeric_limits<> Constants]
2509
2510[section:functions std::numeric_limits<> functions]
2511
2512[h4 max function]
2513
2514Function `std::numeric_limits<T>::max()` returns the largest finite value
2515that can be represented by the type T. If there is no such value (and
2516`numeric_limits<T>::bounded` is `false`) then returns `T()`.
2517
2518For built-in types there is usually a corresponding MACRO value TYPE_MAX,
2519where TYPE is CHAR, INT, FLOAT etc.
2520
2521Other types, including those provided by a typedef,
2522for example `INT64_T_MAX` for `int64_t`, may provide a macro definition.
2523
2524To cater for situations where no `numeric_limits` specialization is available
2525(for example because the precision of the type varies at runtime),
2526packaged versions of this (and other functions) are provided using
2527
2528 #include <boost/math/tools/precision.hpp>
2529
2530 T = boost::math::tools::max_value<T>();
2531
2532Of course, these simply use `std::numeric_limits<T>::max()` if available,
2533but otherwise 'do something sensible'.
2534
2535[h4 lowest function]
2536
2537Since C++11: `std::numeric_limits<T>::lowest()` is
2538
2539* For integral types, the same as function `min()`.
2540* For floating-point types, generally the negative of `max()`
2541(but implementation-dependent).
2542
2543[digits10_5]
2544
2545[h4 min function]
2546
2547Function `std::numeric_limits<T>::min()` returns the minimum finite value
2548that can be represented by the type T.
2549
2550For built-in types there is usually a corresponding MACRO value TYPE_MIN,
2551where TYPE is CHAR, INT, FLOAT etc.
2552
2553Other types, including those provided by a typedef,
2554for example `INT64_T_MIN` for `int64_t`, may provide a macro definition.
2555
2556For floating-point types,
2557it is more fully defined as the ['minimum positive normalized value].
2558
2559See `std::numeric_limits<T>::denorm_min()` for the smallest denormalized value, provided
2560
2561 std::numeric_limits<T>::has_denorm == std::denorm_present
2562
2563
2564To cater for situations where no `numeric_limits` specialization is available
2565(for example because the precision of the type varies at runtime),
2566packaged versions of this (and other functions) are provided using
2567
2568 #include <boost/math/tools/precision.hpp>
2569
2570 T = boost::math::tools::min_value<T>();
2571
2572Of course, these simply use `std::numeric_limits<T>::min()` if available.
2573
2574[h4 denorm_min function]
2575
2576Function `std::numeric_limits<T>::denorm_min()`
2577returns the smallest
2578[@http://en.wikipedia.org/wiki/Denormal_number denormalized value],
2579provided
2580
2581 std::numeric_limits<T>::has_denorm == std::denorm_present
2582
2583[denorm_min_1]
2584
2585The exponent is effectively reduced from -308 to -324
2586(though it remains encoded as zero and leading zeros appear in the significand,
2587thereby losing precision until the significand reaches zero).
2588
2589[h4 round_error]
2590
2591Function `std::numeric_limits<T>::round_error()` returns the maximum error
2592(in units of [@http://en.wikipedia.org/wiki/Unit_in_the_last_place ULP])
2593that can be caused by any basic arithmetic operation.
2594
2595 round_style == std::round_indeterminate;
2596
2597The rounding style is indeterminable at compile time.
2598
2599For floating-point types, when rounding is to nearest,
2600only half a bit is lost by rounding, and `round_error == 0.5`.
2601In contrast when rounding is towards zero, or plus/minus infinity,
2602we can loose up to one bit from rounding, and `round_error == 1`.
2603
2604For integer types, rounding always to zero, so at worst almost one bit can be rounded,
2605so `round_error == 1`.
2606
2607`round_error()` can be used with `std::numeric_limits<T>::epsilon()` to estimate
2608the maximum potential error caused by rounding. For typical floating-point types,
2609`round_error() = 1/2`, so half epsilon is the maximum potential error.
2610
2611[round_error_1]
2612
2613There are, of course, many occasions when much bigger loss of precision occurs,
2614for example, caused by
2615[@http://en.wikipedia.org/wiki/Loss_of_significance Loss of significance or cancellation error]
2616or very many iterations.
2617
2618[h4 epsilon]
2619
2620Function `std::numeric_limits<T>::epsilon()` is meaningful only for non-integral types.
2621
2622It returns the difference between `1.0` and the next value representable
2623by the floating-point type T.
2624So it is a one least-significant-bit change in this floating-point value.
2625
2626For `double` (`float_64t`) it is `2.2204460492503131e-016`
2627showing all possibly significant 17 decimal digits.
2628
2629[epsilon_1]
2630
2631We can explicitly increment by one bit using the function `boost::math::float_next()`
2632and the result is the same as adding `epsilon`.
2633
2634[epsilon_2]
2635
2636Adding any smaller value, like half `epsilon`, will have no effect on this value.
2637
2638[epsilon_3]
2639
2640So this cancellation error leaves the values equal, despite adding half `epsilon`.
2641
2642To achieve greater portability over platform and floating-point type,
2643Boost.Math and Boost.Multiprecion provide a package of functions that
2644'do something sensible' if the standard `numeric_limits` is not available.
2645To use these `#include <boost/math/tools/precision.hpp>`.
2646
2647[epsilon_4]
2648
2649[h5 Tolerance for Floating-point Comparisons]
2650
2651`epsilon` is very useful to compute a tolerance when comparing floating-point values,
2652a much more difficult task than is commonly imagined.
2653
2654For more information you probably want (but still need) see
2655[@http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html What Every Computer Scientist Should Know About Floating-Point Arithmetic]
2656
2657The naive test comparing the absolute difference between two values and a tolerance
2658does not give useful results if the values are too large or too small.
2659
2660So Boost.Test uses an algorithm first devised by Knuth
2661for reliably checking if floating-point values are close enough.
2662
2663See Donald. E. Knuth. The art of computer programming (vol II).
2664Copyright 1998 Addison-Wesley Longman, Inc., 0-201-89684-2.
2665Addison-Wesley Professional; 3rd edition.
2666
2667See also:
2668
2669[@http://adtmag.com/articles/2000/03/15/comparing-floats-how-to-determine-if-floating-quantities-are-close-enough-once-a-tolerance-has-been.aspx Alberto Squassia, Comparing floats]
2670
2671[@http://adtmag.com/articles/2000/03/16/comparing-floats-how-to-determine-if-floating-quantities-are-close-enough-once-a-tolerance-has-been.aspx Alberto Squassia, Comparing floats code]
2672
2673[@boost:/libs/test/doc/html/utf/testing-tools/floating_point_comparison.html floating-point comparison].
2674
2675[tolerance_1]
2676
2677used thus:
2678
2679 BOOST_CHECK_CLOSE_FRACTION(expected, calculated, tolerance);
2680
2681(There is also a version using tolerance as a percentage rather than a fraction).
2682
2683[tolerance_2]
2684
2685[h4 Infinity - positive and negative]
2686
2687For floating-point types only, for which
2688`std::numeric_limits<T>::has_infinity == true`,
2689function `std::numeric_limits<T>::infinity()`
2690provides an implementation-defined representation for [infin].
2691
2692The 'representation' is a particular bit pattern reserved for infinity.
2693For IEEE754 system (for which `std::numeric_limits<T>::is_iec559 == true`)
2694[@http://en.wikipedia.org/wiki/IEEE_754-1985#Positive_and_negative_infinity positive and negative infinity]
2695are assigned bit patterns for all defined floating-point types.
2696
2697Confusingly, the string resulting from outputting this representation, is also
2698implementation-defined. And the string that can be input to generate the representation is also implementation-defined.
2699
2700For example, the output is `1.#INF` on Microsoft systems, but `inf` on most *nix platforms.
2701
2702This implementation-defined-ness has hampered use of infinity (and NaNs)
2703but Boost.Math and Boost.Multiprecision work hard to provide a sensible representation
2704for [*all] floating-point types, not just the built-in types,
2705which with the use of suitable facets to define the input and output strings, makes it possible
2706to use these useful features portably and including Boost.Serialization.
2707
2708[h4 Not-A-Number NaN]
2709
2710[h5 Quiet_NaN]
2711
2712For floating-point types only, for which
2713`std::numeric_limits<T>::has_quiet_NaN == true`,
2714function `std::numeric_limits<T>::quiet_NaN()`
2715provides an implementation-defined representation for NaN.
2716
2717[@http://en.wikipedia.org/wiki/NaN NaNs] are values to indicate that the
2718result of an assignment or computation is meaningless.
2719A typical example is `0/0` but there are many others.
2720
2721NaNs may also be used, to represent missing values: for example,
2722these could, by convention, be ignored in calculations of statistics like means.
2723
2724Many of the problems with a representation for
2725[@http://en.wikipedia.org/wiki/NaN Not-A-Number] has hampered portable use,
2726similar to those with infinity.
2727
2728[nan_1]
2729
2730But using Boost.Math and suitable facets can permit portable use
2731of both NaNs and positive and negative infinity.
2732
2733[facet_1]
2734
2735[h5 Signaling NaN]
2736
2737For floating-point types only, for which
2738`std::numeric_limits<T>::has_signaling_NaN == true`,
2739function `std::numeric_limits<T>::signaling_NaN()`
2740provides an implementation-defined representation for NaN that causes a hardware trap.
2741It should be noted however, that at least one implementation of this function causes a hardware
2742trap to be triggered simply by calling `std::numeric_limits<T>::signaling_NaN()`, and not only
2743by using the value returned.
2744
2745[endsect] [/section:functions std::numeric_limits<> functions]
2746
2747[/ Tables of values for numeric_limits for various built-in and cpp_bin_float types]
2748[include numeric_limits_32_tables.qbk]
2749[/include numeric_limits_64_tables.qbk]
2750
2751[section:how_to_tell How to Determine the Kind of a Number From `std::numeric_limits`]
2752
2753Based on the information above, one can see that different kinds of numbers can be
2754differentiated based on the information stored in `std::numeric_limits`. This is
2755in addition to the traits class [link boost_multiprecision.ref.number.traits_class_support
2756number_category] provided by this library.
2757
2758[h4 Integer Types]
2759
2760For an integer type T, all of the following conditions hold:
2761
2762 std::numeric_limits<T>::is_specialized == true
2763 std::numeric_limits<T>::is_integer == true
2764 std::numeric_limits<T>::is_exact == true
2765 std::numeric_limits<T>::min_exponent == 0
2766 std::numeric_limits<T>::max_exponent == 0
2767 std::numeric_limits<T>::min_exponent10 == 0
2768 std::numeric_limits<T>::max_exponent10 == 0
2769
2770In addition the type is /signed/ if:
2771
2772 std::numeric_limits<T>::is_signed == true
2773
2774If the type is arbitrary precision then:
2775
2776 std::numeric_limits<T>::is_bounded == false
2777
2778Otherwise the type is bounded, and returns a non zero value
2779from:
2780
2781 std::numeric_limits<T>::max()
2782
2783and has:
2784
2785 std::numeric_limits<T>::is_modulo == true
2786
2787if the type implements modulo arithmetic on overflow.
2788
2789[h4 Rational Types]
2790
2791Rational types are just like integers except that:
2792
2793 std::numeric_limits<T>::is_integer == false
2794
2795[h4 Fixed Precision Types]
2796
2797There appears to be no way to tell these apart from rational types, unless they set:
2798
2799 std::numeric_limits<T>::is_exact == false
2800
2801This is because these types are in essence a rational type with a fixed denominator.
2802
2803[h4 floating-point Types]
2804
2805For a floating-point type T, all of the following conditions hold:
2806
2807 std::numeric_limits<T>::is_specialized == true
2808 std::numeric_limits<T>::is_integer == false
2809 std::numeric_limits<T>::is_exact == false
2810 std::numeric_limits<T>::min_exponent != 0
2811 std::numeric_limits<T>::max_exponent != 0
2812 std::numeric_limits<T>::min_exponent10 != 0
2813 std::numeric_limits<T>::max_exponent10 != 0
2814
2815In addition the type is /signed/ if:
2816
2817 std::numeric_limits<T>::is_signed == true
2818
2819And the type may be decimal or binary depending on the value of:
2820
2821 std::numeric_limits<T>::radix
2822
2823In general, there are no arbitrary precision floating-point types, and so:
2824
2825 std::numeric_limits<T>::is_bounded == false
2826
2827[h4 Exact floating-point Types]
2828
2829Exact floating-point types are a [@http://en.wikipedia.org/wiki/Field_%28mathematics%29 field]
2830composed of an arbitrary precision integer scaled by an exponent. Such types
2831have no division operator and are the same as floating-point types except:
2832
2833 std::numeric_limits<T>::is_exact == true
2834
2835[h4 Complex Numbers]
2836
2837For historical reasons, complex numbers do not specialize `std::numeric_limits`, instead you must
2838inspect `std::numeric_limits<T::value_type>`.
2839
2840[endsect] [/section:how_to_tell How to Determine the Kind of a Number From `std::numeric_limits`]
2841
2842
2843[endsect] [/section:limits Numeric Limits]
2844
2845
2846[section:input_output Input Output]
2847
2848
2849[h4 Loopback testing]
2850
2851['Loopback] or ['round-tripping] refers to writing out a value as a decimal digit string using `std::iostream`,
2852usually to a `std::stringstream`, and then reading the string back in to another value,
2853and confirming that the two values are identical. A trivial example using `float` is:
2854
2855 float write; // Value to round-trip.
2856 std::stringstream ss; // Read and write std::stringstream.
2857 ss.precision(std::numeric_limits<T>::max_digits10); // Ensure all potentially significant bits are output.
2858 ss.flags(std::ios_base::fmtflags(std::ios_base::scientific)); // Use scientific format.
2859 ss << write; // Output to string.
2860 float read; // Expected.
2861 ss >> read; // Read decimal digits string from stringstream.
2862 BOOST_CHECK_EQUAL(write, read); // Should be the same.
2863
2864and this can be run in a loop for all possible values of a 32-bit float.
2865For other floating-point types `T`, including built-in `double`,
2866it takes far too long to test all values,
2867so a reasonable test strategy is to use a large number of random values.
2868
2869 T write;
2870 std::stringstream ss;
2871 ss.precision(std::numeric_limits<T>::max_digits10); // Ensure all potentially significant bits are output.
2872 ss.flags(f); // Changed from default iostream format flags if desired.
2873 ss << write; // Output to stringstream.
2874
2875 T read;
2876 ss >> read; // Get read using operator>> from stringstream.
2877 BOOST_CHECK_EQUAL(read, write);
2878
2879 read = static_cast<T>(ss.str()); // Get read by converting from decimal digits string representation of write.
2880 BOOST_CHECK_EQUAL(read, write);
2881
2882 read = static_cast<T>(write.str(0, f)); // Get read using format specified when written.
2883 BOOST_CHECK_EQUAL(read, write);
2884
2885
2886The test at
2887[@../../test/test_cpp_bin_float_io.cpp test_cpp_bin_float_io.cpp]
2888allows any floating-point type to be ['round_tripped] using a wide range of fairly random values.
2889It also includes tests compared a collection of
2890[@../../test/string_data.ipp stringdata] test cases in a file.
2891
2892[h4 Comparing with output using Built-in types]
2893
2894One can make some comparisons with the output of
2895
2896 <number<cpp_bin_float<53, digit_count_2> >
2897
2898which has the same number of significant bits (53) as 64-bit double precision floating-point.
2899
2900However, although most outputs are identical, there are differences on some platforms
2901caused by the implementation-dependent behaviours allowed by the C99 specification
2902[@http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf C99 ISO/IEC 9899:TC2],
2903incorporated by C++.
2904
2905[:['"For e, E, f, F, g, and G conversions, if the number of significant decimal digits
2906is at most DECIMAL_DIG, then the result should be correctly rounded.
2907If the number of significant decimal digits is more than DECIMAL_DIG
2908but the source value is exactly representable with DECIMAL_DIG digits,
2909then the result should be an exact representation with trailing zeros.
2910Otherwise, the source value is bounded by two adjacent decimal strings L < U,
2911both having DECIMAL_DIG significant digits;
2912the value of the resultant decimal string D should satisfy L<= D <= U,
2913with the extra stipulation that the error should have a correct sign
2914for the current rounding direction."]]
2915
2916So not only is correct rounding for the full number of digits not required,
2917but even if the *optional* recommended practice is followed,
2918then the value of these last few digits is unspecified
2919as long as the value is within certain bounds.
2920
2921[note Do not expect the output from different platforms
2922to be [*identical], but `cpp_dec_float`, `cpp_bin_float` (and other backends) outputs should be
2923correctly rounded to the number of digits requested by the set precision and format.]
2924
2925
2926[h4 Macro BOOST_MP_MIN_EXPONENT_DIGITS]
2927
2928[@http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf C99 Standard]
2929for [/e and E] format specifiers, 7.19.6 Formatted input/output functions requires:
2930
2931\"The exponent always contains at least two digits,
2932and only as many more digits as necessary to represent the exponent.\"
2933
2934So to conform to the C99 standard (incorporated by C++)
2935
2936 #define BOOST_MP_MIN_EXPONENT_DIGITS 2
2937
2938Confusingly, Microsoft (and MinGW) do not conform to this standard and provide
2939[*at least three digits], for example `1e+001`.
2940So if you want the output to match that from
2941built-in floating-point types on compilers that use Microsofts runtime then use:
2942
2943 #define BOOST_MP_MIN_EXPONENT_DIGITS 3
2944
2945Also useful to get the minimum exponent field width is
2946
2947 #define BOOST_MP_MIN_EXPONENT_DIGITS 1
2948
2949producing a compact output like `2e+4`,
2950useful when conserving space is important.
2951
2952Larger values are also supported, for example, value 4 for `2e+0004`
2953which may be useful to ensure that columns line up.
2954
2955[endsect] [/section:input_output Input Output]
2956
2957[section:hash Hash Function Support]
2958
2959[hash1]
2960
2961[hash2]
2962
2963[hash3]
2964
2965[hash4]
2966
2967[endsect][/hash]
2968
2969
2970[endsect]
2971
2972[section:ref Reference]
2973
2974[section:number number]
2975
2976[h4 Synopsis]
2977
2978 namespace boost{ namespace multiprecision{
2979
2980 enum expression_template_option { et_on = 1, et_off = 0 };
2981
2982 template <class Backend> struct expression_template_default
2983 { static const expression_template_option value = et_on; };
2984
2985 template <class Backend, expression_template_option ExpressionTemplates = expression_template_default<Backend>::value>
2986 class number
2987 {
2988 number();
2989 number(see-below);
2990 number& operator=(see-below);
2991 number& assign(see-below);
2992
2993 // Member operators
2994 number& operator+=(const ``['see-below]``&);
2995 number& operator-=(const ``['see-below]``&);
2996 number& operator*=(const ``['see-below]``&);
2997 number& operator/=(const ``['see-below]``&);
2998 number& operator++();
2999 number& operator--();
3000 number operator++(int);
3001 number operator--(int);
3002
3003 number& operator%=(const ``['see-below]``&);
3004 number& operator&=(const ``['see-below]``&);
3005 number& operator|=(const ``['see-below]``&);
3006 number& operator^=(const ``['see-below]``&);
3007 number& operator<<=(const ``['integer-type]``&);
3008 number& operator>>=(const ``['integer-type]``&);
3009
3010 // Use in Boolean context:
3011 operator ``['convertible-to-bool-type]``()const;
3012 // swap:
3013 void swap(number& other);
3014 // Sign:
3015 bool is_zero()const;
3016 int sign()const;
3017 // string conversion:
3018 std::string str()const;
3019 // Generic conversion mechanism
3020 template <class T>
3021 T convert_to()const;
3022 template <class T>
3023 explicit operator T ()const;
3024 // precision control:
3025 static unsigned default_precision();
3026 static void default_precision(unsigned digits10);
3027 unsigned precision()const;
3028 void precision(unsigned digits10);
3029 // Comparison:
3030 int compare(const number<Backend>& o)const;
3031 template <class V>
3032 typename enable_if<is_convertible<V, number<Backend, ExpressionTemplates> >, int>::type
3033 compare(const V& o)const;
3034 // Access to the underlying implementation:
3035 Backend& backend();
3036 const Backend& backend()const;
3037 };
3038
3039 // Non member operators:
3040 ``['unmentionable-expression-template-type]`` operator+(const ``['see-below]``&);
3041 ``['unmentionable-expression-template-type]`` operator-(const ``['see-below]``&);
3042 ``['unmentionable-expression-template-type]`` operator+(const ``['see-below]``&, const ``['see-below]``&);
3043 ``['unmentionable-expression-template-type]`` operator-(const ``['see-below]``&, const ``['see-below]``&);
3044 ``['unmentionable-expression-template-type]`` operator*(const ``['see-below]``&, const ``['see-below]``&);
3045 ``['unmentionable-expression-template-type]`` operator/(const ``['see-below]``&, const ``['see-below]``&);
3046 // Integer only operations:
3047 ``['unmentionable-expression-template-type]`` operator%(const ``['see-below]``&, const ``['see-below]``&);
3048 ``['unmentionable-expression-template-type]`` operator&(const ``['see-below]``&, const ``['see-below]``&);
3049 ``['unmentionable-expression-template-type]`` operator|(const ``['see-below]``&, const ``['see-below]``&);
3050 ``['unmentionable-expression-template-type]`` operator^(const ``['see-below]``&, const ``['see-below]``&);
3051 ``['unmentionable-expression-template-type]`` operator<<(const ``['see-below]``&, const ``['integer-type]``&);
3052 ``['unmentionable-expression-template-type]`` operator>>(const ``['see-below]``&, const ``['integer-type]``&);
3053 // Comparison operators:
3054 bool operator==(const ``['see-below]``&, const ``['see-below]``&);
3055 bool operator!=(const ``['see-below]``&, const ``['see-below]``&);
3056 bool operator< (const ``['see-below]``&, const ``['see-below]``&);
3057 bool operator> (const ``['see-below]``&, const ``['see-below]``&);
3058 bool operator<=(const ``['see-below]``&, const ``['see-below]``&);
3059 bool operator>=(const ``['see-below]``&, const ``['see-below]``&);
3060
3061 // Swap:
3062 template <class Backend, expression_template_option ExpressionTemplates>
3063 void swap(number<Backend, ExpressionTemplates>& a, number<Backend, ExpressionTemplates>& b);
3064
3065 // iostream support:
3066 template <class Backend, expression_template_option ExpressionTemplates>
3067 std::ostream& operator << (std::ostream& os, const number<Backend, ExpressionTemplates>& r);
3068 std::ostream& operator << (std::ostream& os, const ``['unmentionable-expression-template-type]``& r);
3069 template <class Backend, expression_template_option ExpressionTemplates>
3070 std::istream& operator >> (std::istream& is, number<Backend, ExpressionTemplates>& r);
3071
3072 // Arithmetic with a higher precision result:
3073 template <class ResultType, class Source1 class Source2>
3074 ResultType& add(ResultType& result, const Source1& a, const Source2& b);
3075 template <class ResultType, class Source1 class Source2>
3076 ResultType& subtract(ResultType& result, const Source1& a, const Source2& b);
3077 template <class ResultType, class Source1 class Source2>
3078 ResultType& multiply(ResultType& result, const Source1& a, const Source2& b);
3079
3080 // min and max overloads:
3081 ``['number]`` min (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3082 ``['number]`` max (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3083
3084 // C99 Non-member function standard library support:
3085 ``['unmentionable-expression-template-type]`` abs (const ``['number-or-expression-template-type]``&);
3086 ``['unmentionable-expression-template-type]`` acos (const ``['number-or-expression-template-type]``&);
3087 ``['number]`` acosh (const ``['number-or-expression-template-type]``&);
3088 ``['unmentionable-expression-template-type]`` asin (const ``['number-or-expression-template-type]``&);
3089 ``['number]`` asinh (const ``['number-or-expression-template-type]``&);
3090 ``['unmentionable-expression-template-type]`` atan (const ``['number-or-expression-template-type]``&);
3091 ``['unmentionable-expression-template-type]`` atan2 (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3092 ``['number]`` atanh (const ``['number-or-expression-template-type]``&);
3093 ``['number]`` cbrt (const ``['number-or-expression-template-type]``&);
3094 ``['unmentionable-expression-template-type]`` ceil (const ``['number-or-expression-template-type]``&);
3095 ``['number]`` copysign (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3096 ``['unmentionable-expression-template-type]`` cos (const ``['number-or-expression-template-type]``&);
3097 ``['unmentionable-expression-template-type]`` cosh (const ``['number-or-expression-template-type]``&);
3098 ``['number]`` erf (const ``['number-or-expression-template-type]``&);
3099 ``['number]`` erfc (const ``['number-or-expression-template-type]``&);
3100 ``['unmentionable-expression-template-type]`` exp (const ``['number-or-expression-template-type]``&);
3101 ``['unmentionable-expression-template-type]`` exp2 (const ``['number-or-expression-template-type]``&);
3102 ``['number]`` expm1 (const ``['number-or-expression-template-type]``&);
3103 ``['unmentionable-expression-template-type]`` fabs (const ``['number-or-expression-template-type]``&);
3104 ``['unmentionable-expression-template-type]`` fdim (const ``['number-or-expression-template-type]``&);
3105 ``['unmentionable-expression-template-type]`` floor (const ``['number-or-expression-template-type]``&);
3106 ``['unmentionable-expression-template-type]`` fma (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3107 ``['unmentionable-expression-template-type]`` fmin (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3108 ``['unmentionable-expression-template-type]`` fmax (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3109 ``['unmentionable-expression-template-type]`` fmod (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3110 ``['unmentionable-expression-template-type]`` frexp (const ``['number-or-expression-template-type]``&, ``['integer-type]``*);
3111 ``['unmentionable-expression-template-type]`` hypot (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3112 ``['integer-type]`` ilogb (const ``['number-or-expression-template-type]``&);
3113 ``['unmentionable-expression-template-type]`` ldexp (const ``['number-or-expression-template-type]``&, ``['integer-type]``);
3114 ``['number]`` lgamma (const ``['number-or-expression-template-type]``&);
3115 long long llrint (const ``['number-or-expression-template-type]``&);
3116 long long llround (const ``['number-or-expression-template-type]``&);
3117 ``['unmentionable-expression-template-type]`` log (const ``['number-or-expression-template-type]``&);
3118 ``['unmentionable-expression-template-type]`` log2 (const ``['number-or-expression-template-type]``&);
3119 ``['unmentionable-expression-template-type]`` log10 (const ``['number-or-expression-template-type]``&);
3120 ``['number]`` log1p (const ``['number-or-expression-template-type]``&);
3121 ``['unmentionable-expression-template-type]`` logb (const ``['number-or-expression-template-type]``&);
3122 long lrint (const ``['number-or-expression-template-type]``&);
3123 long lround (const ``['number-or-expression-template-type]``&);
3124 ``['unmentionable-expression-template-type]`` modf (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3125 ``['unmentionable-expression-template-type]`` nearbyint (const ``['number-or-expression-template-type]``&);
3126 ``['number]`` nextafter (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3127 ``['number]`` nexttoward (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3128 ``['unmentionable-expression-template-type]`` pow (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3129 ``['unmentionable-expression-template-type]`` remainder (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3130 ``['unmentionable-expression-template-type]`` remquo (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&, int*);
3131 ``['unmentionable-expression-template-type]`` rint (const ``['number-or-expression-template-type]``&);
3132 ``['unmentionable-expression-template-type]`` round (const ``['number-or-expression-template-type]``&);
3133 ``['unmentionable-expression-template-type]`` scalbn (const ``['number-or-expression-template-type]``&, ``['integer-type]``);
3134 ``['unmentionable-expression-template-type]`` scalbln (const ``['number-or-expression-template-type]``&, ``['integer-type]``);
3135 ``['unmentionable-expression-template-type]`` sin (const ``['number-or-expression-template-type]``&);
3136 ``['unmentionable-expression-template-type]`` sinh (const ``['number-or-expression-template-type]``&);
3137 ``['unmentionable-expression-template-type]`` sqrt (const ``['number-or-expression-template-type]``&);
3138 ``['unmentionable-expression-template-type]`` tan (const ``['number-or-expression-template-type]``&);
3139 ``['unmentionable-expression-template-type]`` tanh (const ``['number-or-expression-template-type]``&);
3140 ``['number]`` tgamma (const ``['number-or-expression-template-type]``&);
3141 ``['unmentionable-expression-template-type]`` trunc (const ``['number-or-expression-template-type]``&);
3142
3143 int fpclassify (const ``['number-or-expression-template-type]``&);
3144 bool isfinite (const ``['number-or-expression-template-type]``&);
3145 bool isinf (const ``['number-or-expression-template-type]``&);
3146 bool isnan (const ``['number-or-expression-template-type]``&);
3147 bool isnormal (const ``['number-or-expression-template-type]``&);
3148 int signbit (const ``['number-or-expression-template-type]``&);
3149
3150 bool isgreater (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3151 bool isgreaterequal(const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3152 bool isless (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3153 bool islessequal(const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3154 bool islessgreater(const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3155 bool isunordered(const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3156 // Misc other common C library functions:
3157 ``['unmentionable-expression-template-type]`` itrunc (const ``['number-or-expression-template-type]``&);
3158 ``['unmentionable-expression-template-type]`` ltrunc (const ``['number-or-expression-template-type]``&);
3159 ``['unmentionable-expression-template-type]`` lltrunc(const ``['number-or-expression-template-type]``&);
3160 ``['unmentionable-expression-template-type]`` iround (const ``['number-or-expression-template-type]``&);
3161 ``['number]`` changesign(const ``['number-or-expression-template-type]``&);
3162 ``['number]`` copysign(const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3163
3164 // Traits support:
3165 template <class T>
3166 struct component_type;
3167 template <class T>
3168 struct number_category;
3169 template <class T>
3170 struct is_number;
3171 template <class T>
3172 struct is_number_expression;
3173
3174 // Integer specific functions:
3175 ``['unmentionable-expression-template-type]`` gcd(const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3176 ``['unmentionable-expression-template-type]`` lcm(const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3177 ``['unmentionable-expression-template-type]`` pow(const ``['number-or-expression-template-type]``&, unsigned);
3178 ``['unmentionable-expression-template-type]`` powm(const ``['number-or-expression-template-type]``& b, const ``['number-or-expression-template-type]``& p, const ``['number-or-expression-template-type]``& m);
3179 ``['unmentionable-expression-template-type]`` sqrt(const ``['number-or-expression-template-type]``&);
3180 template <class Backend, expression_template_option ExpressionTemplates>
3181 number<Backend, EXpressionTemplates> sqrt(const ``['number-or-expression-template-type]``&, number<Backend, EXpressionTemplates>&);
3182 template <class Backend, expression_template_option ExpressionTemplates>
3183 void divide_qr(const ``['number-or-expression-template-type]``& x, const ``['number-or-expression-template-type]``& y,
3184 number<Backend, ExpressionTemplates>& q, number<Backend, ExpressionTemplates>& r);
3185 template <class Integer>
3186 Integer integer_modulus(const ``['number-or-expression-template-type]``& x, Integer val);
3187 unsigned lsb(const ``['number-or-expression-template-type]``& x);
3188 unsigned msb(const ``['number-or-expression-template-type]``& x);
3189 template <class Backend, class ExpressionTemplates>
3190 bool bit_test(const number<Backend, ExpressionTemplates>& val, unsigned index);
3191 template <class Backend, class ExpressionTemplates>
3192 number<Backend, ExpressionTemplates>& bit_set(number<Backend, ExpressionTemplates>& val, unsigned index);
3193 template <class Backend, class ExpressionTemplates>
3194 number<Backend, ExpressionTemplates>& bit_unset(number<Backend, ExpressionTemplates>& val, unsigned index);
3195 template <class Backend, class ExpressionTemplates>
3196 number<Backend, ExpressionTemplates>& bit_flip(number<Backend, ExpressionTemplates>& val, unsigned index);
3197 template <class Engine>
3198 bool miller_rabin_test(const ``['number-or-expression-template-type]``& n, unsigned trials, Engine& gen);
3199 bool miller_rabin_test(const ``['number-or-expression-template-type]``& n, unsigned trials);
3200
3201 // Rational number support:
3202 typename component_type<``['number-or-expression-template-type]``>::type numerator (const ``['number-or-expression-template-type]``&);
3203 typename component_type<``['number-or-expression-template-type]``>::type denominator(const ``['number-or-expression-template-type]``&);
3204
3205 }} // namespaces
3206
3207 namespace boost{ namespace math{
3208
3209 // Boost.Math interoperability functions:
3210 int fpclassify (const ``['number-or-expression-template-type]``&, int);
3211 bool isfinite (const ``['number-or-expression-template-type]``&, int);
3212 bool isnan (const ``['number-or-expression-template-type]``&, int);
3213 bool isinf (const ``['number-or-expression-template-type]``&, int);
3214 bool isnormal (const ``['number-or-expression-template-type]``&, int);
3215
3216 }} // namespaces
3217
3218 // numeric_limits support:
3219 namespace std{
3220
3221 template <class Backend, expression_template_option ExpressionTemplates>
3222 struct numeric_limits<boost::multiprecision<Backend, ExpressionTemplates> >
3223 {
3224 /* Usual members here */
3225 };
3226
3227 }
3228
3229[h4 Description]
3230
3231 enum expression_template_option { et_on = 1, et_off = 0 };
3232
3233This enumerated type is used to specify whether expression templates are turned on (et_on) or turned off (et_off).
3234
3235 template <class Backend> struct expression_template_default
3236 { static const expression_template_option value = et_on; };
3237
3238This traits class specifies the default expression template option to be used with a particular Backend type.
3239It defaults to `et_on`.
3240
3241 template <class Backend, expression_template_option ExpressionTemplates = expression_template_default<Backend>::value>
3242 class number;
3243
3244Class `number` has two template arguments:
3245
3246[variablelist
3247[[Backend][The actual arithmetic back-end that does all the work.]]
3248[[ExpressionTemplates][A Boolean value: when `et_on`, then expression templates are enabled, otherwise when set to `et_off` they are disabled.
3249 The default for this parameter is computed via the traits class `expression_template_default` whose member `value` defaults to `et_on` unless
3250 the traits class is specialized for a particular backend.]]
3251]
3252
3253 number();
3254 number(see-below);
3255 number& operator=(see-below);
3256 number& assign(see-below);
3257
3258Type `number` is default constructible, and both copy constructible and assignable from:
3259
3260* Itself.
3261* An expression template which is the result of one of the arithmetic operators.
3262* Any builtin arithmetic type, as long as the result would not be lossy (for example float to integer conversion).
3263* Any type that the Backend is implicitly constructible or assignable from.
3264* An rvalue reference to another `number`. Move-semantics are used for construction if the backend also
3265supports rvalue reference construction. In the case of assignment, move semantics are always supported
3266when the argument is an rvalue reference irrespective of the backend.
3267* Any type in the same family, as long as no loss of precision is involved. For example from `int128_t` to `int256_t`,
3268or `cpp_dec_float_50` to `cpp_dec_float_100`.
3269
3270Type `number` is explicitly constructible from:
3271
3272* Any type mentioned above.
3273* A `std::string` or any type which is convertible to `const char*`.
3274* Any arithmetic type (including those that would result in lossy conversions).
3275* Any type in the same family, including those that result in loss of precision.
3276* Any type that the Backend is explicitly constructible from.
3277* Any pair of types for which a generic interconversion exists: that is from integer to integer, integer
3278to rational, integer to float, rational to rational, rational to float, or float to float.
3279
3280The assign member function is available for any type for which an explicit converting constructor exists.
3281It is intended to be used where a temporary generated from an explicit assignment would be expensive, for example:
3282
3283 mpfr_float_50 f50;
3284 mpfr_float_100 f100;
3285
3286 f50 = static_cast<mpfr_float_50>(f100); // explicit cast create a temporary
3287 f50.assign(f100); // explicit call to assign create no temporary
3288
3289In addition, if the type has multiple components (for example rational or complex number types), then there is a
3290two argument constructor:
3291
3292 number(arg1, arg2);
3293
3294Where the two args must either be arithmetic types, or types that are convertible to the two components of `this`.
3295
3296 number& operator+=(const ``['see-below]``&);
3297 number& operator-=(const ``['see-below]``&);
3298 number& operator*=(const ``['see-below]``&);
3299 number& operator/=(const ``['see-below]``&);
3300 number& operator++();
3301 number& operator--();
3302 number operator++(int);
3303 number operator--(int);
3304 // Integer only operations:
3305 number& operator%=(const ``['see-below]``&);
3306 number& operator&=(const ``['see-below]``&);
3307 number& operator|=(const ``['see-below]``&);
3308 number& operator^=(const ``['see-below]``&);
3309 number& operator<<=(const ``['integer-type]``&);
3310 number& operator>>=(const ``['integer-type]``&);
3311
3312These operators all take their usual arithmetic meanings.
3313
3314The arguments to these operators is either:
3315
3316* Another `number<Backend, ExpressionTemplates>`.
3317* An expression template derived from `number<Backend>`.
3318* Any type implicitly convertible to `number<Backend, ExpressionTemplates>`, including some other instance of class `number`.
3319
3320For the left and right shift operations, the argument must be a builtin
3321integer type with a positive value (negative values result in a `std::runtime_error` being thrown).
3322
3323 operator ``['convertible-to-bool-type]``()const;
3324
3325Returns an ['unmentionable-type] that is usable in Boolean contexts (this allows `number` to be used in any
3326Boolean context - if statements, conditional statements, or as an argument to a logical operator - without
3327type `number` being convertible to type `bool`.
3328
3329This operator also enables the use of `number` with any of the following operators:
3330`!`, `||`, `&&` and `?:`.
3331
3332 void swap(number& other);
3333
3334Swaps `*this` with `other`.
3335
3336 bool is_zero()const;
3337
3338Returns `true` is `*this` is zero, otherwise `false`.
3339
3340 int sign()const;
3341
3342Returns a value less than zero if `*this` is negative, a value greater than zero if `*this` is positive, and zero
3343if `*this` is zero.
3344
3345 std::string str(unsigned precision, bool scientific = true)const;
3346
3347Returns the number formatted as a string, with at least /precision/ digits, and in scientific format
3348if /scientific/ is true.
3349
3350 template <class T>
3351 T convert_to()const;
3352
3353 template <class T>
3354 explicit operator T ()const;
3355
3356Provides a generic conversion mechanism to convert `*this` to type `T`. Type `T` may be any arithmetic type.
3357Optionally other types may also be supported by specific `Backend` types.
3358
3359
3360 static unsigned default_precision();
3361 static void default_precision(unsigned digits10);
3362 unsigned precision()const;
3363 void precision(unsigned digits10);
3364
3365These functions are only available if the Backend template parameter supports runtime changes to precision. They get and set
3366the default precision and the precision of `*this` respectively.
3367
3368 int compare(const number<Backend, ExpressionTemplates>& o)const;
3369 template <class V>
3370 typename enable_if<is_convertible<V, number<Backend, ExpressionTemplates> >, int>::type
3371 compare(const V& other)const;
3372
3373Returns:
3374
3375* A value less that 0 for `*this < other`
3376* A value greater that 0 for `*this > other`
3377* Zero for `*this == other`
3378
3379 Backend& backend();
3380 const Backend& backend()const;
3381
3382Returns the underlying back-end instance used by `*this`.
3383
3384[h4 Non-member operators]
3385
3386 // Non member operators:
3387 ``['unmentionable-expression-template-type]`` operator+(const ``['see-below]``&);
3388 ``['unmentionable-expression-template-type]`` operator-(const ``['see-below]``&);
3389 ``['unmentionable-expression-template-type]`` operator+(const ``['see-below]``&, const ``['see-below]``&);
3390 ``['unmentionable-expression-template-type]`` operator-(const ``['see-below]``&, const ``['see-below]``&);
3391 ``['unmentionable-expression-template-type]`` operator*(const ``['see-below]``&, const ``['see-below]``&);
3392 ``['unmentionable-expression-template-type]`` operator/(const ``['see-below]``&, const ``['see-below]``&);
3393 // Integer only operations:
3394 ``['unmentionable-expression-template-type]`` operator%(const ``['see-below]``&, const ``['see-below]``&);
3395 ``['unmentionable-expression-template-type]`` operator&(const ``['see-below]``&, const ``['see-below]``&);
3396 ``['unmentionable-expression-template-type]`` operator|(const ``['see-below]``&, const ``['see-below]``&);
3397 ``['unmentionable-expression-template-type]`` operator^(const ``['see-below]``&, const ``['see-below]``&);
3398 ``['unmentionable-expression-template-type]`` operator<<(const ``['see-below]``&, const ``['integer-type]``&);
3399 ``['unmentionable-expression-template-type]`` operator>>(const ``['see-below]``&, const ``['integer-type]``&);
3400 // Comparison operators:
3401 bool operator==(const ``['see-below]``&, const ``['see-below]``&);
3402 bool operator!=(const ``['see-below]``&, const ``['see-below]``&);
3403 bool operator< (const ``['see-below]``&, const ``['see-below]``&);
3404 bool operator> (const ``['see-below]``&, const ``['see-below]``&);
3405 bool operator<=(const ``['see-below]``&, const ``['see-below]``&);
3406 bool operator>=(const ``['see-below]``&, const ``['see-below]``&);
3407
3408These operators all take their usual arithmetic meanings.
3409
3410The arguments to these functions must contain at least one of the following:
3411
3412* A `number`.
3413* An expression template type derived from `number`.
3414* Any type for which `number` has an implicit constructor - for example a builtin arithmetic type.
3415
3416The return type of these operators is either:
3417
3418* An ['unmentionable-type] expression template type when `ExpressionTemplates` is `true`.
3419* Type `number<Backend, et_off>` when `ExpressionTemplates` is `false`.
3420* Type `bool` if the operator is a comparison operator.
3421
3422Finally note that the second argument to the left and right shift operations must be a builtin integer type,
3423and that the argument must be positive (negative arguments result in a `std::runtime_error` being thrown).
3424
3425[h4 swap]
3426
3427 template <class Backend, ExpressionTemplates>
3428 void swap(number<Backend, ExpressionTemplates>& a, number<Backend, ExpressionTemplates>& b);
3429
3430Swaps `a` and `b`.
3431
3432[h4 Iostream Support]
3433
3434 template <class Backend, expression_template_option ExpressionTemplates>
3435 std::ostream& operator << (std::ostream& os, const number<Backend, ExpressionTemplates>& r);
3436 template <class Unspecified...>
3437 std::ostream& operator << (std::ostream& os, const unmentionable-expression-template& r);
3438 template <class Backend, expression_template_option ExpressionTemplates>
3439 inline std::istream& operator >> (std::istream& is, number<Backend, ExpressionTemplates>& r)
3440
3441These operators provided formatted input-output operations on `number` types, and expression templates derived from them.
3442
3443It's down to the back-end type to actually implement string conversion. However, the back-ends provided with
3444this library support all of the iostream formatting flags, field width and precision settings.
3445
3446[h4 Arithmetic with a higher precision result]
3447
3448 template <class ResultType, class Source1 class Source2>
3449 ResultType& add(ResultType& result, const Source1& a, const Source2& b);
3450
3451 template <class ResultType, class Source1 class Source2>
3452 ResultType& subtract(ResultType& result, const Source1& a, const Source2& b);
3453
3454 template <class ResultType, class Source1 class Source2>
3455 ResultType& multiply(ResultType& result, const Source1& a, const Source2& b);
3456
3457These functions apply the named operator to the arguments ['a] and ['b] and store the
3458result in ['result], returning ['result]. In all cases they behave "as if"
3459arguments ['a] and ['b] were first promoted to type `ResultType` before applying the
3460operator, though particular backends may well avoid that step by way of an optimization.
3461
3462The type `ResultType` must be an instance of class `number`, and the types `Source1` and `Source2`
3463may be either instances of class `number` or native integer types. The latter is an optimization
3464that allows arithmetic to be performed on native integer types producing an extended precision result.
3465
3466[h4 Non-member standard library function support]
3467
3468 ``['unmentionable-expression-template-type]`` abs (const ``['number-or-expression-template-type]``&);
3469 ``['unmentionable-expression-template-type]`` acos (const ``['number-or-expression-template-type]``&);
3470 ``['number]`` acosh (const ``['number-or-expression-template-type]``&);
3471 ``['unmentionable-expression-template-type]`` asin (const ``['number-or-expression-template-type]``&);
3472 ``['number]`` asinh (const ``['number-or-expression-template-type]``&);
3473 ``['unmentionable-expression-template-type]`` atan (const ``['number-or-expression-template-type]``&);
3474 ``['unmentionable-expression-template-type]`` atan2 (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3475 ``['number]`` atanh (const ``['number-or-expression-template-type]``&);
3476 ``['number]`` cbrt (const ``['number-or-expression-template-type]``&);
3477 ``['unmentionable-expression-template-type]`` ceil (const ``['number-or-expression-template-type]``&);
3478 ``['number]`` copysign (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3479 ``['unmentionable-expression-template-type]`` cos (const ``['number-or-expression-template-type]``&);
3480 ``['unmentionable-expression-template-type]`` cosh (const ``['number-or-expression-template-type]``&);
3481 ``['number]`` erf (const ``['number-or-expression-template-type]``&);
3482 ``['number]`` erfc (const ``['number-or-expression-template-type]``&);
3483 ``['unmentionable-expression-template-type]`` exp (const ``['number-or-expression-template-type]``&);
3484 ``['unmentionable-expression-template-type]`` exp2 (const ``['number-or-expression-template-type]``&);
3485 ``['number]`` expm1 (const ``['number-or-expression-template-type]``&);
3486 ``['unmentionable-expression-template-type]`` fabs (const ``['number-or-expression-template-type]``&);
3487 ``['unmentionable-expression-template-type]`` fdim (const ``['number-or-expression-template-type]``&);
3488 ``['unmentionable-expression-template-type]`` floor (const ``['number-or-expression-template-type]``&);
3489 ``['unmentionable-expression-template-type]`` fma (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3490 ``['unmentionable-expression-template-type]`` fmin (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3491 ``['unmentionable-expression-template-type]`` fmax (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3492 ``['unmentionable-expression-template-type]`` fmod (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3493 ``['unmentionable-expression-template-type]`` frexp (const ``['number-or-expression-template-type]``&, ``['integer-type]``*);
3494 ``['unmentionable-expression-template-type]`` hypot (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3495 ``['integer-type]`` ilogb (const ``['number-or-expression-template-type]``&);
3496 ``['unmentionable-expression-template-type]`` ldexp (const ``['number-or-expression-template-type]``&, ``['integer-type]``);
3497 ``['number]`` lgamma (const ``['number-or-expression-template-type]``&);
3498 long long llrint (const ``['number-or-expression-template-type]``&);
3499 long long llround (const ``['number-or-expression-template-type]``&);
3500 ``['unmentionable-expression-template-type]`` log (const ``['number-or-expression-template-type]``&);
3501 ``['unmentionable-expression-template-type]`` log2 (const ``['number-or-expression-template-type]``&);
3502 ``['unmentionable-expression-template-type]`` log10 (const ``['number-or-expression-template-type]``&);
3503 ``['number]`` log1p (const ``['number-or-expression-template-type]``&);
3504 ``['unmentionable-expression-template-type]`` logb (const ``['number-or-expression-template-type]``&);
3505 long lrint (const ``['number-or-expression-template-type]``&);
3506 long lround (const ``['number-or-expression-template-type]``&);
3507 ``['unmentionable-expression-template-type]`` modf (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3508 ``['unmentionable-expression-template-type]`` nearbyint (const ``['number-or-expression-template-type]``&);
3509 ``['number]`` nextafter (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3510 ``['number]`` nexttoward (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3511 ``['unmentionable-expression-template-type]`` pow (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3512 ``['unmentionable-expression-template-type]`` remainder (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3513 ``['unmentionable-expression-template-type]`` remquo (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&, int*);
3514 ``['unmentionable-expression-template-type]`` rint (const ``['number-or-expression-template-type]``&);
3515 ``['unmentionable-expression-template-type]`` round (const ``['number-or-expression-template-type]``&);
3516 ``['unmentionable-expression-template-type]`` scalbn (const ``['number-or-expression-template-type]``&, ``['integer-type]``);
3517 ``['unmentionable-expression-template-type]`` scalbln (const ``['number-or-expression-template-type]``&, ``['integer-type]``);
3518 ``['unmentionable-expression-template-type]`` sin (const ``['number-or-expression-template-type]``&);
3519 ``['unmentionable-expression-template-type]`` sinh (const ``['number-or-expression-template-type]``&);
3520 ``['unmentionable-expression-template-type]`` sqrt (const ``['number-or-expression-template-type]``&);
3521 ``['unmentionable-expression-template-type]`` tan (const ``['number-or-expression-template-type]``&);
3522 ``['unmentionable-expression-template-type]`` tanh (const ``['number-or-expression-template-type]``&);
3523 ``['number]`` tgamma (const ``['number-or-expression-template-type]``&);
3524 ``['unmentionable-expression-template-type]`` trunc (const ``['number-or-expression-template-type]``&);
3525
3526 int fpclassify (const ``['number-or-expression-template-type]``&);
3527 bool isfinite (const ``['number-or-expression-template-type]``&);
3528 bool isinf (const ``['number-or-expression-template-type]``&);
3529 bool isnan (const ``['number-or-expression-template-type]``&);
3530 bool isnormal (const ``['number-or-expression-template-type]``&);
3531 int signbit (const ``['number-or-expression-template-type]``&);
3532
3533 bool isgreater (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3534 bool isgreaterequal(const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3535 bool isless (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3536 bool islessequal(const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3537 bool islessgreater(const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3538 bool isunordered(const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3539
3540These functions all behave exactly as their standard library C++11 counterparts do: their argument is either an instance of `number` or
3541an expression template derived from it; If the argument is of type `number<Backend, et_off>` then that is also the return type,
3542otherwise the return type is an expression template unless otherwise stated.
3543
3544The integer type arguments to `ldexp`, `frexp`, `scalbn` and `ilogb` may be either type `int`, or the actual
3545type of the exponent of the number type.
3546
3547There are also some functions implemented for compatibility with the Boost.Math functions of the same name:
3548
3549 ``['unmentionable-expression-template-type]`` itrunc (const ``['number-or-expression-template-type]``&);
3550 ``['unmentionable-expression-template-type]`` ltrunc (const ``['number-or-expression-template-type]``&);
3551 ``['unmentionable-expression-template-type]`` lltrunc(const ``['number-or-expression-template-type]``&);
3552 ``['unmentionable-expression-template-type]`` iround (const ``['number-or-expression-template-type]``&);
3553 ``['number]`` changesign(const ``['number-or-expression-template-type]``&);
3554 ``['number]`` copysign(const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
3555
3556All these functions are normally implemented by the Backend type. However, default versions are provided for Backend types that
3557don't have native support for these functions. Please note however, that this default support requires the precision of the type
3558to be a compile time constant - this means for example that the [gmp] MPF Backend will not work with these functions when that type is
3559used at variable precision.
3560
3561Also note that with the exception of `abs` that these functions can only be used with floating-point Backend types (if any other types
3562such as fixed precision or complex types are added to the library later, then these functions may be extended to support those number types).
3563
3564The precision of these functions is generally determined by the backend implementation. For example the precision
3565of these functions when used with __mpfr_float_backend is determined entirely by [mpfr]. When these functions use our own
3566implementations, the accuracy of the transcendental functions is generally a few epsilon. Note however, that the trigonometrical
3567functions incur the usual accuracy loss when reducing arguments by large multiples of [pi]. Also note that both __mpf_float
3568and __cpp_dec_float have a number of guard digits beyond their stated precision, so the error rates listed for these
3569are in some sense artificially low.
3570
3571The following table shows the error rates we observe for these functions with various backend types, functions not listed
3572here are exact (tested on Win32 with VC++10, MPFR-3.0.0, MPIR-2.1.1):
3573
3574[table
3575[[Function][mpfr_float_50][mpf_float_50][cpp_dec_float_50]]
3576[[sqrt][1eps][0eps][0eps]]
3577[[exp][1eps][0eps][0eps]]
3578[[log][1eps][0eps][0eps]]
3579[[log10][1eps][0eps][0eps]]
3580[[cos][700eps][0eps][0eps]]
3581[[sin][1eps][0eps][0eps]]
3582[[tan][0eps][0eps][0eps]]
3583[[acos][0eps][0eps][0eps]]
3584[[asin][0eps][0eps][0eps]]
3585[[atan][1eps][0eps][0eps]]
3586[[cosh][1045eps[footnote It's likely that the inherent error in the input values to our test cases are to blame here.]][0eps][0eps]]
3587[[sinh][2eps][0eps][0eps]]
3588[[tanh][1eps][0eps][0eps]]
3589[[pow][0eps][4eps][3eps]]
3590[[atan2][1eps][0eps][0eps]]
3591]
3592[h4 Traits Class Support]
3593
3594 template <class T>
3595 struct component_type;
3596
3597If this is a type with multiple components (for example rational or complex types), then this trait has a single member
3598`type` that is the type of those components.
3599
3600 template <class T>
3601 struct number_category;
3602
3603A traits class that inherits from `mpl::int_<N>` where `N` is one of the enumerated values `number_kind_integer`, `number_kind_floating_point`,
3604`number_kind_rational`, `number_kind_fixed_point`, or `number_kind_unknown`. This traits class is specialized for any type that has
3605`std::numeric_limits` support as well as for classes in this library: which means it can be used for generic code that must work
3606with built in arithmetic types as well as multiprecision ones.
3607
3608 template <class T>
3609 struct is_number;
3610
3611A traits class that inherits from `mpl::true_` if T is an instance of `number<>`, otherwise from `mpl::false_`.
3612
3613 template <class T>
3614 struct is_number_expression;
3615
3616A traits class that inherits from `mpl::true_` if T is an expression template type derived from `number<>`, otherwise from `mpl::false_`.
3617
3618
3619
3620[h4 Integer functions]
3621
3622In addition to functioning with types from this library, these functions are also overloaded for built in integer
3623types if you include `<boost/multiprecision/integer.hpp>`. Further, when used with fixed precision types (whether
3624built in integers or multiprecision ones), the functions will promote to a wider type internally when the algorithm
3625requires it. Versions overloaded for built in integer types return that integer type rather than an expression
3626template.
3627
3628 ``['unmentionable-expression-template-type]`` gcd(const ``['number-or-expression-template-type]``& a, const ``['number-or-expression-template-type]``& b);
3629
3630Returns the largest integer `x` that divides both `a` and `b`.
3631
3632 ``['unmentionable-expression-template-type]`` lcm(const ``['number-or-expression-template-type]``& a, const ``['number-or-expression-template-type]``& b);
3633
3634Returns the smallest integer `x` that is divisible by both `a` and `b`.
3635
3636 ``['unmentionable-expression-template-type]`` pow(const ``['number-or-expression-template-type]``& b, unsigned p);
3637
3638Returns ['b[super p]] as an expression template. Note that this function should be used with extreme care as the result can grow so
3639large as to take "effectively forever" to compute, or else simply run the host machine out of memory. This is the one function in
3640this category that is not overloaded for built in integer types, further, it's probably not a good idea to use it with
3641fixed precision `cpp_int`'s either.
3642
3643 ``['unmentionable-expression-template-type]`` powm(const ``['number-or-expression-template-type]``& b, const ``['number-or-expression-template-type]``& p, const ``['number-or-expression-template-type]``& m);
3644
3645Returns ['b[super p] mod m] as an expression template. Fixed precision types are promoted internally to ensure accuracy.
3646
3647 ``['unmentionable-expression-template-type]`` sqrt(const ``['number-or-expression-template-type]``& a);
3648
3649Returns the largest integer `x` such that `x * x < a`.
3650
3651 template <class Backend, expression_template_option ExpressionTemplates>
3652 number<Backend, EXpressionTemplates> sqrt(const ``['number-or-expression-template-type]``& a, number<Backend, EXpressionTemplates>& r);
3653
3654Returns the largest integer `x` such that `x * x < a`, and sets the remainder `r` such that `r = a - x * x`.
3655
3656 template <class Backend, expression_template_option ExpressionTemplates>
3657 void divide_qr(const ``['number-or-expression-template-type]``& x, const ``['number-or-expression-template-type]``& y,
3658 number<Backend, ExpressionTemplates>& q, number<Backend, ExpressionTemplates>& r);
3659
3660Divides x by y and returns both the quotient and remainder. After the call `q = x / y` and `r = x % y`.
3661
3662 template <class Integer>
3663 Integer integer_modulus(const ``['number-or-expression-template-type]``& x, Integer val);
3664
3665Returns the absolute value of `x % val`.
3666
3667 unsigned lsb(const ``['number-or-expression-template-type]``& x);
3668
3669Returns the (zero-based) index of the least significant bit that is set to 1.
3670
3671Throws a `std::range_error` if the argument is <= 0.
3672
3673 unsigned msb(const ``['number-or-expression-template-type]``& x);
3674
3675Returns the (zero-based) index of the most significant bit.
3676
3677Throws a `std::range_error` if the argument is <= 0.
3678
3679 template <class Backend, class ExpressionTemplates>
3680 bool bit_test(const number<Backend, ExpressionTemplates>& val, unsigned index);
3681
3682Returns `true` if the bit at /index/ in /val/ is set.
3683
3684 template <class Backend, class ExpressionTemplates>
3685 number<Backend, ExpressionTemplates>& bit_set(number<Backend, ExpressionTemplates>& val, unsigned index);
3686
3687Sets the bit at /index/ in /val/, and returns /val/.
3688
3689 template <class Backend, class ExpressionTemplates>
3690 number<Backend, ExpressionTemplates>& bit_unset(number<Backend, ExpressionTemplates>& val, unsigned index);
3691
3692Unsets the bit at /index/ in /val/, and returns /val/.
3693
3694 template <class Backend, class ExpressionTemplates>
3695 number<Backend, ExpressionTemplates>& bit_flip(number<Backend, ExpressionTemplates>& val, unsigned index);
3696
3697Flips the bit at /index/ in /val/, and returns /val/.
3698
3699 template <class Engine>
3700 bool miller_rabin_test(const ``['number-or-expression-template-type]``& n, unsigned trials, Engine& gen);
3701 bool miller_rabin_test(const ``['number-or-expression-template-type]``& n, unsigned trials);
3702
3703Tests to see if the number /n/ is probably prime - the test excludes the vast majority of composite numbers
3704by excluding small prime factors and performing a single Fermat test. Then performs /trials/ Miller-Rabin
3705tests. Returns `false` if /n/ is definitely composite, or `true` if /n/ is probably prime with the
3706probability of it being composite less than 0.25^trials. Fixed precision types are promoted internally
3707to ensure accuracy.
3708
3709[h4 Rational Number Functions]
3710
3711 typename component_type<``['number-or-expression-template-type]``>::type numerator (const ``['number-or-expression-template-type]``&);
3712 typename component_type<``['number-or-expression-template-type]``>::type denominator(const ``['number-or-expression-template-type]``&);
3713
3714These functions return the numerator and denominator of a rational number respectively.
3715
3716[h4 Boost.Math Interoperability Support]
3717
3718 namespace boost{ namespace math{
3719
3720 int fpclassify (const ``['number-or-expression-template-type]``&, int);
3721 bool isfinite (const ``['number-or-expression-template-type]``&, int);
3722 bool isnan (const ``['number-or-expression-template-type]``&, int);
3723 bool isinf (const ``['number-or-expression-template-type]``&, int);
3724 bool isnormal (const ``['number-or-expression-template-type]``&, int);
3725
3726 }} // namespaces
3727
3728These floating-point classification functions behave exactly as their Boost.Math equivalents.
3729
3730Other Boost.Math functions and templates may also be
3731specialized or overloaded to ensure interoperability.
3732
3733[h4 std::numeric_limits support]
3734
3735 namespace std{
3736
3737 template <class Backend, ExpressionTemplates>
3738 struct numeric_limits<boost::multiprecision<Backend, ExpressionTemplates> >
3739 {
3740 /* Usual members here */
3741 };
3742
3743 }
3744
3745Class template `std::numeric_limits` is specialized for all instantiations of `number` whose precision is known at compile time, plus those
3746types whose precision is unlimited (though it is much less useful in those cases). It is not specialized for types
3747whose precision can vary at compile time (such as `mpf_float`).
3748
3749[endsect]
3750
3751[section:cpp_int_ref cpp_int]
3752
3753 namespace boost{ namespace multiprecision{
3754
3755 typedef unspecified-type limb_type;
3756
3757 enum cpp_integer_type { signed_magnitude, unsigned_magnitude };
3758 enum cpp_int_check_type { checked, unchecked };
3759
3760 template <unsigned MinDigits = 0,
3761 unsigned MaxDits = 0,
3762 cpp_integer_type SignType = signed_magnitude,
3763 cpp_int_check_type Checked = unchecked,
3764 class Allocator = std::allocator<limb_type> >
3765 class cpp_int_backend;
3766 //
3767 // Expression templates default to et_off if there is no allocator:
3768 //
3769 template <unsigned MinDigits, unsigned MaxDigits, cpp_integer_type SignType, cpp_int_check_type Checked>
3770 struct expression_template_default<cpp_int_backend<MinDigits, MaxDigits, SignType, Checked, void> >
3771 { static const expression_template_option value = et_off; };
3772
3773 typedef number<cpp_int_backend<> > cpp_int; // arbitrary precision integer
3774 typedef rational_adaptor<cpp_int_backend<> > cpp_rational_backend;
3775 typedef number<cpp_rational_backend> cpp_rational; // arbitrary precision rational number
3776
3777 // Fixed precision unsigned types:
3778 typedef number<cpp_int_backend<128, 128, unsigned_magnitude, unchecked, void> > uint128_t;
3779 typedef number<cpp_int_backend<256, 256, unsigned_magnitude, unchecked, void> > uint256_t;
3780 typedef number<cpp_int_backend<512, 512, unsigned_magnitude, unchecked, void> > uint512_t;
3781 typedef number<cpp_int_backend<1024, 1024, unsigned_magnitude, unchecked, void> > uint1024_t;
3782
3783 // Fixed precision signed types:
3784 typedef number<cpp_int_backend<128, 128, signed_magnitude, unchecked, void> > int128_t;
3785 typedef number<cpp_int_backend<256, 256, signed_magnitude, unchecked, void> > int256_t;
3786 typedef number<cpp_int_backend<512, 512, signed_magnitude, unchecked, void> > int512_t;
3787 typedef number<cpp_int_backend<1024, 1024, signed_magnitude, unchecked, void> > int1024_t;
3788
3789 // Over again, but with checking enabled this time:
3790 typedef number<cpp_int_backend<0, 0, signed_magnitude, checked> > checked_cpp_int;
3791 typedef rational_adaptor<cpp_int_backend<0, 0, signed_magnitude, checked> > checked_cpp_rational_backend;
3792 typedef number<checked_cpp_rational_backend> checked_cpp_rational;
3793
3794 // Checked fixed precision unsigned types:
3795 typedef number<cpp_int_backend<128, 128, unsigned_magnitude, checked, void> > checked_uint128_t;
3796 typedef number<cpp_int_backend<256, 256, unsigned_magnitude, checked, void> > checked_uint256_t;
3797 typedef number<cpp_int_backend<512, 512, unsigned_magnitude, checked, void> > checked_uint512_t;
3798 typedef number<cpp_int_backend<1024, 1024, unsigned_magnitude, checked, void> > checked_uint1024_t;
3799
3800 // Fixed precision signed types:
3801 typedef number<cpp_int_backend<128, 128, signed_magnitude, checked, void> > checked_int128_t;
3802 typedef number<cpp_int_backend<256, 256, signed_magnitude, checked, void> > checked_int256_t;
3803 typedef number<cpp_int_backend<512, 512, signed_magnitude, checked, void> > checked_int512_t;
3804 typedef number<cpp_int_backend<1024, 1024, signed_magnitude, checked, void> > checked_int1024_t;
3805
3806 }} // namespaces
3807
3808Class template `cpp_int_backend` fulfils all of the requirements for a [link boost_multiprecision.ref.backendconc Backend] type.
3809Its members and non-member functions are deliberately not documented: these are considered implementation details that are subject
3810to change.
3811
3812The template arguments are:
3813
3814[variablelist
3815[[MinBits][Determines the number of Bits to store directly within the object before resorting to dynamic memory
3816 allocation. When zero, this field is determined automatically based on how many bits can be stored
3817 in union with the dynamic storage header: setting a larger value may improve performance as larger integer
3818 values will be stored internally before memory allocation is required.]]
3819[[MaxBits][Determines the maximum number of bits to be stored in the type: resulting in a fixed precision type.
3820 When this value is the same as MinBits, then the Allocator parameter is ignored, as no dynamic
3821 memory allocation will ever be performed: in this situation the Allocator parameter should be set to
3822 type `void`. Note that this parameter should not be used simply to prevent large memory
3823 allocations, not only is that role better performed by the allocator, but fixed precision
3824 integers have a tendency to allocate all of MaxBits of storage more often than one would expect.]]
3825[[SignType][Determines whether the resulting type is signed or not. Note that for
3826[@http://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic arbitrary precision] types
3827 this parameter must be `signed_magnitude`. For fixed precision
3828 types then this type may be either `signed_magnitude` or `unsigned_magnitude`.]]
3829[[Checked][This parameter has two values: `checked` or `unchecked`. See the [link boost_multiprecision.tut.ints.cpp_int tutorial] for more information.]]
3830[[Allocator][The allocator to use for dynamic memory allocation, or type `void` if MaxBits == MinBits.]]
3831]
3832
3833The type of `number_category<cpp_int<Args...> >::type` is `mpl::int_<number_kind_integer>`.
3834
3835More information on this type can be found in the [link boost_multiprecision.tut.ints.cpp_int tutorial].
3836
3837[endsect]
3838
3839[section:gmp_int_ref gmp_int]
3840
3841 namespace boost{ namespace multiprecision{
3842
3843 class gmp_int;
3844
3845 typedef number<gmp_int > mpz_int;
3846
3847 }} // namespaces
3848
3849Class template `gmp_int` fulfils all of the requirements for a [link boost_multiprecision.ref.backendconc Backend] type.
3850Its members and non-member functions are deliberately not documented: these are considered implementation details that are subject
3851to change.
3852
3853The type of `number_category<cpp_int<Args...> >::type` is `mpl::int_<number_kind_integer>`.
3854
3855More information on this type can be found in the [link boost_multiprecision.tut.ints.gmp_int tutorial].
3856
3857[endsect]
3858
3859[section:tom_int_ref tom_int]
3860
3861 namespace boost{ namespace multiprecision{
3862
3863 class tommath_int;
3864
3865 typedef number<tommath_int > tom_int;
3866
3867 }} // namespaces
3868
3869Class template `tommath_int` fulfils all of the requirements for a [link boost_multiprecision.ref.backendconc Backend] type.
3870Its members and non-member functions are deliberately not documented: these are considered implementation details that are subject
3871to change.
3872
3873The type of `number_category<cpp_int<Args...> >::type` is `mpl::int_<number_kind_integer>`.
3874
3875More information on this type can be found in the [link boost_multiprecision.tut.ints.tom_int tutorial].
3876
3877[endsect]
3878
3879[section:mpf_ref gmp_float]
3880
3881 namespace boost{ namespace multiprecision{
3882
3883 template <unsigned Digits10>
3884 class gmp_float;
3885
3886 typedef number<gmp_float<50> > mpf_float_50;
3887 typedef number<gmp_float<100> > mpf_float_100;
3888 typedef number<gmp_float<500> > mpf_float_500;
3889 typedef number<gmp_float<1000> > mpf_float_1000;
3890 typedef number<gmp_float<0> > mpf_float;
3891
3892 }} // namespaces
3893
3894Class template `gmp_float` fulfils all of the requirements for a [link boost_multiprecision.ref.backendconc Backend] type.
3895Its members and non-member functions are deliberately not documented: these are considered implementation details that are subject
3896to change.
3897
3898The class takes a single template parameter - `Digits10` - which is the number of decimal digits precision the type
3899should support. When this parameter is zero, then the precision can be set at runtime via `number::default_precision`
3900and `number::precision`. Note that this type does not in any way change the GMP library's global state (for example
3901it does not change the default precision of the mpf_t data type), therefore you can safely mix this type with existing
3902code that uses GMP, and also mix `gmp_float`s of differing precision.
3903
3904The type of `number_category<cpp_int<Args...> >::type` is `mpl::int_<number_kind_floating_point>`.
3905
3906More information on this type can be found in the [link boost_multiprecision.tut.floats.gmp_float tutorial].
3907
3908[endsect]
3909
3910[section:mpfr_ref mpfr_float_backend]
3911
3912 namespace boost{ namespace multiprecision{
3913
3914 template <unsigned Digits10>
3915 class mpfr_float_backend;
3916
3917 typedef number<mpfr_float_backend<50> > mpfr_float_50;
3918 typedef number<mpfr_float_backend<100> > mpfr_float_100;
3919 typedef number<mpfr_float_backend<500> > mpfr_float_500;
3920 typedef number<mpfr_float_backend<1000> > mpfr_float_1000;
3921 typedef number<mpfr_float_backend<0> > mpfr_float;
3922
3923 }} // namespaces
3924
3925Class template `mpfr_float_backend` fulfils all of the requirements for a [link boost_multiprecision.ref.backendconc Backend] type.
3926Its members and non-member functions are deliberately not documented: these are considered implementation details that are subject
3927to change.
3928
3929The class takes a single template parameter - `Digits10` - which is the number of decimal digits precision the type
3930should support. When this parameter is zero, then the precision can be set at runtime via `number::default_precision`
3931and `number::precision`. Note that this type does not in any way change the GMP or MPFR library's global state (for example
3932it does not change the default precision of the mpfr_t data type), therefore you can safely mix this type with existing
3933code that uses GMP or MPFR, and also mix `mpfr_float_backend`s of differing precision.
3934
3935The type of `number_category<cpp_int<Args...> >::type` is `mpl::int_<number_kind_floating_point>`.
3936
3937More information on this type can be found in the [link boost_multiprecision.tut.floats.mpfr_float tutorial].
3938
3939[endsect]
3940
3941[section:cpp_bin_float_ref cpp_bin_float]
3942
3943 namespace boost{ namespace multiprecision{
3944
3945 enum digit_base_type
3946 {
3947 digit_base_2 = 2,
3948 digit_base_10 = 10
3949 };
3950
3951 template <unsigned Digits, digit_base_type base = digit_base_10, class Allocator = void, class Exponent = int, ExponentMin = 0, ExponentMax = 0>
3952 class cpp_bin_float;
3953
3954 typedef number<cpp_bin_float<50> > cpp_bin_float_50;
3955 typedef number<cpp_bin_float<100> > cpp_bin_float_100;
3956
3957 typedef number<backends::cpp_bin_float<24, backends::digit_base_2, void, boost::int16_t, -126, 127>, et_off> cpp_bin_float_single;
3958 typedef number<backends::cpp_bin_float<53, backends::digit_base_2, void, boost::int16_t, -1022, 1023>, et_off> cpp_bin_float_double;
3959 typedef number<backends::cpp_bin_float<64, backends::digit_base_2, void, boost::int16_t, -16382, 16383>, et_off> cpp_bin_float_double_extended;
3960 typedef number<backends::cpp_bin_float<113, backends::digit_base_2, void, boost::int16_t, -16382, 16383>, et_off> cpp_bin_float_quad;
3961
3962 }} // namespaces
3963
3964Class template `cpp_bin_float` fulfils all of the requirements for a [link boost_multiprecision.ref.backendconc Backend] type.
3965Its members and non-member functions are deliberately not documented: these are considered implementation details that are subject
3966to change.
3967
3968The class takes six template parameters:
3969
3970[variablelist
3971[[Digits][The number of digits precision the type
3972should support. This is normally expressed as base-10 digits, but that can be changed via the second template parameter.]]
3973[[base][An enumerated value (either `digit_base_10` or `digit_base_2`) that indicates whether `Digits` is base-10 or base-2]]
3974[[Allocator][The allocator used: defaults to type `void`, meaning all storage is within the class, and no dynamic
3975allocation is performed, but can be set to a standard library allocator if dynamic allocation makes more sense.]]
3976[[Exponent][A signed integer type to use as the type of the exponent - defaults to `int`.]]
3977[[ExponentMin][The smallest (most negative) permitted exponent, defaults to zero, meaning "define as small as possible
3978given the limitations of the type and our internal requirements".]]
3979[[ExponentMax][The largest (most positive) permitted exponent, defaults to zero, meaning "define as large as possible
3980given the limitations of the type and our internal requirements".]]
3981]
3982
3983The type of `number_category<cpp_bin_float<Args...> >::type` is `mpl::int_<number_kind_floating_point>`.
3984
3985More information on this type can be found in the [link boost_multiprecision.tut.floats.cpp_bin_float tutorial].
3986
3987[h4 Implementation Notes]
3988
3989Internally, an N-bit `cpp_bin_float` is represented as an N-bit unsigned integer along with an exponent and a sign.
3990The integer part is normalized so that it's most significant bit is always 1. The decimal point is assumed to be
3991directly after the most significant bit of the integer part. The special values zero, infinity and NaN all have
3992the integer part set to zero, and the exponent to one of 3 special values above the maximum permitted exponent.
3993
3994Multiplication is trivial: multiply the two N-bit integer mantissa's to obtain a 2N-bit number, then round and
3995adjust the sign and exponent.
3996
3997Addition and subtraction proceed similarly - if the exponents are such that there is overlap between the two
3998values, then left shift the larger value to produce a number with between N and 2N bits, then perform integer
3999addition or subtraction, round, and adjust the exponent.
4000
4001Division proceeds as follows: first scale the numerator by some power of 2 so that integer division will
4002produce either an N-bit or N+1 bit result plus a remainder. If we get an N bit result then the size of
4003twice the remainder compared to the denominator gives us the rounding direction. Otherwise we have one extra bit
4004in the result which we can use to determine rounding (in this case ties occur only if the remainder is zero and
4005the extra bit is a 1).
4006
4007Square root uses integer square root in a manner analogous to division.
4008
4009Decimal string to binary conversion proceeds as follows: first parse the digits to
4010produce an integer multiplied by a decimal exponent. Note that we stop parsing digits
4011once we have parsed as many as can possibly effect the result - this stops the integer
4012part growing too large when there are a very large number of input digits provided.
4013At this stage if the decimal exponent is positive then the result is an integer and we
4014can in principle simply multiply by 10^N to get an exact integer result. In practice
4015however, that could produce some very large integers. We also need to be able to divide
4016by 10^N in the event that the exponent is negative. Therefore calculation of the 10^N
4017values plus the multiplication or division are performed using limited precision
4018integer arithmetic, plus an exponent, and a track of the accumulated error. At the end of
4019the calculation we will either be able to round unambiguously, or the error will be such
4020that we can't tell which way to round. In the latter case we simply up the precision and try
4021again until we have an unambiguously rounded result.
4022
4023Binary to decimal conversion proceeds very similarly to the above, our aim is to calculate
4024`mantissa * 2^shift * 10^E` where `E` is the decimal exponent and `shift` is calculated
4025so that the result is an N bit integer assuming we want N digits printed in the result.
4026As before we use limited precision arithmetic to calculate the result and up the
4027precision as necessary until the result is unambiguously correctly rounded. In addition
4028our initial calculation of the decimal exponent may be out by 1, so we have to correct
4029that and loop as well in the that case.
4030
4031[endsect]
4032
4033[section:cpp_dec_ref cpp_dec_float]
4034
4035 namespace boost{ namespace multiprecision{
4036
4037 template <unsigned Digits10, class ExponentType = boost::int32_t, class Allocator = void>
4038 class cpp_dec_float;
4039
4040 typedef number<cpp_dec_float<50> > cpp_dec_float_50;
4041 typedef number<cpp_dec_float<100> > cpp_dec_float_100;
4042
4043 }} // namespaces
4044
4045Class template `cpp_dec_float` fulfils all of the requirements for a [link boost_multiprecision.ref.backendconc Backend] type.
4046Its members and non-member functions are deliberately not documented: these are considered implementation details that are subject
4047to change.
4048
4049The class takes three template parameters:
4050
4051[variablelist
4052[[Digits10][The number of decimal digits precision the type
4053should support. Note that this type does not normally perform any dynamic memory allocation, and as a result the `Digits10`
4054template argument should not be set too high or the class's size will grow unreasonably large.]]
4055[[ExponentType][A signed integer type that represents the exponent of the number]]
4056[[Allocator][The allocator used: defaults to type `void`, meaning all storage is within the class, and no dynamic
4057allocation is performed, but can be set to a standard library allocator if dynamic allocation makes more sense.]]
4058]
4059
4060The type of `number_category<cpp_dec_float<Args...> >::type` is `mpl::int_<number_kind_floating_point>`.
4061
4062More information on this type can be found in the [link boost_multiprecision.tut.floats.cpp_dec_float tutorial].
4063
4064[endsect]
4065
4066[section:internals Internal Support Code]
4067
4068There are some traits classes which authors of new backends should be aware of:
4069
4070 namespace boost{ namespace multiprecision{ namespace detail{
4071
4072 template<typename From, typename To>
4073 struct is_explicitly_convertible;
4074
4075 }}}
4076
4077Inherits from `boost::integral_constant<bool,true>` if type `From` has an explicit conversion from `To`.
4078
4079For compilers that support C++11 SFINAE-expressions this trait should "just work". Otherwise it inherits
4080from `boost::is_convertible<From, To>::type`, and will need to be specialised for Backends that have
4081constructors marked as `explicit`.
4082
4083 template <class From, class To>
4084 struct is_lossy_conversion
4085 {
4086 static const bool value = see below;
4087 };
4088
4089Member `value` is true if the conversion from `From` to `To` would result in a loss of precision, and `false` otherwise.
4090
4091The default version of this trait simply checks whether the ['kind] of conversion (for example from a floating-point to an integer type)
4092is inherently lossy. Note that if either of the types `From` or `To` are of an unknown number category (because `number_category` is not
4093specialised for that type) then this trait will be `true`.
4094
4095 template<typename From, typename To>
4096 struct is_restricted_conversion
4097 {
4098 static const bool value = see below;
4099 };
4100
4101Member `value` is `true` if `From` is only explicitly convertible to `To` and not implicitly convertible, or
4102if `is_lossy_conversion<From, To>::value` is `true`. Otherwise `false`.
4103
4104Note that while this trait is the ultimate arbiter of which constructors are marked as `explicit` in class `number`,
4105authors of backend types should generally specialise one of the traits above, rather than this one directly.
4106
4107 template <class T>
4108 is_signed_number;
4109 template <class T>
4110 is_unsigned_number;
4111
4112These two traits inherit from either `mpl::true_` or `mpl::false_`, by default types are assumed to be signed unless
4113`is_unsigned_number` is specialized for that type.
4114
4115[endsect]
4116
4117[section:backendconc Backend Requirements]
4118
4119The requirements on the `Backend` template argument to `number` are split up into
4120sections: compulsory and optional.
4121
4122Compulsory requirements have no default implementation in the library, therefore if the feature
4123they implement is to be supported at all, then they must be implemented by the backend.
4124
4125Optional requirements have default implementations that are called if the backend doesn't provide
4126it's own. Typically the backend will implement these to improve performance.
4127
4128In the following tables, type B is the `Backend` template argument to `number`, `b` and `b2` are
4129a variables of type B, `pb` is a variable of type B*, `cb`, `cb2` and `cb3` are constant variables of type `const B`,
4130`rb` is a variable of type `B&&`, `a` and `a2` are variables of Arithmetic type,
4131`s` is a variable of type `const char*`, `ui` is a variable of type `unsigned`, `bb` is a variable of type `bool`,
4132`pa` is a variable of type pointer-to-arithmetic-type, `exp` is a variable of type `B::exp_type`,
4133`pexp` is a variable of type `B::exp_type*`, `i` is a variable of type `int`, `pi` pointer to a variable of type `int`,
4134B2 is another type that meets these requirements, b2 is a variable of type B2, `ss` is variable of type `std::streamsize`
4135and `ff` is a variable of type `std::ios_base::fmtflags`.
4136
4137[table Compulsory Requirements on the Backend type.
4138[[Expression][Return Type][Comments][Throws]]
4139[[`B::signed_types`][`mpl::list<type-list>`][A list of signed integral types that can be assigned to type B. The types shall be
4140 listed in order of size, smallest first, and shall terminate in the type that is `std::intmax_t`.][[space]]]
4141[[`B::unsigned_types`][`mpl::list<type-list>`][A list of unsigned integral types that can be assigned to type B. The types shall be
4142 listed in order of size, smallest first, and shall terminate in the type that is `std::uintmax_t`.][[space]]]
4143[[`B::float_types`][`mpl::list<type-list>`][A list of floating-point types that can be assigned to type B.The types shall be
4144 listed in order of size, smallest first, and shall terminate in type `long double`.][[space]]]
4145[[`B::exponent_type`][A signed integral type.][The type of the exponent of type B. This type is required only for floating-point types.][[space]]]
4146[[`B()`][ ][Default constructor.][[space]]]
4147[[`B(cb)`][ ][Copy Constructor.][[space]]]
4148[[`b = b`][`B&`][Assignment operator.][[space]]]
4149[[`b = a`][`B&`][Assignment from an Arithmetic type. The type of `a` shall be listed in one of the type lists
4150 `B::signed_types`, `B::unsigned_types` or `B::float_types`.][[space]]]
4151[[`b = s`][`B&`][Assignment from a string.][Throws a `std::runtime_error` if the string could not be interpreted as a valid number.]]
4152[[`b.swap(b)`][`void`][Swaps the contents of its arguments.][`noexcept`]]
4153[[`cb.str(ss, ff)`][`std::string`][Returns the string representation of `b` with `ss` digits and formatted according to the flags set in `ff`.
4154 If `ss` is zero, then returns as many digits as are required to reconstruct the original value.][[space]]]
4155[[`b.negate()`][`void`][Negates `b`.][[space]]]
4156[[`cb.compare(cb2)`][`int`][Compares `cb` and `cb2`, returns a value less than zero if `cb < cb2`, a value greater than zero if `cb > cb2` and zero
4157 if `cb == cb2`.][`noexcept`]]
4158[[`cb.compare(a)`][`int`][Compares `cb` and `a`, returns a value less than zero if `cb < a`, a value greater than zero if `cb > a` and zero
4159 if `cb == a`. The type of `a` shall be listed in one of the type lists
4160 `B::signed_types`, `B::unsigned_types` or `B::float_types`.][[space]]]
4161[[`eval_add(b, cb)`][`void`][Adds `cb` to `b`.][[space]]]
4162[[`eval_subtract(b, cb)`][`void`][Subtracts `cb` from `b`.][[space]]]
4163[[`eval_multiply(b, cb)`][`void`][Multiplies `b` by `cb`.][[space]]]
4164[[`eval_divide(b, cb)`][`void`][Divides `b` by `cb`.]
4165 [`std::overflow_error` if cb has the value zero, and `std::numeric_limits<number<B> >::has_infinity == false`]]
4166[[`eval_modulus(b, cb)`][`void`][Computes `b %= cb`, only required when `B` is an integer type.]
4167 [`std::overflow_error` if cb has the value zero.]]
4168[[`eval_bitwise_and(b, cb)`][`void`][Computes `b &= cb`, only required when `B` is an integer type.][[space]]]
4169[[`eval_bitwise_or(b, cb)`][`void`][Computes `b |= cb`, only required when `B` is an integer type.][[space]]]
4170[[`eval_bitwise_xor(b, cb)`][`void`][Computes `b ^= cb`, only required when `B` is an integer type.][[space]]]
4171[[`eval_complement(b, cb)`][`void`][Computes the ones-complement of `cb` and stores the result in `b`, only required when `B` is an integer type.][[space]]]
4172[[`eval_left_shift(b, ui)`][`void`][Computes `b <<= ui`, only required when `B` is an integer type.][[space]]]
4173[[`eval_right_shift(b, ui)`][`void`][Computes `b >>= ui`, only required when `B` is an integer type.][[space]]]
4174[[`eval_convert_to(pa, cb)`][`void`][Converts `cb` to the type of `*pa` and store the result in `*pa`. Type `B` shall support
4175 conversion to at least types `std::intmax_t`, `std::uintmax_t` and `long long`.
4176 Conversion to other arithmetic types can then be synthesised using other operations.
4177 Conversions to other types are entirely optional.][[space]]]
4178[[`eval_frexp(b, cb, pexp)`][`void`][Stores values in `b` and `*pexp` such that the value of `cb` is b * 2[super *pexp], only required when `B` is a floating-point type.][[space]]]
4179[[`eval_ldexp(b, cb, exp)`][`void`][Stores a value in `b` that is cb * 2[super exp], only required when `B` is a floating-point type.][[space]]]
4180[[`eval_frexp(b, cb, pi)`][`void`][Stores values in `b` and `*pi` such that the value of `cb` is b * 2[super *pi], only required when `B` is a floating-point type.]
4181 [`std::runtime_error` if the exponent of cb is too large to be stored in an `int`.]]
4182[[`eval_ldexp(b, cb, i)`][`void`][Stores a value in `b` that is cb * 2[super i], only required when `B` is a floating-point type.][[space]]]
4183[[`eval_floor(b, cb)`][`void`][Stores the floor of `cb` in `b`, only required when `B` is a floating-point type.][[space]]]
4184[[`eval_ceil(b, cb)`][`void`][Stores the ceiling of `cb` in `b`, only required when `B` is a floating-point type.][[space]]]
4185[[`eval_sqrt(b, cb)`][`void`][Stores the square root of `cb` in `b`, only required when `B` is a floating-point type.][[space]]]
4186[[`boost::multiprecision::number_category<B>::type`][`mpl::int_<N>`][`N` is one of the values `number_kind_integer`, `number_kind_floating_point`, `number_kind_rational` or `number_kind_fixed_point`.
4187 Defaults to `number_kind_floating_point`.][[space]]]
4188]
4189
4190[table Optional Requirements on the Backend Type
4191[[Expression][Returns][Comments][Throws]]
4192
4193[[['Construct and assign:]]]
4194[[`B(rb)`][`B`][Move constructor. Afterwards variable `rb` shall be in sane state, albeit with unspecified value.
4195 Only destruction and assignment to the moved-from variable `rb` need be supported after the operation.][`noexcept`]]
4196[[`b = rb`][`B&`][Move-assign. Afterwards variable `rb` shall be in sane state, albeit with unspecified value.
4197 Only destruction and assignment to the moved-from variable `rb` need be supported after the operation.][`noexcept`]]
4198[[`B(a)`][`B`][Direct construction from an arithmetic type. The type of `a` shall be listed in one of the type lists
4199 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4200 When not provided, this operation is simulated using default-construction followed by assignment.][[space]]]
4201[[`B(b2)`][`B`][Copy constructor from a different back-end type. When not provided, a generic interconversion routine is used.
4202 This constructor may be `explicit` if the corresponding frontend constructor should also be `explicit`.][[space]]]
4203[[`b = b2`][`b&`][Assignment operator from a different back-end type. When not provided, a generic interconversion routine is used.][[space]]]
4204[[`assign_components(b, a, a)`][`void`][Assigns to `b` the two components in the following arguments.
4205 Only applies to rational and complex number types.
4206 When not provided, arithmetic operations are used to synthesise the result from the two values.][[space]]]
4207[[`assign_components(b, b2, b2)`][`void`][Assigns to `b` the two components in the following arguments.
4208 Only applies to rational and complex number types.
4209 When not provided, arithmetic operations are used to synthesise the result from the two values.][[space]]]
4210
4211[[['Comparisons:]]]
4212[[`eval_eq(cb, cb2)`][`bool`][Returns `true` if `cb` and `cb2` are equal in value.
4213 When not provided, the default implementation returns `cb.compare(cb2) == 0`.][`noexcept`]]
4214[[`eval_eq(cb, a)`][`bool`][Returns `true` if `cb` and `a` are equal in value.
4215 The type of `a` shall be listed in one of the type lists
4216 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4217 When not provided, return the equivalent of `eval_eq(cb, B(a))`.][[space]]]
4218[[`eval_eq(a, cb)`][`bool`][Returns `true` if `cb` and `a` are equal in value.
4219 The type of `a` shall be listed in one of the type lists
4220 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4221 When not provided, the default version returns `eval_eq(cb, a)`.][[space]]]
4222[[`eval_lt(cb, cb2)`][`bool`][Returns `true` if `cb` is less than `cb2` in value.
4223 When not provided, the default implementation returns `cb.compare(cb2) < 0`.][`noexcept`]]
4224[[`eval_lt(cb, a)`][`bool`][Returns `true` if `cb` is less than `a` in value.
4225 The type of `a` shall be listed in one of the type lists
4226 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4227 When not provided, the default implementation returns `eval_lt(cb, B(a))`.][[space]]]
4228[[`eval_lt(a, cb)`][`bool`][Returns `true` if `a` is less than `cb` in value.
4229 The type of `a` shall be listed in one of the type lists
4230 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4231 When not provided, the default implementation returns `eval_gt(cb, a)`.][[space]]]
4232[[`eval_gt(cb, cb2)`][`bool`][Returns `true` if `cb` is greater than `cb2` in value.
4233 When not provided, the default implementation returns `cb.compare(cb2) > 0`.][`noexcept`]]
4234[[`eval_gt(cb, a)`][`bool`][Returns `true` if `cb` is greater than `a` in value.
4235 The type of `a` shall be listed in one of the type lists
4236 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4237 When not provided, the default implementation returns `eval_gt(cb, B(a))`.][[space]]]
4238[[`eval_gt(a, cb)`][`bool`][Returns `true` if `a` is greater than `cb` in value.
4239 The type of `a` shall be listed in one of the type lists
4240 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4241 When not provided, the default implementation returns `eval_lt(cb, a)`.][[space]]]
4242[[`eval_is_zero(cb)`][`bool`][Returns `true` if `cb` is zero, otherwise `false`. The default version of this function
4243 returns `cb.compare(ui_type(0)) == 0`, where `ui_type` is `ui_type` is
4244 `typename mpl::front<typename B::unsigned_types>::type`.][[space]]]
4245[[`eval_get_sign(cb)`][`int`][Returns a value < zero if `cb` is negative, a value > zero if `cb` is positive, and zero if `cb` is zero.
4246 The default version of this function
4247 returns `cb.compare(ui_type(0))`, where `ui_type` is `ui_type` is
4248 `typename mpl::front<typename B::unsigned_types>::type`.][[space]]]
4249
4250[[['Basic arithmetic:]]]
4251[[`eval_add(b, a)`][`void`][Adds `a` to `b`. The type of `a` shall be listed in one of the type lists
4252 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4253 When not provided, the default version calls `eval_add(b, B(a))`][[space]]]
4254[[`eval_add(b, cb, cb2)`][`void`][Add `cb` to `cb2` and stores the result in `b`.
4255 When not provided, does the equivalent of `b = cb; eval_add(b, cb2)`.][[space]]]
4256[[`eval_add(b, cb, a)`][`void`][Add `cb` to `a` and stores the result in `b`. The type of `a` shall be listed in one of the type lists
4257 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4258 When not provided, does the equivalent of `eval_add(b, cb, B(a))`.][[space]]]
4259[[`eval_add(b, a, cb)`][`void`][Add `a` to `cb` and stores the result in `b`. The type of `a` shall be listed in one of the type lists
4260 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4261 When not provided, does the equivalent of `eval_add(b, cb, a)`.][[space]]]
4262[[`eval_subtract(b, a)`][`void`][Subtracts `a` from `b`. The type of `a` shall be listed in one of the type lists
4263 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4264 When not provided, the default version calls `eval_subtract(b, B(a))`][[space]]]
4265[[`eval_subtract(b, cb, cb2)`][`void`][Subtracts `cb2` from `cb` and stores the result in `b`.
4266 When not provided, does the equivalent of `b = cb; eval_subtract(b, cb2)`.][[space]]]
4267[[`eval_subtract(b, cb, a)`][`void`][Subtracts `a` from `cb` and stores the result in `b`. The type of `a` shall be listed in one of the type lists
4268 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4269 When not provided, does the equivalent of `eval_subtract(b, cb, B(a))`.][[space]]]
4270[[`eval_subtract(b, a, cb)`][`void`][Subtracts `cb` from `a` and stores the result in `b`. The type of `a` shall be listed in one of the type lists
4271 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4272 When not provided, does the equivalent of `eval_subtract(b, cb, a); b.negate();`.][[space]]]
4273[[`eval_multiply(b, a)`][`void`][Multiplies `b` by `a`. The type of `a` shall be listed in one of the type lists
4274 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4275 When not provided, the default version calls `eval_multiply(b, B(a))`][[space]]]
4276[[`eval_multiply(b, cb, cb2)`][`void`][Multiplies `cb` by `cb2` and stores the result in `b`.
4277 When not provided, does the equivalent of `b = cb; eval_multiply(b, cb2)`.][[space]]]
4278[[`eval_multiply(b, cb, a)`][`void`][Multiplies `cb` by `a` and stores the result in `b`. The type of `a` shall be listed in one of the type lists
4279 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4280 When not provided, does the equivalent of `eval_multiply(b, cb, B(a))`.][[space]]]
4281[[`eval_multiply(b, a, cb)`][`void`][Multiplies `a` by `cb` and stores the result in `b`. The type of `a` shall be listed in one of the type lists
4282 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4283 When not provided, does the equivalent of `eval_multiply(b, cb, a)`.][[space]]]
4284[[`eval_multiply_add(b, cb, cb2)`][`void`][Multiplies `cb` by `cb2` and adds the result to `b`.
4285 When not provided does the equivalent of creating a temporary `B t` and `eval_multiply(t, cb, cb2)` followed by
4286 `eval_add(b, t)`.][[space]]]
4287[[`eval_multiply_add(b, cb, a)`][`void`][Multiplies `a` by `cb` and adds the result to `b`.
4288 The type of `a` shall be listed in one of the type lists
4289 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4290 When not provided does the equivalent of creating a temporary `B t` and `eval_multiply(t, cb, a)` followed by
4291 `eval_add(b, t)`.][[space]]]
4292[[`eval_multiply_add(b, a, cb)`][`void`][Multiplies `a` by `cb` and adds the result to `b`.
4293 The type of `a` shall be listed in one of the type lists
4294 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4295 When not provided does the equivalent of `eval_multiply_add(b, cb, a)`.][[space]]]
4296[[`eval_multiply_subtract(b, cb, cb2)`][`void`][Multiplies `cb` by `cb2` and subtracts the result from `b`.
4297 When not provided does the equivalent of creating a temporary `B t` and `eval_multiply(t, cb, cb2)` followed by
4298 `eval_subtract(b, t)`.][[space]]]
4299[[`eval_multiply_subtract(b, cb, a)`][`void`][Multiplies `a` by `cb` and subtracts the result from `b`.
4300 The type of `a` shall be listed in one of the type lists
4301 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4302 When not provided does the equivalent of creating a temporary `B t` and `eval_multiply(t, cb, a)` followed by
4303 `eval_subtract(b, t)`.][[space]]]
4304[[`eval_multiply_subtract(b, a, cb)`][`void`][Multiplies `a` by `cb` and subtracts the result from `b`.
4305 The type of `a` shall be listed in one of the type lists
4306 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4307 When not provided does the equivalent of `eval_multiply_subtract(b, cb, a)`.][[space]]]
4308[[`eval_multiply_add(b, cb, cb2, cb3)`][`void`][Multiplies `cb` by `cb2` and adds the result to `cb3` storing the result in `b`.
4309 When not provided does the equivalent of `eval_multiply(b, cb, cb2)` followed by
4310 `eval_add(b, cb3)`.
4311 For brevity, only a version showing all arguments of type `B` is shown here, but you can replace up to any 2 of
4312 `cb`, `cb2` and `cb3` with any type listed in one of the type lists
4313 `B::signed_types`, `B::unsigned_types` or `B::float_types`.][[space]]]
4314[[`eval_multiply_subtract(b, cb, cb2, cb3)`][`void`][Multiplies `cb` by `cb2` and subtracts from the result `cb3` storing the result in `b`.
4315 When not provided does the equivalent of `eval_multiply(b, cb, cb2)` followed by
4316 `eval_subtract(b, cb3)`.
4317 For brevity, only a version showing all arguments of type `B` is shown here, but you can replace up to any 2 of
4318 `cb`, `cb2` and `cb3` with any type listed in one of the type lists
4319 `B::signed_types`, `B::unsigned_types` or `B::float_types`.][[space]]]
4320[[`eval_divide(b, a)`][`void`][Divides `b` by `a`. The type of `a` shall be listed in one of the type lists
4321 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4322 When not provided, the default version calls `eval_divide(b, B(a))`]
4323 [`std::overflow_error` if `a` has the value zero, and `std::numeric_limits<number<B> >::has_infinity == false`]]
4324[[`eval_divide(b, cb, cb2)`][`void`][Divides `cb` by `cb2` and stores the result in `b`.
4325 When not provided, does the equivalent of `b = cb; eval_divide(b, cb2)`.]
4326 [`std::overflow_error` if `cb2` has the value zero, and `std::numeric_limits<number<B> >::has_infinity == false`]]
4327[[`eval_divide(b, cb, a)`][`void`][Divides `cb` by `a` and stores the result in `b`. The type of `a` shall be listed in one of the type lists
4328 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4329 When not provided, does the equivalent of `eval_divide(b, cb, B(a))`.]
4330 [`std::overflow_error` if `a` has the value zero, and `std::numeric_limits<number<B> >::has_infinity == false`]]
4331[[`eval_divide(b, a, cb)`][`void`][Divides `a` by `cb` and stores the result in `b`. The type of `a` shall be listed in one of the type lists
4332 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4333 When not provided, does the equivalent of `eval_divide(b, B(a), cb)`.]
4334 [`std::overflow_error` if cb has the value zero, and `std::numeric_limits<number<B> >::has_infinity == false`]]
4335[[`eval_increment(b)`][void][Increments the value of `b` by one.
4336 When not provided, does the equivalent of `eval_add(b, static_cast<ui_type>(1u))`.
4337 Where `ui_type` is `typename mpl::front<typename B::unsigned_types>::type`.][[space]]]
4338[[`eval_decrement(b)`][void][Decrements the value of `b` by one.
4339 When not provided, does the equivalent of `eval_subtract(b, static_cast<ui_type>(1u))`.
4340 Where `ui_type` is `typename mpl::front<typename B::unsigned_types>::type`.][[space]]]
4341
4342[[['Integer specific operations:]]]
4343[[`eval_modulus(b, a)`][`void`][Computes `b %= cb`, only required when `B` is an integer type. The type of `a` shall be listed in one of the type lists
4344 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4345 When not provided, the default version calls `eval_modulus(b, B(a))`]
4346 [`std::overflow_error` if `a` has the value zero.]]
4347[[`eval_modulus(b, cb, cb2)`][`void`][Computes `cb % cb2` and stores the result in `b`, only required when `B` is an integer type.
4348 When not provided, does the equivalent of `b = cb; eval_modulus(b, cb2)`.]
4349 [`std::overflow_error` if `a` has the value zero.]]
4350[[`eval_modulus(b, cb, a)`][`void`][Computes `cb % a` and stores the result in `b`, only required when `B` is an integer type. The type of `a` shall be listed in one of the type lists
4351 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4352 When not provided, does the equivalent of `eval_modulus(b, cb, B(a))`.]
4353 [`std::overflow_error` if `a` has the value zero.]]
4354[[`eval_modulus(b, a, cb)`][`void`][Computes `cb % a` and stores the result in `b`, only required when `B` is an integer type. The type of `a` shall be listed in one of the type lists
4355 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4356 When not provided, does the equivalent of `eval_modulus(b, B(a), cb)`.]
4357 [`std::overflow_error` if `a` has the value zero.]]
4358[[`eval_bitwise_and(b, a)`][`void`][Computes `b &= cb`, only required when `B` is an integer type. The type of `a` shall be listed in one of the type lists
4359 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4360 When not provided, the default version calls `eval_bitwise_and(b, B(a))`][[space]]]
4361[[`eval_bitwise_and(b, cb, cb2)`][`void`][Computes `cb & cb2` and stores the result in `b`, only required when `B` is an integer type.
4362 When not provided, does the equivalent of `b = cb; eval_bitwise_and(b, cb2)`.][[space]]]
4363[[`eval_bitwise_and(b, cb, a)`][`void`][Computes `cb & a` and stores the result in `b`, only required when `B` is an integer type. The type of `a` shall be listed in one of the type lists
4364 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4365 When not provided, does the equivalent of `eval_bitwise_and(b, cb, B(a))`.][[space]]]
4366[[`eval_bitwise_and(b, a, cb)`][`void`][Computes `cb & a` and stores the result in `b`, only required when `B` is an integer type. The type of `a` shall be listed in one of the type lists
4367 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4368 When not provided, does the equivalent of `eval_bitwise_and(b, cb, a)`.][[space]]]
4369[[`eval_bitwise_or(b, a)`][`void`][Computes `b |= cb`, only required when `B` is an integer type. The type of `a` shall be listed in one of the type lists
4370 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4371 When not provided, the default version calls `eval_bitwise_or(b, B(a))`][[space]]]
4372[[`eval_bitwise_or(b, cb, cb2)`][`void`][Computes `cb | cb2` and stores the result in `b`, only required when `B` is an integer type.
4373 When not provided, does the equivalent of `b = cb; eval_bitwise_or(b, cb2)`.][[space]]]
4374[[`eval_bitwise_or(b, cb, a)`][`void`][Computes `cb | a` and stores the result in `b`, only required when `B` is an integer type. The type of `a` shall be listed in one of the type lists
4375 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4376 When not provided, does the equivalent of `eval_bitwise_or(b, cb, B(a))`.][[space]]]
4377[[`eval_bitwise_or(b, a, cb)`][`void`][Computes `cb | a` and stores the result in `b`, only required when `B` is an integer type. The type of `a` shall be listed in one of the type lists
4378 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4379 When not provided, does the equivalent of `eval_bitwise_or(b, cb, a)`.][[space]]]
4380[[`eval_bitwise_xor(b, a)`][`void`][Computes `b ^= cb`, only required when `B` is an integer type. The type of `a` shall be listed in one of the type lists
4381 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4382 When not provided, the default version calls `eval_bitwise_xor(b, B(a))`][[space]]]
4383[[`eval_bitwise_xor(b, cb, cb2)`][`void`][Computes `cb ^ cb2` and stores the result in `b`, only required when `B` is an integer type.
4384 When not provided, does the equivalent of `b = cb; eval_bitwise_xor(b, cb2)`.][[space]]]
4385[[`eval_bitwise_xor(b, cb, a)`][`void`][Computes `cb ^ a` and stores the result in `b`, only required when `B` is an integer type. The type of `a` shall be listed in one of the type lists
4386 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4387 When not provided, does the equivalent of `eval_bitwise_xor(b, cb, B(a))`.][[space]]]
4388[[`eval_bitwise_xor(b, a, cb)`][`void`][Computes `a ^ cb` and stores the result in `b`, only required when `B` is an integer type. The type of `a` shall be listed in one of the type lists
4389 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4390 When not provided, does the equivalent of `eval_bitwise_xor(b, cb, a)`.][[space]]]
4391[[`eval_left_shift(b, cb, ui)`][`void`][Computes `cb << ui` and stores the result in `b`, only required when `B` is an integer type.
4392 When not provided, does the equivalent of `b = cb; eval_left_shift(b, a);`.][[space]]]
4393[[`eval_right_shift(b, cb, ui)`][`void`][Computes `cb >> ui` and stores the result in `b`, only required when `B` is an integer type.
4394 When not provided, does the equivalent of `b = cb; eval_right_shift(b, a);`.][[space]]]
4395[[`eval_qr(cb, cb2, b, b2)`][`void`][Sets `b` to the result of `cb / cb2` and `b2` to the result of `cb % cb2`. Only required when `B` is an integer type.
4396 The default version of this function is synthesised from other operations above.]
4397 [`std::overflow_error` if `a` has the value zero.]]
4398[[`eval_integer_modulus(cb, ui)`][`unsigned`][Returns the result of `cb % ui`. Only required when `B` is an integer type.
4399 The default version of this function is synthesised from other operations above.]
4400 [`std::overflow_error` if `a` has the value zero.]]
4401[[`eval_lsb(cb)`][`unsigned`][Returns the index of the least significant bit that is set. Only required when `B` is an integer type.
4402 The default version of this function is synthesised from other operations above.][[space]]]
4403[[`eval_msb(cb)`][`unsigned`][Returns the index of the most significant bit that is set. Only required when `B` is an integer type.
4404 The default version of this function is synthesised from other operations above.][[space]]]
4405[[`eval_bit_test(cb, ui)`][`bool`][Returns true if `cb` has bit `ui` set. Only required when `B` is an integer type.
4406 The default version of this function is synthesised from other operations above.][[space]]]
4407[[`eval_bit_set(b, ui)`][`void`][Sets the bit at index `ui` in `b`. Only required when `B` is an integer type.
4408 The default version of this function is synthesised from other operations above.][[space]]]
4409[[`eval_bit_unset(b, ui)`][`void`][Unsets the bit at index `ui` in `b`. Only required when `B` is an integer type.
4410 The default version of this function is synthesised from other operations above.][[space]]]
4411[[`eval_bit_flip(b, ui)`][`void`][Flips the bit at index `ui` in `b`. Only required when `B` is an integer type.
4412 The default version of this function is synthesised from other operations above.][[space]]]
4413[[`eval_gcd(b, cb, cb2)`][`void`][Sets `b` to the greatest common divisor of `cb` and `cb2`. Only required when `B` is an integer type.
4414 The default version of this function is synthesised from other operations above.][[space]]]
4415[[`eval_lcm(b, cb, cb2)`][`void`][Sets `b` to the least common multiple of `cb` and `cb2`. Only required when `B` is an integer type.
4416 The default version of this function is synthesised from other operations above.][[space]]]
4417[[`eval_gcd(b, cb, a)`][`void`][Sets `b` to the greatest common divisor of `cb` and `cb2`. Only required when `B` is an integer type.
4418 The type of `a` shall be listed in one of the type lists
4419 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4420 The default version of this function calls `eval_gcd(b, cb, B(a))`.][[space]]]
4421[[`eval_lcm(b, cb, a)`][`void`][Sets `b` to the least common multiple of `cb` and `cb2`. Only required when `B` is an integer type.
4422 The type of `a` shall be listed in one of the type lists
4423 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4424 The default version of this function calls `eval_lcm(b, cb, B(a))`.][[space]]]
4425[[`eval_gcd(b, a, cb)`][`void`][Sets `b` to the greatest common divisor of `cb` and `a`. Only required when `B` is an integer type.
4426 The type of `a` shall be listed in one of the type lists
4427 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4428 The default version of this function calls `eval_gcd(b, cb, a)`.][[space]]]
4429[[`eval_lcm(b, a, cb)`][`void`][Sets `b` to the least common multiple of `cb` and `a`. Only required when `B` is an integer type.
4430 The type of `a` shall be listed in one of the type lists
4431 `B::signed_types`, `B::unsigned_types` or `B::float_types`.
4432 The default version of this function calls `eval_lcm(b, cb, a)`.][[space]]]
4433[[`eval_powm(b, cb, cb2, cb3)`][`void`][Sets `b` to the result of ['(cb^cb2)%cb3].
4434 The default version of this function is synthesised from other operations above.][[space]]]
4435[[`eval_powm(b, cb, cb2, a)`][`void`][Sets `b` to the result of ['(cb^cb2)%a].
4436 The type of `a` shall be listed in one of the type lists
4437 `B::signed_types`, `B::unsigned_types`.
4438 The default version of this function is synthesised from other operations above.][[space]]]
4439[[`eval_powm(b, cb, a, cb2)`][`void`][Sets `b` to the result of ['(cb^a)%cb2].
4440 The type of `a` shall be listed in one of the type lists
4441 `B::signed_types`, `B::unsigned_types`.
4442 The default version of this function is synthesised from other operations above.][[space]]]
4443[[`eval_powm(b, cb, a, a2)`][`void`][Sets `b` to the result of ['(cb^a)%a2].
4444 The type of `a` shall be listed in one of the type lists
4445 `B::signed_types`, `B::unsigned_types`.
4446 The default version of this function is synthesised from other operations above.][[space]]]
4447[[`eval_integer_sqrt(b, cb, b2)`][`void`][Sets `b` to the largest integer which when squared is less than `cb`, also
4448 sets `b2` to the remainder, ie to ['cb - b[super 2]].
4449 The default version of this function is synthesised from other operations above.][[space]]]
4450
4451[[['Sign manipulation:]]]
4452[[`eval_abs(b, cb)`][`void`][Set `b` to the absolute value of `cb`.
4453 The default version of this functions assigns `cb` to `b`, and then calls `b.negate()` if
4454 `eval_get_sign(cb) < 0`.][[space]]]
4455[[`eval_fabs(b, cb)`][`void`][Set `b` to the absolute value of `cb`.
4456 The default version of this functions assigns `cb` to `b`, and then calls `b.negate()` if
4457 `eval_get_sign(cb) < 0`.][[space]]]
4458
4459[[['floating-point functions:]]]
4460[[`eval_fpclassify(cb)`][`int`][Returns one of the same values returned by `std::fpclassify`. Only required when `B` is an floating-point type.
4461 The default version of this function will only test for zero `cb`.][[space]]]
4462[[`eval_trunc(b, cb)`][`void`][Performs the equivalent operation to `std::trunc` on argument `cb` and stores the result in `b`. Only required when `B` is an floating-point type.
4463 The default version of this function is synthesised from other operations above.][[space]]]
4464[[`eval_round(b, cb)`][`void`][Performs the equivalent operation to `std::round` on argument `cb` and stores the result in `b`. Only required when `B` is an floating-point type.
4465 The default version of this function is synthesised from other operations above.][[space]]]
4466[[`eval_exp(b, cb)`][`void`][Performs the equivalent operation to `std::exp` on argument `cb` and stores the result in `b`. Only required when `B` is an floating-point type.
4467 The default version of this function is synthesised from other operations above.][[space]]]
4468[[`eval_exp2(b, cb)`][`void`][Performs the equivalent operation to `std::exp2` on argument `cb` and stores the result in `b`. Only required when `B` is an floating-point type.
4469 The default version of this function is implemented in terms of `eval_pow`.][[space]]]
4470[[`eval_log(b, cb)`][`void`][Performs the equivalent operation to `std::log` on argument `cb` and stores the result in `b`. Only required when `B` is an floating-point type.
4471 The default version of this function is synthesised from other operations above.][[space]]]
4472[[`eval_log10(b, cb)`][`void`][Performs the equivalent operation to `std::log10` on argument `cb` and stores the result in `b`. Only required when `B` is an floating-point type.
4473 The default version of this function is synthesised from other operations above.][[space]]]
4474[[`eval_sin(b, cb)`][`void`][Performs the equivalent operation to `std::sin` on argument `cb` and stores the result in `b`. Only required when `B` is an floating-point type.
4475 The default version of this function is synthesised from other operations above.][[space]]]
4476[[`eval_cos(b, cb)`][`void`][Performs the equivalent operation to `std::cos` on argument `cb` and stores the result in `b`. Only required when `B` is an floating-point type.
4477 The default version of this function is synthesised from other operations above.][[space]]]
4478[[`eval_tan(b, cb)`][`void`][Performs the equivalent operation to `std::exp` on argument `cb` and stores the result in `b`. Only required when `B` is an floating-point type.
4479 The default version of this function is synthesised from other operations above.][[space]]]
4480[[`eval_asin(b, cb)`][`void`][Performs the equivalent operation to `std::asin` on argument `cb` and stores the result in `b`. Only required when `B` is an floating-point type.
4481 The default version of this function is synthesised from other operations above.][[space]]]
4482[[`eval_acos(b, cb)`][`void`][Performs the equivalent operation to `std::acos` on argument `cb` and stores the result in `b`. Only required when `B` is an floating-point type.
4483 The default version of this function is synthesised from other operations above.][[space]]]
4484[[`eval_atan(b, cb)`][`void`][Performs the equivalent operation to `std::atan` on argument `cb` and stores the result in `b`. Only required when `B` is an floating-point type.
4485 The default version of this function is synthesised from other operations above.][[space]]]
4486[[`eval_sinh(b, cb)`][`void`][Performs the equivalent operation to `std::sinh` on argument `cb` and stores the result in `b`. Only required when `B` is an floating-point type.
4487 The default version of this function is synthesised from other operations above.][[space]]]
4488[[`eval_cosh(b, cb)`][`void`][Performs the equivalent operation to `std::cosh` on argument `cb` and stores the result in `b`. Only required when `B` is an floating-point type.
4489 The default version of this function is synthesised from other operations above.][[space]]]
4490[[`eval_tanh(b, cb)`][`void`][Performs the equivalent operation to `std::tanh` on argument `cb` and stores the result in `b`. Only required when `B` is an floating-point type.
4491 The default version of this function is synthesised from other operations above.][[space]]]
4492[[`eval_fmod(b, cb, cb2)`][`void`][Performs the equivalent operation to `std::fmod` on arguments `cb` and `cb2`, and store the result in `b`. Only required when `B` is an floating-point type.
4493 The default version of this function is synthesised from other operations above.][[space]]]
4494[[`eval_modf(b, cb, pb)`][`void`][Performs the equivalent operation to `std::modf` on argument `cb`, and store the integer result in `*pb` and the fractional part in `b`.
4495 Only required when `B` is an floating-point type.
4496 The default version of this function is synthesised from other operations above.][[space]]]
4497[[`eval_pow(b, cb, cb2)`][`void`][Performs the equivalent operation to `std::pow` on arguments `cb` and `cb2`, and store the result in `b`. Only required when `B` is an floating-point type.
4498 The default version of this function is synthesised from other operations above.][[space]]]
4499[[`eval_atan2(b, cb, cb2)`][`void`][Performs the equivalent operation to `std::atan` on arguments `cb` and `cb2`, and store the result in `b`. Only required when `B` is an floating-point type.
4500 The default version of this function is synthesised from other operations above.][[space]]]
4501[[`eval_scalbn(b, cb, e)`][`void`][Scales value `cb` by ['r[super e]], where ['r] is the radix of the type. The default version of this function
4502 is implemented in terms of eval_ldexp, consequently this function must be provided for types with a radix other than 2.]]
4503[[`eval_scalbln(b, cb, e)`][`void`][Calls `eval_scalbn(b, cb, e)`.]]
4504[[`eval_ilogb(cb)`][`B::exponent_type`][Returns the exponent ['e] of value `cb` such that ['1 <= cb*r[super -e] < r], where ['r] is the radix of type B.
4505 The default version of this function is implemented in terms of eval_frexp, consequently this function must be provided for types with a radix other than 2.]]
4506[[`eval_remquo(b, cb, cb2, pi)`][`void`][Sets `b = cb - n * cb2` and stores `n` in `*pi`.]]
4507[[`eval_remquo(b, cb, a, pi)`][`void`][Default version converts a to type B and calls the overload above.]]
4508[[`eval_remquo(b, a, cb, pi)`][`void`][Default version converts a to type B and calls the overload above.]]
4509[[`eval_remainder(b, cb, cb2)`][`void`][Default version calls eval_remquo with a dummy final argument.]]
4510[[`eval_remainder(b, cb, a)`][`void`][Default version calls eval_remquo with a dummy final argument.]]
4511[[`eval_remainder(b, a, cb)`][`void`][Default version calls eval_remquo with a dummy final argument.]]
4512
4513[[`eval_fdim(b, cb, cb2)`][`void`][Default version sets `b = cb - cb2` if `cb > cb2` and zero otherwise. Special cases are handled as in the C99 annex.]]
4514[[`eval_fdim(b, cb, a)`][`void`][Default version sets `b = cb - cb2` if `cb > cb2` and zero otherwise. Special cases are handled as in the C99 annex.]]
4515[[`eval_fdim(b, a, cb)`][`void`][Default version sets `b = cb - cb2` if `cb > cb2` and zero otherwise. Special cases are handled as in the C99 annex.]]
4516
4517[[`eval_fmax(b, cb, cb2)`][`void`][Sets `b` to the larger of `cb` and `cb2`.]]
4518[[`eval_fmax(b, cb, a)`][`void`][Sets `b` to the larger of `cb` and `a`.]]
4519[[`eval_fmax(b, a, cb)`][`void`][Sets `b` to the larger of `cb` and `a`.]]
4520[[`eval_fmin(b, cb, cb2)`][`void`][Sets `b` to the smaller of `cb` and `cb2`.]]
4521[[`eval_fmin(b, cb, a)`][`void`][Sets `b` to the smaller of `cb` and `a`.]]
4522[[`eval_fmin(b, a, cb)`][`void`][Sets `b` to the smaller of `cb` and `a`.]]
4523
4524[[`eval_hypot(b, cb, cb2)`][`void`][Sets `b` to the square root of the sum of the squares of `cb` and `cb2` without undue over or under flow.]]
4525[[`eval_hypot(b, cb, a)`][`void`][As above.]]
4526[[`eval_hypot(b, a, cb)`][`void`][As above.]]
4527
4528[[`eval_logb(b, cb)`][`B::exponent_type`][Sets `b` to the exponent ['e] of value `cb` such that ['1 <= cb*r[super -b] < r], where ['r] is the radix of type B.
4529 The default version of this function is implemented in terms of `eval_ilogb`.]]
4530[[`eval_nearbyint(b, cb)`][`void`][Calls `eval_round(b, cb)`.]]
4531[[`eval_rint(b, cb)`][`void`][Calls `eval_nearbyint(b, cb)`.]]
4532[[`eval_log2(b, cb)`][`void`][Sets `b` to the logarithm base 2 of `cb`.]]
4533
4534[[['hashing:]]]
4535[[`hash_value(cb)`][`std::size_t`]
4536 [Returns a hash value for the argument that is suitable for use with `std::hash` etc. If not provided then no automatic hashing support will be available for the number type.]]
4537]
4538
4539When the tables above place no ['throws] requirements on an operation, then it is up to each type modelling this concept to
4540decide when or whether throwing an exception is desirable. However, thrown exceptions should always either be the type, or
4541inherit from the type `std::runtime_error`. For example, a floating-point type might choose to throw `std::overflow_error`
4542whenever the result of an operation would be infinite, and `std::underflow_error` whenever it would round to zero.
4543
4544[note
4545The non-member functions are all named with an "eval_" prefix to avoid conflicts with template classes of the same name -
4546in point of fact this naming convention shouldn't be necessary, but rather works around some compiler bugs.]
4547
4548[h4 Overloadable Functions]
4549
4550Some of the C99 math functions do not have `eval_` functions but must be overloaded directly: these functions
4551are either trivial or are forwarded to the Boost.Math implementations by default.
4552The full list of these functions is:
4553
4554 int sign (const ``['number-or-expression-template-type]``&);
4555 int signbit (const ``['number-or-expression-template-type]``&);
4556 ``['number]`` changesign (const ``['number-or-expression-template-type]``&);
4557 ``['number]`` copysign (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
4558 ``['number]`` asinh (const ``['number-or-expression-template-type]``&);
4559 ``['number]`` acosh (const ``['number-or-expression-template-type]``&);
4560 ``['number]`` atanh (const ``['number-or-expression-template-type]``&);
4561 ``['number]`` cbrt (const ``['number-or-expression-template-type]``&);
4562 ``['number]`` erf (const ``['number-or-expression-template-type]``&);
4563 ``['number]`` erfc (const ``['number-or-expression-template-type]``&);
4564 ``['number]`` expm1 (const ``['number-or-expression-template-type]``&);
4565 ``['number]`` log1p (const ``['number-or-expression-template-type]``&);
4566 ``['number]`` tgamma (const ``['number-or-expression-template-type]``&);
4567 ``['number]`` lgamma (const ``['number-or-expression-template-type]``&);
4568 long lrint (const ``['number-or-expression-template-type]``&);
4569 long long llrint (const ``['number-or-expression-template-type]``&);
4570 ``['number]`` nextafter (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
4571 ``['number]`` nexttoward (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&);
4572
4573[endsect]
4574
4575[section:headers Header File Structure]
4576
4577[table Top level headers
4578[[Header][Contains]]
4579[[cpp_int.hpp][The `cpp_int` backend type.]]
4580[[gmp.hpp][Defines all [gmp] related backends.]]
4581[[miller_rabin.hpp][Miller Rabin primality testing code.]]
4582[[number.hpp][Defines the `number` backend, is included by all the backend headers.]]
4583[[mpfr.hpp][Defines the mpfr_float_backend backend.]]
4584[[random.hpp][Defines code to interoperate with Boost.Random.]]
4585[[rational_adaptor.hpp][Defines the `rational_adaptor` backend.]]
4586[[cpp_dec_float.hpp][Defines the `cpp_dec_float` backend.]]
4587[[tommath.hpp][Defines the `tommath_int` backend.]]
4588[[concepts/number_archetypes.hpp][Defines a backend concept archetypes for testing use.]]
4589]
4590
4591[table Implementation Headers
4592[[Header][Contains]]
4593[[cpp_int/add.hpp][Add and subtract operators for `cpp_int_backend`.]]
4594[[cpp_int/bitwise.hpp][Bitwise operators for `cpp_int_backend`.]]
4595[[cpp_int/checked.hpp][Helper functions for checked arithmetic for `cpp_int_backend`.]]
4596[[cpp_int/comparison.hpp][Comparison operators for `cpp_int_backend`.]]
4597[[cpp_int/cpp_int_config.hpp][Basic setup and configuration for `cpp_int_backend`.]]
4598[[cpp_int/divide.hpp][Division and modulus operators for `cpp_int_backend`.]]
4599[[cpp_int/limits.hpp][`numeric_limits` support for `cpp_int_backend`.]]
4600[[cpp_int/misc.hpp][Miscellaneous operators for `cpp_int_backend`.]]
4601[[cpp_int/multiply.hpp][Multiply operators for `cpp_int_backend`.]]
4602[[detail/big_lanczos.hpp][Lanczos support for Boost.Math integration.]]
4603[[detail/default_ops.hpp][Default versions of the optional backend non-member functions.]]
4604[[detail/generic_interconvert.hpp][Generic interconversion routines.]]
4605[[detail/number_base.hpp][All the expression template code, metaprogramming, and operator overloads for `number`.]]
4606[[detail/no_et_ops.hpp][The non-expression template operators.]]
4607[[detail/functions/constants.hpp][Defines constants used by the floating-point functions.]]
4608[[detail/functions/pow.hpp][Defines default versions of the power and exponential related floating-point functions.]]
4609[[detail/functions/trig.hpp][Defines default versions of the trigonometric related floating-point functions.]]
4610]
4611
4612[endsect]
4613
4614[endsect]
4615
4616[section:perf Performance Comparison]
4617
4618[section:overhead The Overhead in the Number Class Wrapper]
4619
4620Using a simple [@../../performance/arithmetic_backend.hpp backend class] that wraps any built in arithmetic type
4621we can measure the overhead involved in wrapping a type inside the `number` frontend, and the effect that turning
4622on expression templates has. The following table compares the performance between `double` and a `double` wrapped
4623inside class `number`:
4624
4625[table
4626[[Type][Bessel Function Evaluation][Non-Central T Evaluation]]
4627[[`double`] [[*1.0 (0.016s)]] [[*1.0] (0.46s)]]
4628[[`number<arithmetic_backend<double>, et_off>`] [1.2 (0.019s)] [[*1.0](0.46s)]]
4629[[`number<arithmetic_backend<double>, et_on>`] [1.2 (0.019s)] [1.7 (0.79s)]]
4630]
4631
4632As you can see whether or not there is an overhead, and how large it is depends on the actual situation,
4633but the overhead is in any cases small. Expression templates generally add a greater overhead the
4634more complex the expression becomes due to the logic of figuring out how to best unpack and evaluate
4635the expression, but of course this is also the situation where you save more temporaries. For a
4636"trivial" backend like this, saving temporaries has no benefit, but for larger types it becomes
4637a bigger win.
4638
4639The following table compares arithmetic using either `long long` or `number<arithmetic_backend<long long> >`
4640for the [@../../performance/voronoi_performance.cpp voronoi-diagram builder test]:
4641
4642[table
4643[[Type][Relative time]]
4644[[`long long`][[*1.0](0.0823s)]]
4645[[`number<arithmetic_backend<long long>, et_off>`][1.05 (0.0875s)]]
4646]
4647
4648This test involves mainly creating a lot of temporaries and performing a small amount of arithmetic on them,
4649with very little difference in performance between the native and "wrapped" types.
4650
4651The test code was compiled with Microsoft Visual Studio 2010 with all optimisations
4652turned on (/Ox), and used MPIR-2.3.0 and [tommath]-0.42.0. The tests were run on 32-bit
4653Windows Vista machine.
4654
4655[endsect]
4656
4657[section:realworld Floating-Point Real World Tests]
4658
4659These tests test the total time taken to execute all of Boost.Math's test cases for these functions.
4660In each case the best performing library gets a relative score of 1, with the total execution time
4661given in brackets. The first three libraries listed are the various floating-point types provided
4662by this library, while for comparison, two popular C++ front-ends to [mpfr] ([mpfr_class] and [mpreal])
4663are also shown.
4664
4665[table Bessel Function Performance
4666[[Library][50 Decimal Digits][100 Decimal Digits]]
4667[[mpfr_float] [1.2 (5.78s)] [1.2 (9.56s)]]
4668[[static_mpfr_float] [1.1 (5.47s)] [1.1 (9.09s)]]
4669[[mpf_float] [[*1.0] (4.82s)] [[*1.0](8.07s)]]
4670[[cpp_dec_float] [1.8 (8.54s)] [2.6 (20.66s)]]
4671[[[mpfr_class]] [1.3 (6.28s)] [1.2(10.06s)]]
4672[[[mpreal]] [2.0 (9.54s)] [1.7 (14.08s)]]
4673]
4674
4675[table Non-Central T Distribution Performance
4676[[Library][50 Decimal Digits]]
4677[[mpfr_float] [1.3 (263.27s)]]
4678[[static_mpfr_float] [1.2 (232.88s)]]
4679[[mpf_float] [[*1.0] (195.73s)]]
4680[[cpp_dec_float] [1.9 (366.38s)]]
4681[[[mpfr_class]] [1.5 (286.94s)]]
4682[[[mpreal]] [2.0 (388.70s)]]
4683]
4684
4685Test code was compiled with Microsoft Visual Studio 2010 with all optimisations
4686turned on (/Ox), and used MPIR-2.3.0 and [mpfr]-3.0.0. The tests were run on 32-bit
4687Windows Vista machine.
4688
4689[endsect]
4690
4691[section:int_real_world Integer Real World Tests]
4692
4693The first set of [@../../performance/voronoi_performance.cpp tests] measure the times taken to
4694execute the multiprecision part of the Voronoi-diagram builder from Boost.Polygon. The tests
4695mainly create a large number of temporaries "just in case" multiprecision arithmetic is required,
4696for comparison, also included in the tests is Boost.Polygon's own partial-multiprecision integer
4697type which was custom written for this specific task:
4698
4699[table
4700[[Integer Type][Relative Performance (Actual time in parenthesis)]]
4701[[polygon::detail::extended_int][1(0.138831s)]]
4702[[int256_t][1.19247(0.165551s)]]
4703[[int512_t][1.23301(0.17118s)]]
4704[[int1024_t][1.21463(0.168628s)]]
4705[[checked_int256_t][1.31711(0.182855s)]]
4706[[checked_int512_t][1.57413(0.218538s)]]
4707[[checked_int1024_t][1.36992(0.190187s)]]
4708[[cpp_int][1.63244(0.226632s)]]
4709[[mpz_int][5.42511(0.753172s)]]
4710[[tom_int][29.0793(4.03709s)]]
4711]
4712
4713Note how for this use case, any dynamic allocation is a performance killer.
4714
4715The next [@../../performance/miller_rabin_performance.cpp tests] measure the time taken to generate 1000 128-bit
4716random numbers and test for primality using the Miller Rabin test. This is primarily a test of modular-exponentiation
4717since that is the rate limiting step:
4718
4719[table
4720[[Integer Type][Relative Performance (Actual time in parenthesis)]]
4721[[cpp_int][5.25827(0.379597s)]]
4722[[cpp_int (no Expression templates)][5.15675(0.372268s)]]
4723[[cpp_int (128-bit cache)][5.10882(0.368808s)]]
4724[[cpp_int (256-bit cache)][5.50623(0.397497s)]]
4725[[cpp_int (512-bit cache)][4.82257(0.348144s)]]
4726[[cpp_int (1024-bit cache)][5.00053(0.360991s)]]
4727[[int1024_t][4.37589(0.315897s)]]
4728[[checked_int1024_t][4.52396(0.326587s)]]
4729[[mpz_int][1(0.0721905s)]]
4730[[mpz_int (no Expression templates)][1.0248(0.0739806s)]]
4731[[tom_int][2.60673(0.188181s)]]
4732[[tom_int (no Expression templates)][2.64997(0.191303s)]]
4733]
4734
4735It's interesting to note that expression templates have little effect here - perhaps because the actual expressions involved
4736are relatively trivial in this case - so the time taken for multiplication and division tends to dominate. Also note
4737how increasing the internal cache size used by `cpp_int` is quite effective in this case in cutting out memory allocations
4738altogether - cutting about a third off the total runtime. Finally the much quicker times from GMP and tommath are down to their
4739much better modular-exponentiation algorithms (GMP's is about 5x faster). That's an issue which needs to be addressed
4740in a future release for __cpp_int.
4741
4742Test code was compiled with Microsoft Visual Studio 2010 with all optimisations
4743turned on (/Ox), and used MPIR-2.3.0 and [mpfr]-3.0.0. The tests were run on 32-bit
4744Windows Vista machine.
4745
4746[endsect]
4747
4748[section:float_performance Float Algorithm Performance]
4749
4750Note that these tests are carefully designed to test performance of the underlying algorithms
4751and not memory allocation or variable copying. As usual, performance results should be taken
4752with a healthy dose of scepticism, and real-world performance may vary widely depending upon the
4753specifics of the program. In each table relative times are given first, with the best performer
4754given a score of 1. Total actual times are given in brackets, measured in seconds for 500000
4755operations.
4756
4757[table Operator +
4758[[Backend][50 Bits][100 Bits][500 Bits]]
4759[[cpp_dec_float][[*1] (0.0575156s)][[*1] (0.0740086s)][[*1] (0.219073s)]]
4760[[gmp_float][2.45065 (0.14095s)][2.01398 (0.149052s)][1.09608 (0.240122s)]]
4761[[mpfr_float][2.6001 (0.149546s)][2.12079 (0.156957s)][1.09078 (0.23896s)]]
4762]
4763[table Operator +(int)
4764[[Backend][50 Bits][100 Bits][500 Bits]]
4765[[cpp_dec_float][1.46115 (0.0855392s)][2.60353 (0.114398s)][3.62562 (0.264905s)]]
4766[[gmp_float][[*1] (0.0585424s)][[*1] (0.0439398s)][[*1] (0.0730648s)]]
4767[[mpfr_float][2.40441 (0.14076s)][3.2877 (0.144461s)][2.40379 (0.175632s)]]
4768]
4769[table Operator +(unsigned long long)
4770[[Backend][50 Bits][100 Bits][500 Bits]]
4771[[cpp_dec_float][[*1] (0.118146s)][[*1] (0.144714s)][[*1] (0.315639s)]]
4772[[gmp_float][4.5555 (0.538213s)][3.83096 (0.554395s)][1.95079 (0.615745s)]]
4773[[mpfr_float][5.74477 (0.678719s)][4.85295 (0.702291s)][2.70354 (0.853342s)]]
4774]
4775[table Operator +=(unsigned long long)
4776[[Backend][50 Bits][100 Bits][500 Bits]]
4777[[cpp_dec_float][[*1] (0.101188s)][[*1] (0.122394s)][[*1] (0.251975s)]]
4778[[gmp_float][5.199 (0.526079s)][4.39327 (0.537712s)][2.42151 (0.610159s)]]
4779[[mpfr_float][6.08318 (0.615547s)][5.18525 (0.634645s)][3.1022 (0.781677s)]]
4780]
4781[table Operator -
4782[[Backend][50 Bits][100 Bits][500 Bits]]
4783[[cpp_dec_float][[*1] (0.0895163s)][[*1] (0.129248s)][1.5088 (0.374512s)]]
4784[[gmp_float][1.72566 (0.154474s)][1.22567 (0.158415s)][[*1] (0.248219s)]]
4785[[mpfr_float][1.83764 (0.164499s)][1.34284 (0.173559s)][1.00226 (0.248781s)]]
4786]
4787[table Operator -(int)
4788[[Backend][50 Bits][100 Bits][500 Bits]]
4789[[cpp_dec_float][[*1] (0.105285s)][[*1] (0.142741s)][[*1] (0.278718s)]]
4790[[gmp_float][2.34437 (0.246828s)][1.28814 (0.183871s)][1.00731 (0.280754s)]]
4791[[mpfr_float][2.8032 (0.295136s)][2.09178 (0.298582s)][1.25213 (0.34899s)]]
4792]
4793[table Operator -(unsigned long long)
4794[[Backend][50 Bits][100 Bits][500 Bits]]
4795[[cpp_dec_float][[*1] (0.13719s)][[*1] (0.184428s)][[*1] (0.344212s)]]
4796[[gmp_float][4.0804 (0.559791s)][3.06776 (0.565781s)][2.07736 (0.715053s)]]
4797[[mpfr_float][5.10114 (0.699828s)][3.88684 (0.716843s)][2.50074 (0.860784s)]]
4798]
4799[table Operator -=(unsigned long long)
4800[[Backend][50 Bits][100 Bits][500 Bits]]
4801[[cpp_dec_float][[*1] (0.100984s)][[*1] (0.123148s)][[*1] (0.246181s)]]
4802[[gmp_float][5.68353 (0.573944s)][4.68636 (0.577116s)][2.6958 (0.663655s)]]
4803[[mpfr_float][6.19738 (0.625834s)][5.18544 (0.638577s)][3.18738 (0.784673s)]]
4804]
4805[table Operator *
4806[[Backend][50 Bits][100 Bits][500 Bits]]
4807[[cpp_dec_float][1.03667 (0.284251s)][1.30576 (0.536527s)][1.44686 (4.81057s)]]
4808[[gmp_float][[*1] (0.274196s)][[*1] (0.410891s)][[*1] (3.32484s)]]
4809[[mpfr_float][1.24537 (0.341477s)][1.15785 (0.475749s)][1.1796 (3.92199s)]]
4810]
4811[table Operator *(int)
4812[[Backend][50 Bits][100 Bits][500 Bits]]
4813[[cpp_dec_float][3.97453 (0.240262s)][9.91222 (0.463473s)][50.7926 (4.36527s)]]
4814[[gmp_float][[*1] (0.0604505s)][[*1] (0.0467577s)][[*1] (0.0859431s)]]
4815[[mpfr_float][2.56974 (0.155342s)][3.56312 (0.166603s)][3.22964 (0.277565s)]]
4816]
4817[table Operator *(unsigned long long)
4818[[Backend][50 Bits][100 Bits][500 Bits]]
4819[[cpp_dec_float][[*1] (0.331877s)][1.01058 (0.586122s)][6.688 (4.7931s)]]
4820[[gmp_float][1.72433 (0.572266s)][[*1] (0.579987s)][[*1] (0.716672s)]]
4821[[mpfr_float][2.5553 (0.848047s)][1.74987 (1.0149s)][1.80403 (1.2929s)]]
4822]
4823[table Operator *=(unsigned long long)
4824[[Backend][50 Bits][100 Bits][500 Bits]]
4825[[cpp_dec_float][[*1] (0.321397s)][1.00772 (0.574887s)][6.65946 (4.7468s)]]
4826[[gmp_float][1.77419 (0.570218s)][[*1] (0.570482s)][[*1] (0.712791s)]]
4827[[mpfr_float][2.62172 (0.842611s)][1.77691 (1.01369s)][1.77511 (1.26528s)]]
4828]
4829[table Operator /
4830[[Backend][50 Bits][100 Bits][500 Bits]]
4831[[cpp_dec_float][2.96096 (4.00777s)][4.53244 (7.86435s)][6.11936 (51.5509s)]]
4832[[gmp_float][[*1] (1.35354s)][[*1] (1.73512s)][[*1] (8.42422s)]]
4833[[mpfr_float][1.30002 (1.75963s)][1.39045 (2.41261s)][1.66762 (14.0484s)]]
4834]
4835[table Operator /(int)
4836[[Backend][50 Bits][100 Bits][500 Bits]]
4837[[cpp_dec_float][8.60726 (1.8181s)][15.4122 (3.67479s)][34.5119 (24.729s)]]
4838[[gmp_float][1.24394 (0.262756s)][[*1] (0.238433s)][[*1] (0.716536s)]]
4839[[mpfr_float][[*1] (0.211229s)][1.12178 (0.26747s)][1.02237 (0.732562s)]]
4840]
4841[table Operator /(unsigned long long)
4842[[Backend][50 Bits][100 Bits][500 Bits]]
4843[[cpp_dec_float][2.10976 (1.97569s)][3.73601 (3.9133s)][11.3085 (25.4533s)]]
4844[[gmp_float][[*1] (0.936452s)][[*1] (1.04746s)][[*1] (2.25081s)]]
4845[[mpfr_float][1.3423 (1.257s)][1.51575 (1.58768s)][3.31513 (7.46175s)]]
4846]
4847[table Operator /=(unsigned long long)
4848[[Backend][50 Bits][100 Bits][500 Bits]]
4849[[cpp_dec_float][2.17401 (1.96883s)][3.79591 (3.8965s)][11.2328 (25.2606s)]]
4850[[gmp_float][[*1] (0.905621s)][[*1] (1.0265s)][[*1] (2.24882s)]]
4851[[mpfr_float][1.37953 (1.24933s)][1.53073 (1.57129s)][3.30546 (7.43339s)]]
4852]
4853[table Operator construct
4854[[Backend][50 Bits][100 Bits][500 Bits]]
4855[[cpp_dec_float][[*1] (0.00929804s)][[*1] (0.0268321s)][[*1] (0.0310685s)]]
4856[[gmp_float][30.8781 (0.287106s)][7.59969 (0.203916s)][6.51873 (0.202527s)]]
4857[[mpfr_float][23.5296 (0.218779s)][8.11058 (0.217624s)][7.16325 (0.222552s)]]
4858]
4859[table Operator construct(unsigned)
4860[[Backend][50 Bits][100 Bits][500 Bits]]
4861[[cpp_dec_float][[*1] (0.0603971s)][[*1] (0.0735485s)][[*1] (0.116464s)]]
4862[[gmp_float][3.91573 (0.236498s)][2.88171 (0.211945s)][1.81075 (0.210887s)]]
4863[[mpfr_float][4.90052 (0.295977s)][4.01118 (0.295017s)][2.62005 (0.305141s)]]
4864]
4865[table Operator construct(unsigned long long)
4866[[Backend][50 Bits][100 Bits][500 Bits]]
4867[[cpp_dec_float][[*1] (0.0610288s)][[*1] (0.0759005s)][[*1] (0.118511s)]]
4868[[gmp_float][8.26247 (0.504249s)][6.69042 (0.507806s)][4.32819 (0.51294s)]]
4869[[mpfr_float][10.1593 (0.620013s)][8.45884 (0.64203s)][5.51472 (0.653557s)]]
4870]
4871[table Operator str
4872[[Backend][50 Bits][100 Bits][500 Bits]]
4873[[cpp_dec_float][2.95848 (0.0223061s)][3.33461 (0.033471s)][3.0159 (0.132732s)]]
4874[[gmp_float][[*1] (0.00753971s)][[*1] (0.0100374s)][[*1] (0.0440106s)]]
4875[[mpfr_float][1.25424 (0.00945658s)][1.24943 (0.012541s)][1.09428 (0.0481601s)]]
4876]
4877
4878Test code was compiled with Microsoft Visual Studio 2010 with all optimisations
4879turned on (/Ox), and used MPIR-2.3.0 and [mpfr]-3.0.0. The tests were run on 32-bit
4880Windows Vista machine.
4881
4882[endsect]
4883
4884[section:integer_performance Integer Algorithm Performance]
4885
4886Note that these tests are carefully designed to test performance of the underlying algorithms
4887and not memory allocation or variable copying. As usual, performance results should be taken
4888with a healthy dose of scepticism, and real-world performance may vary widely depending upon the
4889specifics of the program. In each table relative times are given first, with the best performer
4890given a score of 1. Total actual times are given in brackets, measured in seconds for 500000
4891operations.
4892
4893[table Operator +
4894[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
4895[[cpp_int][1.23704 (0.0274266s)][1.09358 (0.0383278s)][1.26645 (0.0558828s)][1.32188 (0.0916899s)]]
4896[[cpp_int(fixed)][1.62044 (0.0359271s)][1.5277 (0.053543s)][1.73059 (0.076363s)][1.71537 (0.118983s)]]
4897[[gmp_int][1.87515 (0.0415741s)][1.21699 (0.042653s)][1.15599 (0.0510088s)][[*1] (0.0693631s)]]
4898[[tommath_int][[*1] (0.0221711s)][[*1] (0.035048s)][[*1] (0.0441255s)][1.04441 (0.0724435s)]]
4899]
4900[table Operator +(int)
4901[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
4902[[cpp_int][[*1] (0.0155377s)][[*1] (0.0209523s)][[*1] (0.0306377s)][[*1] (0.043125s)]]
4903[[cpp_int(fixed)][1.31904 (0.0204948s)][1.76211 (0.0369203s)][1.52941 (0.0468577s)][1.60412 (0.0691778s)]]
4904[[gmp_int][1.96204 (0.0304855s)][2.02569 (0.0424428s)][2.11505 (0.0648002s)][2.65993 (0.114709s)]]
4905[[tommath_int][14.0654 (0.218543s)][10.8239 (0.226786s)][7.76691 (0.23796s)][6.10039 (0.263079s)]]
4906]
4907[table Operator +(unsigned long long)
4908[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
4909[[cpp_int][[*1] (0.026624s)][[*1] (0.0291407s)][[*1] (0.0373209s)][[*1] (0.0464919s)]]
4910[[cpp_int(fixed)][1.31378 (0.034978s)][1.54897 (0.045138s)][1.53649 (0.0573431s)][1.27833 (0.0594319s)]]
4911[[gmp_int][25.5775 (0.680974s)][24.0117 (0.699717s)][19.5633 (0.730121s)][16.8939 (0.785432s)]]
4912[[tommath_int][19.4694 (0.518354s)][18.4246 (0.536907s)][14.7715 (0.551288s)][12.3637 (0.574812s)]]
4913]
4914[table Operator +=(unsigned long long)
4915[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
4916[[cpp_int][1.18405 (0.0196905s)][1.22304 (0.0206476s)][1.25861 (0.0217397s)][1.29525 (0.0220829s)]]
4917[[cpp_int(fixed)][[*1] (0.0166298s)][[*1] (0.0168822s)][[*1] (0.0172728s)][[*1] (0.0170492s)]]
4918[[gmp_int][39.9082 (0.663668s)][39.4584 (0.666147s)][38.5504 (0.665873s)][39.2231 (0.668722s)]]
4919[[tommath_int][30.6219 (0.509238s)][30.4135 (0.513447s)][30.9077 (0.533863s)][32.3086 (0.550835s)]]
4920]
4921[table Operator -
4922[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
4923[[cpp_int][1.06986 (0.0296064s)][[*1] (0.0381508s)][1.05932 (0.053186s)][1.1766 (0.0844721s)]]
4924[[cpp_int(fixed)][1.3304 (0.0368163s)][1.44506 (0.0551303s)][1.4431 (0.0724545s)][1.57255 (0.112898s)]]
4925[[gmp_int][1.48072 (0.0409761s)][1.19003 (0.0454007s)][1.0794 (0.0541942s)][[*1] (0.0717934s)]]
4926[[tommath_int][[*1] (0.0276731s)][1.10891 (0.0423057s)][[*1] (0.0502076s)][1.08479 (0.0778811s)]]
4927]
4928[table Operator -(int)
4929[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
4930[[cpp_int][[*1] (0.0147372s)][[*1] (0.0170001s)][[*1] (0.0232882s)][[*1] (0.0310734s)]]
4931[[cpp_int(fixed)][1.4267 (0.0210256s)][1.98887 (0.0338109s)][1.83788 (0.0428009s)][1.81269 (0.0563264s)]]
4932[[gmp_int][2.07504 (0.0305803s)][2.40928 (0.0409579s)][2.58711 (0.0602493s)][3.26438 (0.101435s)]]
4933[[tommath_int][13.5424 (0.199577s)][12.1793 (0.207048s)][9.28855 (0.216314s)][7.49327 (0.232842s)]]
4934]
4935[table Operator -(unsigned long long)
4936[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
4937[[cpp_int][[*1] (0.0277377s)][[*1] (0.0296807s)][[*1] (0.0372392s)][[*1] (0.0455855s)]]
4938[[cpp_int(fixed)][1.19867 (0.0332484s)][1.48639 (0.0441169s)][1.43253 (0.0533464s)][1.27697 (0.0582111s)]]
4939[[gmp_int][24.1794 (0.670683s)][22.9073 (0.679904s)][18.8758 (0.702922s)][16.5837 (0.755975s)]]
4940[[tommath_int][18.149 (0.503413s)][17.4116 (0.516787s)][14.0411 (0.52288s)][11.8237 (0.538987s)]]
4941]
4942[table Operator -=(unsigned long long)
4943[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
4944[[cpp_int][1.26896 (0.0203467s)][1.25722 (0.0206147s)][1.36108 (0.0225485s)][1.18351 (0.0226161s)]]
4945[[cpp_int(fixed)][[*1] (0.0160342s)][[*1] (0.0163971s)][[*1] (0.0165667s)][[*1] (0.0191094s)]]
4946[[gmp_int][41.1339 (0.659547s)][40.3982 (0.662411s)][39.925 (0.661425s)][34.636 (0.661874s)]]
4947[[tommath_int][31.1543 (0.499533s)][31.0303 (0.508806s)][30.7699 (0.509756s)][27.7054 (0.529434s)]]
4948]
4949[table Operator *
4950[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
4951[[cpp_int][1.11839 (0.0757577s)][1.61061 (0.207951s)][1.4501 (0.696912s)][1.72796 (2.64108s)]]
4952[[cpp_int(fixed)][1.01115 (0.0684934s)][1.28687 (0.166152s)][[*1] (0.480595s)][[*1] (1.52844s)]]
4953[[gmp_int][[*1] (0.0677384s)][[*1] (0.129113s)][1.09011 (0.523902s)][1.03374 (1.58s)]]
4954[[tommath_int][1.6322 (0.110562s)][2.71751 (0.350866s)][2.05222 (0.986288s)][2.0644 (3.15531s)]]
4955]
4956[table Operator *(int)
4957[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
4958[[cpp_int][1.01611 (0.0229536s)][1.12175 (0.0298152s)][1.16413 (0.0416439s)][1.31747 (0.0666043s)]]
4959[[cpp_int(fixed)][1.30215 (0.0294152s)][1.669 (0.0443606s)][1.72395 (0.0616701s)][1.88315 (0.095202s)]]
4960[[gmp_int][[*1] (0.0225897s)][[*1] (0.0265791s)][[*1] (0.0357725s)][[*1] (0.0505547s)]]
4961[[tommath_int][10.8281 (0.244603s)][10.1516 (0.26982s)][8.76424 (0.313519s)][8.04364 (0.406644s)]]
4962]
4963[table Operator *(unsigned long long)
4964[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
4965[[cpp_int][[*1] (0.0570721s)][[*1] (0.0856141s)][[*1] (0.143279s)][[*1] (0.252785s)]]
4966[[cpp_int(fixed)][1.10857 (0.0632686s)][1.2951 (0.110878s)][1.20827 (0.173121s)][1.18463 (0.299456s)]]
4967[[gmp_int][12.0605 (0.68832s)][8.13434 (0.696415s)][5.21762 (0.747577s)][3.11601 (0.787681s)]]
4968[[tommath_int][10.0524 (0.57371s)][7.33116 (0.627651s)][4.85202 (0.695193s)][3.35808 (0.848871s)]]
4969]
4970[table Operator *=(unsigned long long)
4971[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
4972[[cpp_int][111.27 (7.43118s)][67.7078 (7.34138s)][43.3851 (7.4075s)][25.3089 (7.55455s)]]
4973[[cpp_int(fixed)][[*1] (0.0667848s)][[*1] (0.108427s)][[*1] (0.170738s)][[*1] (0.298493s)]]
4974[[gmp_int][46.3718 (3.09693s)][28.4639 (3.08626s)][18.1719 (3.10264s)][10.5223 (3.14083s)]]
4975[[tommath_int][276.674 (18.4776s)][169.146 (18.34s)][108.491 (18.5236s)][63.3261 (18.9024s)]]
4976]
4977[table Operator /
4978[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
4979[[cpp_int][2.68035 (0.595251s)][2.04702 (0.707471s)][1.62314 (0.921536s)][1.43112 (1.38811s)]]
4980[[cpp_int(fixed)][[*1] (0.222079s)][[*1] (0.34561s)][[*1] (0.567748s)][[*1] (0.969945s)]]
4981[[gmp_int][3.79283 (0.842308s)][2.73668 (0.945824s)][1.86649 (1.05969s)][1.32141 (1.2817s)]]
4982[[tommath_int][13.2531 (2.94324s)][11.2054 (3.87271s)][9.83293 (5.58262s)][13.0164 (12.6252s)]]
4983]
4984[table Operator /(int)
4985[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
4986[[cpp_int][4.06026 (0.225473s)][3.45732 (0.340049s)][3.00195 (0.547957s)][2.80587 (0.978029s)]]
4987[[cpp_int(fixed)][2.43766 (0.135367s)][2.56264 (0.252052s)][2.44011 (0.445402s)][2.38009 (0.829617s)]]
4988[[gmp_int][[*1] (0.0555316s)][[*1] (0.0983563s)][[*1] (0.182534s)][[*1] (0.348566s)]]
4989[[tommath_int][35.9988 (1.99907s)][27.1024 (2.66569s)][21.8333 (3.98531s)][25.8066 (8.99528s)]]
4990]
4991[table Operator /(unsigned long long)
4992[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
4993[[cpp_int][1.50505 (0.705756s)][1.39347 (1.58556s)][2.63348 (3.57438s)][4.75451 (8.52733s)]]
4994[[cpp_int(fixed)][[*1] (0.468925s)][1.12378 (1.27869s)][2.29966 (3.12128s)][4.4844 (8.04288s)]]
4995[[gmp_int][2.17234 (1.01866s)][[*1] (1.13785s)][[*1] (1.35728s)][[*1] (1.79352s)]]
4996[[tommath_int][4.74612 (2.22557s)][2.70088 (3.07319s)][3.65634 (4.96268s)][6.79408 (12.1853s)]]
4997]
4998[table Operator /=(unsigned long long)
4999[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5000[[cpp_int][1.76281 (0.0574966s)][1.76471 (0.0604224s)][1.56085 (0.0716403s)][1.31422 (0.124043s)]]
5001[[cpp_int(fixed)][[*1] (0.0326164s)][[*1] (0.0342393s)][[*1] (0.0458981s)][[*1] (0.0943852s)]]
5002[[gmp_int][20.2862 (0.661664s)][19.4043 (0.664389s)][14.4881 (0.664976s)][7.14238 (0.674135s)]]
5003[[tommath_int][32.9555 (1.07489s)][30.1525 (1.0324s)][22.8324 (1.04796s)][11.7456 (1.10861s)]]
5004]
5005[table Operator %
5006[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5007[[cpp_int][1.8501 (0.364131s)][1.46527 (0.476653s)][1.27509 (0.689738s)][1.20064 (1.11769s)]]
5008[[cpp_int(fixed)][[*1] (0.196817s)][[*1] (0.325301s)][[*1] (0.540932s)][[*1] (0.930916s)]]
5009[[gmp_int][3.2533 (0.640305s)][2.15441 (0.700832s)][1.47898 (0.800029s)][1.07439 (1.00016s)]]
5010[[tommath_int][15.3501 (3.02116s)][12.1106 (3.9396s)][11.0689 (5.98752s)][13.5535 (12.6172s)]]
5011]
5012[table Operator %(int)
5013[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5014[[cpp_int][1.82761 (0.104331s)][2.01496 (0.202512s)][2.10004 (0.389523s)][2.17252 (0.768097s)]]
5015[[cpp_int(fixed)][1.78851 (0.102099s)][1.96844 (0.197838s)][2.02956 (0.376451s)][2.07257 (0.73276s)]]
5016[[gmp_int][[*1] (0.057086s)][[*1] (0.100505s)][[*1] (0.185483s)][[*1] (0.353552s)]]
5017[[tommath_int][36.3018 (2.07233s)][26.3075 (2.64402s)][21.9525 (4.07183s)][25.6759 (9.07775s)]]
5018]
5019[table Operator construct
5020[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5021[[cpp_int][1.40211 (0.0026854s)][[*1] (0.00278639s)][[*1] (0.00322813s)][[*1] (0.0027185s)]]
5022[[cpp_int(fixed)][[*1] (0.00191526s)][1.40721 (0.00392103s)][1.90346 (0.00614463s)][2.14621 (0.00583447s)]]
5023[[gmp_int][98.705 (0.189046s)][68.9726 (0.192184s)][58.8994 (0.190135s)][70.0525 (0.190438s)]]
5024[[tommath_int][105.602 (0.202255s)][74.1994 (0.206748s)][63.6455 (0.205456s)][76.8935 (0.209035s)]]
5025]
5026[table Operator construct(unsigned)
5027[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5028[[cpp_int][1.73436 (0.00348927s)][[*1] (0.00263476s)][[*1] (0.0027009s)][[*1] (0.00318651s)]]
5029[[cpp_int(fixed)][[*1] (0.00201185s)][1.36851 (0.0036057s)][2.07362 (0.00560064s)][1.66856 (0.00531688s)]]
5030[[gmp_int][97.2414 (0.195635s)][76.3759 (0.201232s)][72.7396 (0.196462s)][63.8129 (0.20334s)]]
5031[[tommath_int][210.112 (0.422713s)][162.652 (0.42855s)][158.33 (0.427634s)][134.626 (0.428987s)]]
5032]
5033[table Operator construct(unsigned long long)
5034[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5035[[cpp_int][2.34403 (0.00739542s)][1.66376 (0.00713834s)][1.22989 (0.0074969s)][1.23708 (0.00711417s)]]
5036[[cpp_int(fixed)][[*1] (0.00315501s)][[*1] (0.00429049s)][[*1] (0.00609561s)][[*1] (0.0057508s)]]
5037[[gmp_int][222.866 (0.703144s)][164.331 (0.705059s)][115.363 (0.70321s)][122.347 (0.703596s)]]
5038[[tommath_int][218.681 (0.689941s)][163.796 (0.702765s)][114.57 (0.698376s)][122.422 (0.704027s)]]
5039]
5040[table Operator gcd
5041[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5042[[cpp_int][1.16358 (2.74442s)][1.39847 (8.11559s)][1.64677 (22.2518s)][1.95096 (64.4961s)]]
5043[[cpp_int(fixed)][[*1] (2.35859s)][1.30986 (7.60133s)][1.67681 (22.6577s)][2.0895 (69.0758s)]]
5044[[gmp_int][1.03392 (2.4386s)][[*1] (5.80319s)][[*1] (13.5124s)][[*1] (33.0586s)]]
5045[[tommath_int][5.25978 (12.4057s)][4.4619 (25.8932s)][4.15577 (56.1542s)][3.91192 (129.323s)]]
5046]
5047[table Operator powm
5048[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5049[[cpp_int][2.50722 (2.91621s)][3.5561 (13.406s)][4.37066 (73.483s)][4.88831 (473.91s)]]
5050[[cpp_int(fixed)][1.93385 (2.24931s)][3.18107 (11.9922s)][4.20753 (70.7403s)][4.8158 (466.88s)]]
5051[[gmp_int][[*1] (1.16313s)][[*1] (3.76986s)][[*1] (16.8128s)][[*1] (96.9476s)]]
5052[[tommath_int][1.44081 (1.67584s)][1.8794 (7.08507s)][2.19115 (36.8394s)][2.17186 (210.557s)]]
5053]
5054[table Operator str
5055[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5056[[cpp_int][1.17175 (0.00160006s)][1.41999 (0.00329476s)][1.40856 (0.00813784s)][1.52964 (0.0229767s)]]
5057[[cpp_int(fixed)][[*1] (0.00136554s)][[*1] (0.00232027s)][[*1] (0.00577741s)][1.14754 (0.0172372s)]]
5058[[gmp_int][1.50501 (0.00205515s)][1.52968 (0.00354926s)][1.01989 (0.0058923s)][[*1] (0.015021s)]]
5059[[tommath_int][12.2161 (0.0166816s)][16.9577 (0.0393463s)][18.7474 (0.108311s)][22.7368 (0.341528s)]]
5060]
5061[table Operator |
5062[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5063[[cpp_int][[*1] (0.0301617s)][[*1] (0.0423404s)][[*1] (0.0522358s)][[*1] (0.0813156s)]]
5064[[cpp_int(fixed)][1.0638 (0.0320861s)][1.22566 (0.0518951s)][1.28515 (0.0671305s)][1.16118 (0.094422s)]]
5065[[gmp_int][1.76553 (0.0532514s)][1.51489 (0.0641408s)][1.70708 (0.0891706s)][1.77346 (0.14421s)]]
5066[[tommath_int][4.37637 (0.131999s)][3.46212 (0.146587s)][2.91875 (0.152463s)][4.19621 (0.341217s)]]
5067]
5068[table Operator |(int)
5069[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5070[[cpp_int][[*1] (0.0289129s)][[*1] (0.0351119s)][[*1] (0.0406779s)][[*1] (0.0525891s)]]
5071[[cpp_int(fixed)][1.06091 (0.030674s)][1.25979 (0.0442336s)][1.36194 (0.0554009s)][1.37438 (0.0722772s)]]
5072[[gmp_int][4.92854 (0.142498s)][4.34687 (0.152627s)][3.71442 (0.151095s)][2.981 (0.156768s)]]
5073[[tommath_int][10.9847 (0.317598s)][9.37065 (0.329021s)][8.53651 (0.347248s)][11.2155 (0.589813s)]]
5074]
5075[table Operator ^
5076[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5077[[cpp_int][[*1] (0.0305149s)][[*1] (0.04217s)][[*1] (0.0525977s)][[*1] (0.0816632s)]]
5078[[cpp_int(fixed)][1.01544 (0.0309861s)][1.24872 (0.0526585s)][1.26661 (0.066621s)][1.15965 (0.0947007s)]]
5079[[gmp_int][1.64675 (0.0502505s)][1.47181 (0.0620663s)][1.66038 (0.0873322s)][1.67895 (0.137108s)]]
5080[[tommath_int][4.30668 (0.131418s)][3.45859 (0.145849s)][2.91462 (0.153303s)][4.15538 (0.339342s)]]
5081]
5082[table Operator ^(int)
5083[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5084[[cpp_int][1.01566 (0.0296088s)][[*1] (0.0356634s)][[*1] (0.0401898s)][[*1] (0.0514097s)]]
5085[[cpp_int(fixed)][[*1] (0.0291524s)][1.2393 (0.0441976s)][1.38556 (0.0556856s)][1.38899 (0.0714075s)]]
5086[[gmp_int][4.68027 (0.136441s)][4.15243 (0.14809s)][3.74237 (0.150405s)][3.0483 (0.156712s)]]
5087[[tommath_int][10.919 (0.318314s)][9.16311 (0.326788s)][8.62554 (0.346659s)][11.6212 (0.597442s)]]
5088]
5089[table Operator &
5090[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5091[[cpp_int][1.0346 (0.0303431s)][[*1] (0.0427309s)][[*1] (0.0535587s)][1.06945 (0.0828084s)]]
5092[[cpp_int(fixed)][[*1] (0.0293284s)][1.10435 (0.04719s)][1.05262 (0.0563769s)][[*1] (0.0774309s)]]
5093[[gmp_int][1.86057 (0.0545675s)][1.58432 (0.0676995s)][1.69164 (0.0906018s)][1.86625 (0.144505s)]]
5094[[tommath_int][4.4157 (0.129506s)][3.60396 (0.154s)][2.95985 (0.158525s)][4.4032 (0.340944s)]]
5095]
5096[table Operator &(int)
5097[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5098[[cpp_int][1.05874 (0.038946s)][[*1] (0.0483903s)][[*1] (0.063842s)][[*1] (0.100361s)]]
5099[[cpp_int(fixed)][[*1] (0.0367853s)][1.05827 (0.0512099s)][1.09114 (0.0696605s)][1.09432 (0.109826s)]]
5100[[gmp_int][3.92298 (0.144308s)][2.99447 (0.144903s)][2.228 (0.14224s)][1.42296 (0.142809s)]]
5101[[tommath_int][8.79208 (0.323419s)][7.02288 (0.339839s)][5.65271 (0.36088s)][6.27104 (0.629365s)]]
5102]
5103[table Operator <<
5104[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5105[[cpp_int][[*1] (0.0248801s)][1.23196 (0.04s)][[*1] (0.0424149s)][[*1] (0.060157s)]]
5106[[cpp_int(fixed)][1.08931 (0.027102s)][1.40572 (0.0456418s)][1.3475 (0.0571542s)][1.24573 (0.0749397s)]]
5107[[gmp_int][1.05561 (0.0262636s)][[*1] (0.0324686s)][1.09914 (0.0466199s)][1.16315 (0.0699719s)]]
5108[[tommath_int][1.60497 (0.0399319s)][2.13048 (0.0691737s)][2.31219 (0.0980712s)][2.74695 (0.165248s)]]
5109]
5110[table Operator >>
5111[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5112[[cpp_int][[*1] (0.0213349s)][1.02127 (0.0295019s)][[*1] (0.0327116s)][1.13168 (0.0433804s)]]
5113[[cpp_int(fixed)][1.13514 (0.0242181s)][1.16938 (0.0337803s)][1.46999 (0.0480859s)][1.60077 (0.061362s)]]
5114[[gmp_int][1.26614 (0.0270129s)][[*1] (0.0288873s)][1.42219 (0.0465221s)][[*1] (0.0383329s)]]
5115[[tommath_int][12.0066 (0.25616s)][10.2837 (0.297067s)][9.99696 (0.327017s)][16.0943 (0.616942s)]]
5116]
5117
5118Test code was compiled with Microsoft Visual Studio 2010 with all optimisations
5119turned on (/Ox), and used MPIR-2.3.0 and [mpfr]-3.0.0. The tests were run on 32-bit
5120Windows Vista machine.
5121
5122Linux x86_64 results are broadly similar, except that libtommath performs much better there.
5123
5124[endsect]
5125
5126[section:rational_performance Rational Type Performance]
5127
5128Note that these tests are carefully designed to test performance of the underlying algorithms
5129and not memory allocation or variable copying. As usual, performance results should be taken
5130with a healthy dose of scepticism, and real-world performance may vary widely depending upon the
5131specifics of the program. In each table relative times are given first, with the best performer
5132given a score of 1. Total actual times are given in brackets, measured in seconds for 500000
5133operations.
5134
5135[table Operator +
5136[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5137[[cpp_rational][5.89417 (18.4116s)][6.87256 (47.4698s)][6.65008 (107.715s)][6.53801 (256.244s)]]
5138[[mpq_rational][[*1] (3.1237s)][[*1] (6.90715s)][[*1] (16.1975s)][[*1] (39.1929s)]]
5139]
5140[table Operator +(int)
5141[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5142[[cpp_rational][3.62367 (2.46488s)][4.18291 (2.94603s)][4.726 (3.74866s)][6.1388 (5.56817s)]]
5143[[mpq_rational][[*1] (0.680215s)][[*1] (0.704303s)][[*1] (0.7932s)][[*1] (0.907046s)]]
5144]
5145[table Operator +(unsigned long long)
5146[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5147[[cpp_rational][1.1527 (2.6378s)][1.31751 (3.09863s)][1.58996 (4.00714s)][2.15642 (5.75702s)]]
5148[[mpq_rational][[*1] (2.28837s)][[*1] (2.35189s)][[*1] (2.52028s)][[*1] (2.66971s)]]
5149]
5150[table Operator +=(unsigned long long)
5151[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5152[[cpp_rational][1.18436 (2.7059s)][1.32279 (3.11099s)][1.61398 (4.05389s)][2.20048 (5.84623s)]]
5153[[mpq_rational][[*1] (2.2847s)][[*1] (2.35183s)][[*1] (2.51174s)][[*1] (2.6568s)]]
5154]
5155[table Operator -
5156[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5157[[cpp_rational][5.81893 (18.3457s)][6.82209 (47.1928s)][6.64143 (107.498s)][6.51362 (255.137s)]]
5158[[mpq_rational][[*1] (3.15277s)][[*1] (6.91765s)][[*1] (16.1859s)][[*1] (39.1698s)]]
5159]
5160[table Operator -(int)
5161[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5162[[cpp_rational][3.72441 (2.48756s)][4.27663 (2.98713s)][4.62109 (3.72114s)][6.17605 (5.56503s)]]
5163[[mpq_rational][[*1] (0.667908s)][[*1] (0.698479s)][[*1] (0.805252s)][[*1] (0.901066s)]]
5164]
5165[table Operator -(unsigned long long)
5166[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5167[[cpp_rational][1.15627 (2.63239s)][1.32096 (3.12092s)][1.61044 (4.00106s)][2.19378 (5.7644s)]]
5168[[mpq_rational][[*1] (2.27663s)][[*1] (2.36262s)][[*1] (2.48445s)][[*1] (2.62761s)]]
5169]
5170[table Operator -=(unsigned long long)
5171[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5172[[cpp_rational][1.1984 (2.73444s)][1.34141 (3.15698s)][1.64159 (4.06997s)][2.23017 (5.88108s)]]
5173[[mpq_rational][[*1] (2.28174s)][[*1] (2.35348s)][[*1] (2.47929s)][[*1] (2.63706s)]]
5174]
5175[table Operator *
5176[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5177[[cpp_rational][5.4306 (32.5882s)][6.91805 (89.9436s)][6.94556 (207.307s)][6.88704 (492.151s)]]
5178[[mpq_rational][[*1] (6.00084s)][[*1] (13.0013s)][[*1] (29.8475s)][[*1] (71.4604s)]]
5179]
5180[table Operator *(int)
5181[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5182[[cpp_rational][2.12892 (2.51376s)][2.47245 (3.07841s)][2.86832 (3.93619s)][3.94086 (6.02565s)]]
5183[[mpq_rational][[*1] (1.18077s)][[*1] (1.24508s)][[*1] (1.3723s)][[*1] (1.52902s)]]
5184]
5185[table Operator *(unsigned long long)
5186[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5187[[cpp_rational][1.32254 (5.43565s)][1.56078 (6.73163s)][1.97701 (9.32522s)][2.85404 (15.1573s)]]
5188[[mpq_rational][[*1] (4.11002s)][[*1] (4.313s)][[*1] (4.71682s)][[*1] (5.31082s)]]
5189]
5190[table Operator *=(unsigned long long)
5191[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5192[[cpp_rational][6.29806 (58.1188s)][6.30556 (59.5076s)][6.3385 (62.1007s)][6.55345 (67.6905s)]]
5193[[mpq_rational][[*1] (9.22804s)][[*1] (9.43733s)][[*1] (9.79739s)][[*1] (10.329s)]]
5194]
5195[table Operator /
5196[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5197[[cpp_rational][4.4269 (66.8031s)][6.40103 (173.527s)][6.32347 (348.193s)][6.61148 (824.063s)]]
5198[[mpq_rational][[*1] (15.0903s)][[*1] (27.1093s)][[*1] (55.0637s)][[*1] (124.641s)]]
5199]
5200[table Operator /(int)
5201[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5202[[cpp_rational][1.78772 (2.50984s)][2.10623 (3.10606s)][2.46986 (3.99358s)][3.37428 (5.96678s)]]
5203[[mpq_rational][[*1] (1.40393s)][[*1] (1.4747s)][[*1] (1.61693s)][[*1] (1.76831s)]]
5204]
5205[table Operator /(unsigned long long)
5206[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5207[[cpp_rational][1.29695 (5.45454s)][1.55248 (6.85353s)][1.93237 (9.28765s)][2.75211 (14.8541s)]]
5208[[mpq_rational][[*1] (4.20568s)][[*1] (4.41458s)][[*1] (4.80635s)][[*1] (5.39734s)]]
5209]
5210[table Operator /=(unsigned long long)
5211[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5212[[cpp_rational][6.19401 (58.4278s)][6.20135 (59.643s)][6.21327 (62.0338s)][6.40576 (67.6778s)]]
5213[[mpq_rational][[*1] (9.43295s)][[*1] (9.61774s)][[*1] (9.98407s)][[*1] (10.5652s)]]
5214]
5215[table Operator construct
5216[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5217[[cpp_rational][[*1] (0.00978288s)][[*1] (0.0100574s)][[*1] (0.0101393s)][[*1] (0.0101847s)]]
5218[[mpq_rational][39.1516 (0.383015s)][38.3523 (0.385725s)][37.5812 (0.381048s)][37.6007 (0.382953s)]]
5219]
5220[table Operator construct(unsigned)
5221[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5222[[cpp_rational][[*1] (0.0548151s)][[*1] (0.0557542s)][[*1] (0.055825s)][[*1] (0.0552808s)]]
5223[[mpq_rational][7.21073 (0.395257s)][7.1016 (0.395944s)][7.02046 (0.391917s)][7.16881 (0.396297s)]]
5224]
5225[table Operator construct(unsigned long long)
5226[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5227[[cpp_rational][[*1] (0.0605156s)][[*1] (0.0616657s)][[*1] (0.0592056s)][[*1] (0.0603081s)]]
5228[[mpq_rational][35.1604 (2.12775s)][34.7575 (2.14335s)][35.7232 (2.11502s)][35.0437 (2.11342s)]]
5229]
5230[table Operator str
5231[[Backend][128 Bits][256 Bits][512 Bits][1024 Bits]]
5232[[cpp_rational][5.48898 (0.0208949s)][8.49668 (0.0546688s)][10.107 (0.121897s)][10.5339 (0.310584s)]]
5233[[mpq_rational][[*1] (0.0038067s)][[*1] (0.00643413s)][[*1] (0.0120606s)][[*1] (0.0294843s)]]
5234]
5235
5236Test code was compiled with Microsoft Visual Studio 2010 with all optimisations
5237turned on (/Ox), and used MPIR-2.3.0 and [mpfr]-3.0.0. The tests were run on 32-bit
5238Windows Vista machine.
5239
5240[endsect]
5241
5242[endsect]
5243
5244[section:map Roadmap]
5245
5246[section:hist History]
5247
5248[h4 Multiprecision-2.3.0 (Boost-1.63)]
5249
5250* Added support for all the C99 math functions.
5251* Extended generic-interconversions to handle narrowing cases as well, changed convert_to member function and hence explicit
5252conversion operators to use the same conversion code as the explicit constructors.
5253* Fix IO stream parsing error, see [@https://svn.boost.org/trac/boost/ticket/12488 #12488].
5254* Make default constructed floating point types all zero for consistency, see [@https://svn.boost.org/trac/boost/ticket/12500 #12500].
5255* Fix conversion of cpp_bin_float to float/double/long double when the exponent value would overflow an int, see [@https://svn.boost.org/trac/boost/ticket/12512 #12512].
5256* Fix cpp_bin_float subtractions that yield signed-zeros, see [@https://svn.boost.org/trac/boost/ticket/12524 #12524].
5257* Fix ceil/trunc/round applied to cpp_bin_float and yielding a signed zero, see [@https://svn.boost.org/trac/boost/ticket/12525 #12525].
5258
5259[h4 Multiprecision-2.2.8 (Boost-1.62)]
5260
5261* Added support for hashing via `Boost.Hash` or `std::hash`.
5262* Fixed some arithmetic operations in cpp_bin_float and cpp_dec_float that should generate a NaN, see [@https://svn.boost.org/trac/boost/ticket/12157 #12157].
5263* Prevent inadvertant instantiation of variable-precision `mpfr_float_backend` with fixed allocation.
5264* Fixed division over/underflow in cpp_bin_float, see [@https://svn.boost.org/trac/boost/ticket/12167 #12167].
5265* Added support for signed-zeros throughout the library, including support for `signbit` and `copysign`, mpfr, float128, and cpp_bin_float types
5266should now respect signed-zeros correctly.
5267* Fixed bug in conversion of cpp_bin_float infinities to double etc, see [@https://svn.boost.org/trac/boost/ticket/12196 #12196].
5268* Fix add and subtract of cpp_bin_float when the exponents would overflow., see [@https://svn.boost.org/trac/boost/ticket/12198 #12198].
5269* Improve variable-precision support in mpfr and mpf backends, allow these types to be used with Boost.Math.
5270* Fixed bug in subtraction of signed infinities in cpp_bin_float, see [@https://svn.boost.org/trac/boost/ticket/12209 #12209].
5271* Fix result of sqrt(infinity) in cpp_bin_float (result should be infinity), see [@https://svn.boost.org/trac/boost/ticket/12227 #12227].
5272* Added workaround in gmp.hpp for recent MPIR releases which are not quite source-compatible with GMP on Windows x64.
5273* Allow `cpp_int` code to be used with /RTCc with MSVC.
5274* Fix conversion of `cpp_int` to signed integer when the result is INT_MIN, see [@https://svn.boost.org/trac/boost/ticket/12343 #12343].
5275* Update uBlas support to match latest uBlas code.
5276* Fix some errors present when building on big-endian machines (not all `cpp_int` constructors are available on non-little-endian machines).
5277* Fix fencepost error in rational to float conversion routines, see [@https://svn.boost.org/trac/boost/ticket/12327 #12327].
5278* Fix some Oracle C++ compiler compatibility issues.
5279* Add modf support to complete C90 compatibility.
5280* Fix self assignment bug in expression template code for expressions such as `a = a * a * a`, see [@https://svn.boost.org/trac/boost/ticket/12408 #12408].
5281* Fixed some compiler errors that occur when converting from `cpp_int` to `cpp_bin_float`.
5282
5283[h4 Multiprecision-2.2.7 (Boost-1.61)]
5284
5285* Fixed bug in stream input for integer types, see [@https://svn.boost.org/trac/boost/ticket/11857 #11857].
5286* Fixed some ambiguous conversions involving expression templates see [@https://svn.boost.org/trac/boost/ticket/11922 #11922].
5287* Add expression template aware min/max overloads see [@https://svn.boost.org/trac/boost/ticket/11149 #11149].
5288* Fix bug in right shifting negative small integers in cpp_int see [@https://svn.boost.org/trac/boost/ticket/11999 #11999].
5289* Use memmove for bitshifts in cpp_int when possible see [@https://svn.boost.org/trac/boost/ticket/9233 #9233].
5290* Use memcpy for data import into cpp_int where possible, see [@https://svn.boost.org/trac/boost/ticket/9235 #9235].
5291* Changed `cpp_bin_float.convert_to<double>()` to a function template rather than proceding via `long double` to avoid
5292double-rounding bug, see [@https://svn.boost.org/trac/boost/ticket/12039 #12039].
5293* Fixed conversions from NaN's and Infinities, see [@https://svn.boost.org/trac/boost/ticket/12112 #12112].
5294* Enabled better support for Clang on Windows.
5295* Fixed handling of NaN's and Infinities in basic arithmetic for cpp_dec_float and cpp_bin_float, see [@https://svn.boost.org/trac/boost/ticket/12090 #12090].
5296* Fixed fencepost error in cpp_bin_float subtraction.
5297* Fixed double-rounding in conversion to float routines for cpp_bin_float, see [@https://svn.boost.org/trac/boost/ticket/12039 #12039].
5298* Make float128 denorm aware, see [@https://svn.boost.org/trac/boost/ticket/12075 #12075].
5299* Allow the library and tests to be used without exception handling support, see [@https://svn.boost.org/trac/boost/ticket/12070 #12070].
5300* Fixed buggy comparison operator overloads for boost::rational.
5301* Added some workarounds for Oracle C++.
5302* Fixed some missing typecasts for cases where cpp_int's limb_type is wider than unsigned.
5303
5304
5305[h4 Multiprecision-2.2.6 (Boost-1.60)]
5306
5307* Fixed result of Miller Rabin primality test for value 2, see [@https://svn.boost.org/trac/boost/ticket/11495 #11495].
5308* Improved initialization of cpp_int from very large strings of hex or octal digits, see [@https://svn.boost.org/trac/boost/ticket/11590 #11590].
5309* Fixed fmod behaviour for negative divisors, see [@https://svn.boost.org/trac/boost/ticket/11641 #11641].
5310* Fixed infinite division loop in cpp_int special case, see [@https://svn.boost.org/trac/boost/ticket/11648 #11648].
5311* Patched missing return statement in [@https://svn.boost.org/trac/boost/ticket/11762 #11762].
5312* Fixed mixed mode arithmetic compiler error in [@https://svn.boost.org/trac/boost/ticket/11764 #11764].
5313* Fixed over-aggressive use of noexcept in [@https://svn.boost.org/trac/boost/ticket/11826 #11826].
5314
5315
5316[h4 Multiprecision-2.2.5 (Boost-1.59)]
5317
5318* Depricated boost/multiprecision/random.hpp as it's no longer needed, updated random examples to match.
5319* Fixed a bug in cpp_int's right shift operator when shifting negative values - semantics now gives the
5320same values as shifting 2's compliment integers, though not the same bit pattern.
5321* Fixed support for GCC-4.6.4 in C++0x mode by disabling conditional noexcept suppoprt for that compiler
5322see [@https://svn.boost.org/trac/boost/ticket/11402 #11402].
5323* Suppressed numerous compiler warnings.
5324
5325[h4 Multiprecision-2.2.4 (Boost-1.58)]
5326
5327* Changed `frexp` to always be non-expression template generating, see: [@https://svn.boost.org/trac/boost/ticket/10993 10993].
5328* Improved support of cpp_dec_float on Cygwin and other platforms with missing long double support, see [@https://svn.boost.org/trac/boost/ticket/10924 10924].
5329* Improved noexcept support and added some more tests, see [@https://svn.boost.org/trac/boost/ticket/10990 10990].
5330* Various workarounds applied for Intel-15.0 and Solaris-12.4 compilers.
5331
5332[h4 Multiprecision-2.2.3 (Boost-1.57)]
5333
5334* Changed rational to float conversions to exactly round to nearest, see [@https://svn.boost.org/trac/boost/ticket/10085 10085].
5335* Added improved generic float to rational conversions.
5336* Fixed rare bug in exponent function for __cpp_bin_float.
5337* Fixed various minor documentation issues.
5338
5339[h4 Multiprecision-2.2.2 (Boost-1.56)]
5340
5341* Change floating-point to rational conversions to be implicit, see [@https://svn.boost.org/trac/boost/ticket/10082 10082].
5342* Fix definition of checked_cpp_rational typedef.
5343
5344[h4 Multiprecision-2.2.1]
5345
5346* Fix bug in assignment from string in cpp_int, see [@https://svn.boost.org/trac/boost/ticket/9936 9936].
5347
5348[h4 Multiprecision-2.2.0]
5349
5350* Moved to Boost.Multiprecision specific version number - we have one breaking change in Boost-1.54
5351which makes this major version 2, plus two releases with new features since then.
5352* Added new __cpp_bin_float backend for binary floating-point.
5353* Added MSVC-specific #include for compiler intrinsics, see [@https://svn.boost.org/trac/boost/ticket/9336 9336].
5354* Fixed various typos in docs, see [@https://svn.boost.org/trac/boost/ticket/9432 9432].
5355* Fixed __gmp_rational to allow move-copy from an already copied-from object, see [@https://svn.boost.org/trac/boost/ticket/9497 9497].
5356* Added list of values for numeric_limits.
5357
5358[h4 Boost-1.55]
5359
5360* Added support for Boost.Serialization.
5361* Suppressed some GCC warnings. See [@https://svn.boost.org/trac/boost/ticket/8872 8872].
5362* Fixed bug in pow for large integer arguments. See [@https://svn.boost.org/trac/boost/ticket/8809 8809].
5363* Fixed bug in pow for calculation of 0[super N]. See [@https://svn.boost.org/trac/boost/ticket/8798 8798].
5364* Fixed bug in fixed precision cpp_int IO code that causes conversion to string to fail when the
5365bit count is very small (less than CHAR_BIT). See [@https://svn.boost.org/trac/boost/ticket/8745 8745].
5366* Fixed bug in cpp_int that causes left shift to fail when a fixed precision type would overflow.
5367See [@https://svn.boost.org/trac/boost/ticket/8741 8741].
5368* Fixed some cosmetic warnings from cpp_int. See [@https://svn.boost.org/trac/boost/ticket/8748 8748].
5369* Fixed calls to functions which are required to be macros in C99. See [@https://svn.boost.org/trac/boost/ticket/8732 8732].
5370* Fixed bug that causes construction from INT_MIN, LONG_MIN etc to fail in cpp_int. See [@https://svn.boost.org/trac/boost/ticket/8711 8711].
5371
5372[h4 1.54]
5373
5374* [*Breaking change] renamed `rational_adapter` to `rational_adaptor`.
5375* Add support for [mpfi].
5376* Add logged_adaptor.
5377* Add support for 128-bit floats via GCC's `__float128` or Intel's `_Quad` data types.
5378* Add support for user-defined literals in cpp_int, improve `constexpr` support.
5379* Fixed bug in integer division of `cpp_int` that results in incorrect sign of `cpp_int` when both arguments are small enough
5380to fit in a `double_limb_type`. See [@https://svn.boost.org/trac/boost/ticket/8126 8126].
5381* Fixed bug in subtraction of a single limb in `cpp_int` that results in incorrect value when the result should have a 0
5382in the last limb: [@https://svn.boost.org/trac/boost/ticket/8133 8133].
5383* Fixed bug in `cpp_int` where division of 0 by something doesn't get zero in the result: [@https://svn.boost.org/trac/boost/ticket/8160 8160].
5384* Fixed bug in some transcendental functions that caused incorrect return values when variables are reused, for example with
5385`a = pow(a, b)`. See [@https://svn.boost.org/trac/boost/ticket/8326 8326].
5386* Fixed some assignment operations in the mpfr and gmp backends to be safe if the target has been moved from: [@https://svn.boost.org/trac/boost/ticket/8326 8667].
5387* Fixed bug in `cpp_int` that gives incorrect answer for 0%N for large N: [@https://svn.boost.org/trac/boost/ticket/8670 8670].
5388* Fixed set_precision in mpfr backend so it doesn't trample over an existing value: [@https://svn.boost.org/trac/boost/ticket/8692 8692].
5389
5390[h4 1.53]
5391
5392* First Release.
5393* Fix bug in [@https://svn.boost.org/trac/boost/ticket/7878 cpp_int division].
5394* Fix issue [@https://svn.boost.org/trac/boost/ticket/7806 #7806].
5395
5396[h4 Post review changes]
5397
5398* Non-expression template operators further optimised with rvalue reference support.
5399* Many functions made `constexp`.
5400* Differentiate between explicit and implicit conversions in the number constructor.
5401* Removed "mp_" prefix from types.
5402* Allowed mixed precision arithmetic.
5403* Changed ExpressionTemplates parameter to class `number` to use enumerated values rather than true/false.
5404* Changed ExpressionTemplate parameter default value to use a traits class so that the default value depends on the backend used.
5405* Added support for fused-multiply-add/subtract with GMP support.
5406* Tweaked expression template unpacking to use fewer temporaries when the LHS also appears in the RHS.
5407* Refactored `cpp_int_backend` based on review comments with new template parameter structure.
5408* Added additional template parameter to `mpfr_float_backend` to allow stack-based allocation.
5409* Added section on mixed precision arithmetic, and added support for operations yielding a higher precision result
5410than either of the arguments.
5411* Added overloads of integer-specific functions for built in integer types.
5412
5413[h4 Pre-review history]
5414
5415*2011-2012, John Maddock adds an expression template enabled front end to Christopher's code,
5416and adds support for other backends.
5417* 2011, Christopher Kormanyos publishes the decimal floating-point code under the Boost
5418Software Licence. The code is published as: [@http://doi.acm.org/10.1145/1916461.1916469
5419"Algorithm 910: A Portable C++ Multiple-Precision
5420System for Special-Function Calculations"], in ACM TOMS, {VOL 37, ISSUE 4, (February 2011)} (C) ACM,
54212011.
5422* 2002-2011, Christopher Kormanyos develops the all C++ decimal arithmetic floating-point
5423code.
5424
5425[endsect]
5426
5427[section:todo TODO]
5428
5429
5430
5431More a list of what ['could] be done, rather than what ['should] be done (which may be a much smaller list!).
5432
5433* Add back-end support for libdecNumber.
5434* Add an adaptor back-end for complex number types.
5435* Add better multiplication routines (Karatsuba, FFT etc) to cpp_int_backend.
5436* Add assembly level routines to cpp_int_backend.
5437* Can ring types (exact floating-point types) be supported? The answer should be yes, but someone needs to write it,
5438the hard part is IO and binary-decimal conversion.
5439* Should there be a choice of rounding mode (probably MPFR specific)?
5440* We can reuse temporaries in multiple subtrees (temporary caching).
5441* cpp_dec_float should round to nearest.
5442* A 2's complement fixed precision int that uses exactly N bits and no more.
5443
5444Things requested in review:
5445
5446* The performances of mp_number<a_trivial_adaptor<float>, false>respect to
5447float and mp_number<a_trivial_adaptor<int>, false> and int should be
5448given to show the cost of using the generic interface (Mostly done, just need to update docs to the latest results).
5449* Should we provide min/max overloads for expression templates? (Not done - we can't overload functions declared in the std namespace :-( ).
5450* The rounding applied when converting must be documented (Done).
5451* Document why we don't abstract out addition/multiplication algorithms etc. (done - FAQ)
5452* Document why we don't use proto (compile times) (Done).
5453* We can reuse temporaries in multiple subtrees (temporary caching) Moved to TODO list.
5454* Emphasise in the docs that ET's may reorder operations (done 2012/10/31).
5455* Document what happens to small fixed precision cpp_int's (done 2012/10/31).
5456* The use of bool in template parameters could be improved by the use of
5457an enum class which will be more explicit. E.g `enum class expression_template {disabled, enabled};
5458enum class sign {unsigned, signed};` (Partly done 2012/09/15, done 2012/10/31).
5459* Each back-end should document the requirements it satisfies (not currently scheduled for inclusion: it's
5460deliberately an implementation detail, and "optional" requirements are optimisations which can't be detected
5461by the user). Not done: this is an implementation detail, the exact list of requirements satisfied is purely
5462an optimization, not something the user can detect.
5463* A backend for an overflow aware integers (done 2012/10/31).
5464* IIUC convert_to is used to emulate in c++98 compilers C++11 explicit
5465conversions. Could the explicit conversion operator be added on
5466compilers supporting it? (Done 2012/09/15).
5467* The front-end should make the differences between implicit and explicit
5468construction (Done 2012/09/15).
5469* The tutorial should add more examples concerning implicit or explicit
5470conversions. (Done 2012/09/15).
5471* The documentation must explain how move semantics helps in this domain
5472and what the backend needs to do to profit from this optimization. (Done 2012/09/15).
5473* The documentation should contain Throws specification on the mp_number
5474and backend requirements operations. (Done 2012/09/15).
5475* The library interface should use the noexcept (BOOST_NOEXCEPT, ...)
5476facilities (Done 2012/09/15).
5477* It is unfortunate that the generic mp_number front end can not make use
5478constexpr as not all the backends can ensure this (done - we can go quite a way).
5479* literals: The library doesn't provide some kind of literals. I think that the
5480mp_number class should provide a way to create literals if the backend
5481is able to. (Done 2012/09/15).
5482* The ExpresionTemplate parameter could be defaulted to a traits class for more sensible defaults (done 2012/09/20).
5483* In a = exp1 op exp2 where a occurs inside one of exp1 or exp2 then we can optimise and eliminate one more temporary (done 2012/09/20).
5484
5485
5486
5487[h4 Pre-Review Comments]
5488
5489* Make fixed precision orthogonal to Allocator type in cpp_int. Possible solution - add an additional MaxBits
5490template argument that defaults to 0 (meaning keep going till no more space/memory). Done.
5491* Can ring types (exact floating-point types) be supported? The answer should be yes, but someone needs to write it (Moved to TODO list).
5492* Should there be a choice of rounding mode (probably MPFR specific)? Moved to TODO list.
5493* Make the exponent type for cpp_dec_float a template parameter, maybe include support for big-integer exponents.
5494Open question - what should be the default - int32_t or int64_t? (done 2012/09/06)
5495* Document the size requirements of fixed precision ints (done 2012/09/15).
5496* Document std lib function accuracy (done 2012/09/15).
5497* Be a bit clearer on the effects of sign-magnitude representation of cpp_int - min == -max etc - done.
5498* Document cpp_dec_float precision, rounding, and exponent size (done 2012/09/06).
5499* Can we be clearer in the docs that mixed arithmetic doesn't work (no longer applicable as of 2012/09/06)?
5500* Document round functions behaviour better (they behave as in C++11) (added note 2012/09/06).
5501* Document limits on size of cpp_dec_float (done 2012/09/06).
5502* Add support for fused multiply add (and subtract). GMP mpz_t could use this (done 2012/09/20).
5503
5504[endsect]
5505
5506[section:faq FAQ]
5507
5508[variablelist
5509[[Why do I get compiler errors when passing a `number` to a template function?]
5510 [Most likely you are actually passing an expression template type to the function and
5511 template-argument-deduction deduces the "wrong" type. Try casting the arguments
5512 involving expressions to the actual number type, or as a last resort turning off
5513 expression template support in the number type you are using.]]
5514[[When is expression template support a performance gain?]
5515 [As a general rule, expression template support adds a small runtime overhead
5516 creating and unpacking the expression templates, but greatly reduces the number of
5517 temporaries created. So it's most effective in improving performance when the cost
5518 of creating a temporary is high: for example when creating a temporary involves a memory
5519 allocation. It is least effective (and may even be a dis-optimisation) when temporaries
5520 are cheap: for example if the number type is basically a thin wrapper around a native
5521 arithmetic type. In addition, since the library makes extensive use of thin inline wrapper
5522 functions, turning on compiler optimization is essential to achieving high performance.]]
5523[[Do expression templates reorder operations?]
5524 [Yes they do, sometimes quite radically so, if this is a concern then they should be turned
5525 off for the number type you are using.]]
5526[[I can't construct my number type from ['some other type], but the docs indicate that the conversion should be allowed, what's up?]
5527 [Some conversions are ['explicit], that includes construction from a string, or constructing from any type
5528 that may result in loss of precision (for example constructing an integer type from a float).]]
5529[[Why do I get an exception thrown (or the program crash due to an uncaught exception) when using the bitwise operators on a checked `cpp_int`?]
5530 [Bitwise operations on negative values (or indeed any signed integer type) are unspecified by the standard. As a result
5531 any attempt to carry out a bitwise operation on a negative checked-integer will result in a `std::range_error` being thrown.]]
5532[[Why do I get compiler errors when trying to use the complement operator?]
5533 [Use of the complement operator on signed types is problematic as the result is unspecified by the standard, and is further
5534 complicated by the fact that most extended precision integer types use a sign-magnitude representation rather than the 2's
5535 complement one favored by most native integer types. As a result the complement operator is deliberately disabled for
5536 checked `cpp_int`'s. Unchecked `cpp_int`'s give the same valued result as a 2's complement type would, but not the same bit-pattern.]]
5537[[Why can't I negate an unsigned type?]
5538 [The unary negation operator is deliberately disabled for unsigned integer types as its use would almost always be a programming error.]]
5539[[Why doesn't the library use proto?]
5540 [A very early version of the library did use proto, but compile times became too slow
5541 for the library to be usable. Since the library only required a tiny fraction of what
5542 proto has to offer anyway, a lightweight expression template mechanism was used instead.
5543 Compile times are still too slow...]]
5544[[Why not abstract out addition/multiplication algorithms?]
5545 [This was deemed not to be practical: these algorithms are intimately
5546 tied to the actual data representation used.]]
5547]
5548
5549[endsect]
5550
5551[section:ack Acknowledgements]
5552
5553This library would not have happened without:
5554
5555* Christopher Kormanyos' C++ decimal number code.
5556* Paul Bristow for patiently testing, and commenting on the library.
5557* All the folks at GMP, MPFR and libtommath, for providing the "guts" that makes this library work.
5558* [@http://www-cs-faculty.stanford.edu/~uno/taocp.html "The Art Of Computer Programming"],
5559Donald E. Knuth, Volume 2: Seminumerical Algorithms, Third Edition
5560(Reading, Massachusetts: Addison-Wesley, 1997), xiv+762pp. ISBN 0-201-89684-2
5561
5562[endsect]
5563
5564[endsect]
5565
5566[section:indexes Indexes]
5567
5568'''
5569<index type="function_name">
5570<title>Function Index</title>
5571</index>
5572
5573<index type="class_name">
5574<title>Class Index</title>
5575</index>
5576
5577<index type="typedef_name">
5578<title>Typedef Index</title>
5579</index>
5580
5581<index/>
5582'''
5583
5584[endsect]
5585
5586
5587
5588