diff --git a/doc/html/boost_multiprecision/indexes/s01.html b/doc/html/boost_multiprecision/indexes/s01.html index ad20bd40..f8c6e580 100644 --- a/doc/html/boost_multiprecision/indexes/s01.html +++ b/doc/html/boost_multiprecision/indexes/s01.html @@ -13,9 +13,9 @@
PrevUpHomeNext
-
+

-Function Index

+Function Index

A B C D E F I L M P R S T Z

@@ -55,10 +55,16 @@
C
-
  • +
    +
  • +
  • +

    cpp_dec_float

    + +
  • +
D
diff --git a/doc/html/boost_multiprecision/indexes/s02.html b/doc/html/boost_multiprecision/indexes/s02.html index d1ad0b8d..d8dacbad 100644 --- a/doc/html/boost_multiprecision/indexes/s02.html +++ b/doc/html/boost_multiprecision/indexes/s02.html @@ -13,9 +13,9 @@
PrevUpHomeNext
-
+

-Class Index

+Class Index

C G I M N T

diff --git a/doc/html/boost_multiprecision/indexes/s03.html b/doc/html/boost_multiprecision/indexes/s03.html index 1f790e8f..42e8cba8 100644 --- a/doc/html/boost_multiprecision/indexes/s03.html +++ b/doc/html/boost_multiprecision/indexes/s03.html @@ -13,9 +13,9 @@
PrevUpHomeNext
-
+

-Typedef Index

+Typedef Index

C I L M T U

diff --git a/doc/html/boost_multiprecision/indexes/s04.html b/doc/html/boost_multiprecision/indexes/s04.html index 21e9dbb6..0deb96a1 100644 --- a/doc/html/boost_multiprecision/indexes/s04.html +++ b/doc/html/boost_multiprecision/indexes/s04.html @@ -12,9 +12,9 @@
PrevUpHome
-
+

-Index

+Index

A B C D E F G I L M N O P R S T U Z

@@ -98,6 +98,7 @@
  • cpp_dec_float

  • cpp_dec_float_100

  • cpp_dec_float_50

  • +
  • TODO

  • @@ -817,6 +818,10 @@
    • +

      TODO

      + +
    • +
    • tommath_int

    • diff --git a/doc/html/boost_multiprecision/map/hist.html b/doc/html/boost_multiprecision/map/hist.html index 157d4400..f7102bd0 100644 --- a/doc/html/boost_multiprecision/map/hist.html +++ b/doc/html/boost_multiprecision/map/hist.html @@ -37,6 +37,13 @@
    • Removed "mp_" prefix from types.
    • +
    • + Allowed mixed precision arithmetic. +
    • +
    • + Changed ExpressionTemplates parameter to class number + to use enumerated values rather than true/false. +
    diff --git a/doc/html/boost_multiprecision/map/todo.html b/doc/html/boost_multiprecision/map/todo.html index d2ec17ec..e7fd11c7 100644 --- a/doc/html/boost_multiprecision/map/todo.html +++ b/doc/html/boost_multiprecision/map/todo.html @@ -54,7 +54,7 @@
  • Make the exponent type for cpp_dec_float a templare parameter, maybe include support for big-integer exponents. Open question - what should - be the default - int32_t or int64_t? + be the default - int32_t or int64_t? (done 2012/09/06)
  • Document the size requirements of fixed precision ints. @@ -76,19 +76,21 @@ - min == -max etc.
  • - Document cpp_dec_float precision, rounding, and exponent size. + Document cpp_dec_float precision, rounding, and exponent size (done 2012/09/06).
  • - Can we be clearer in the docs that mixed arithmetic doesn't work? + Can we be clearer in the docs that mixed arithmetic doesn't work (no + longer applicable as of 2012/09/06)?
  • - Document round functions behaviour better (they behave as in C99). + Document round functions behaviour better (they behave as in C++11) (added + note 2012/09/06).
  • Should there be a choice of rounding mode (probably MPFR specific)?
  • - Document limits on size of cpp_dec_float. + Document limits on size of cpp_dec_float (done 2012/09/06).
  • diff --git a/doc/html/boost_multiprecision/ref/number.html b/doc/html/boost_multiprecision/ref/number.html index 3969151d..b1f6dc2e 100644 --- a/doc/html/boost_multiprecision/ref/number.html +++ b/doc/html/boost_multiprecision/ref/number.html @@ -580,7 +580,7 @@ unmentionable-expression-template-type atan2 (const number-or-expression-template-type&, const number-or-expression-template-type&);

    - These functions all behave exactly as their standard library counterparts + These functions all behave exactly as their standard library C++11 counterparts do: their argument is either an instance of number or an expression template derived from it; If the argument is of type number<Backend, et_off> then that is also the return type, otherwise the return type is an expression @@ -601,6 +601,317 @@ library later, then these functions may be extended to support those number types).

    +

    + The precision of these functions is generally deterimined by the backend + implementation. For example the precision of these functions when used with + mpfr_float + is determined entirely by MPFR. + When these functions use our own implementations, the accuracy of the transcendal + functions is generally a few epsilon. Note however, that the trigonmetrical + functions incur the usual accuracy loss when reducing arguments by large + multiples of π. Also note that both __mpf_float and cpp_dec_float + have a number of guard digits beyond their stated precision, so the error + rates listed for these are in some sense artificially low. +

    +

    + The following table shows the error rates we observe for these functions + with various backend types, functions not listed here are exact (tested on + Win32 with VC++10, MPFR-3.0.0, MPIR-2.1.1): +

    +
    ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    + Function +

    +
    +

    + mpfr_float_50 +

    +
    +

    + mpf_float_50 +

    +
    +

    + cpp_dec_float_50 +

    +
    +

    + sqrt +

    +
    +

    + 1eps +

    +
    +

    + 0eps +

    +
    +

    + 0eps +

    +
    +

    + exp +

    +
    +

    + 1eps +

    +
    +

    + 0eps +

    +
    +

    + 0eps +

    +
    +

    + log +

    +
    +

    + 1eps +

    +
    +

    + 0eps +

    +
    +

    + 0eps +

    +
    +

    + log10 +

    +
    +

    + 1eps +

    +
    +

    + 0eps +

    +
    +

    + 0eps +

    +
    +

    + cos +

    +
    +

    + 700eps +

    +
    +

    + 0eps +

    +
    +

    + 0eps +

    +
    +

    + sin +

    +
    +

    + 1eps +

    +
    +

    + 0eps +

    +
    +

    + 0eps +

    +
    +

    + tan +

    +
    + + +
    +

    + acos +

    +
    + + +
    +

    + asin +

    +
    + + +
    +

    + atan +

    +
    + + +
    +

    + cosh +

    +
    + + +
    +

    + sinh +

    +
    + + +
    +

    + tanh +

    +
    + + +
    +

    + pow +

    +
    + + +
    +

    + fmod +

    +
    + + +
    +

    + atan2 +

    +
    + + +
    Traits Class diff --git a/doc/html/boost_multiprecision/tut.html b/doc/html/boost_multiprecision/tut.html index 1ed672ca..5ae44082 100644 --- a/doc/html/boost_multiprecision/tut.html +++ b/doc/html/boost_multiprecision/tut.html @@ -31,9 +31,9 @@
    Floating Point Numbers
    +
    cpp_dec_float
    gmp_float
    mpfr_float
    -
    cpp_dec_float
    Examples
    Area of @@ -50,8 +50,8 @@
    Rational Number Types
    -
    gmp_rational
    cpp_rational
    +
    gmp_rational
    tommath_rational
    Use With Boost.Rational
    rational_adapter
    diff --git a/doc/html/boost_multiprecision/tut/floats.html b/doc/html/boost_multiprecision/tut/floats.html index 171fa60d..bb8f542f 100644 --- a/doc/html/boost_multiprecision/tut/floats.html +++ b/doc/html/boost_multiprecision/tut/floats.html @@ -7,20 +7,20 @@ - +
    -PrevUpHomeNext +PrevUpHomeNext
    +
    cpp_dec_float
    gmp_float
    mpfr_float
    -
    cpp_dec_float
    Examples
    Area of @@ -81,6 +81,39 @@ + +

    + 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. +

    + + +

    mpf_float<N> @@ -147,39 +180,6 @@

    - - -

    - 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. -

    - -
    @@ -193,7 +193,7 @@
    -PrevUpHomeNext +PrevUpHomeNext
    diff --git a/doc/html/boost_multiprecision/tut/floats/cpp_dec_float.html b/doc/html/boost_multiprecision/tut/floats/cpp_dec_float.html index e0a56312..5ceefb43 100644 --- a/doc/html/boost_multiprecision/tut/floats/cpp_dec_float.html +++ b/doc/html/boost_multiprecision/tut/floats/cpp_dec_float.html @@ -6,12 +6,12 @@ - - + +
    -PrevUpHomeNext +PrevUpHomeNext

    @@ -22,7 +22,7 @@

    namespace boost{ namespace multiprecision{
     
    -template <unsigned Digits10>
    +template <unsigned Digits10, class ExponentType = boost::int32_t, class Allocator = void>
     class cpp_dec_float;
     
     typedef number<cpp_dec_float<50> > cpp_dec_float_50;
    @@ -42,7 +42,27 @@
               be used at fixed precision by specifying a non-zero Digits10
               template parameter. The typedefs cpp_dec_float_50
               and cpp_dec_float_100 provide
    -          arithmetic types at 50 and 100 decimal digits precision respectively.
    +          arithmetic types at 50 and 100 decimal digits precision respectively. Optionally,
    +          you can specify an integer type to use for the exponent, this defaults
    +          to a 32-bit integer type which is more than large enough for the vast majority
    +          of use cases, but larger types such as long
    +          long can also be specified if you
    +          need a truely huge exponent range.
    +        

    +

    + Normally cpp_dec_float + allocates no memory: all of the space required for it's digits are allocated + directly within the class. As a result care should be taken not to use + the class with too high a digit count as stack space requirements can grow + out of control. If that represents a problem then providing an allocator + as the final template parameter causes cpp_dec_float + to dynamically allocate the memory it needs: this significantly reduces + the size of cpp_dec_float + and increases the viable upper limit on the number of digits at the expense + of performance. However, please bare in mind that arithmetic operations + rapidly become very expensive as the digit count grows: + the current implementation really isn't optimized or designed for large + digit counts.

    There is full standard library and numeric_limits @@ -83,13 +103,25 @@ Any number instantiated on this type, is convertible to any other number instantiated on this type - for example you can convert from number<cpp_dec_float<50> > to number<cpp_dec_float<SomeOtherValue> >. - Narrowing conversions are truncating. + Narrowing conversions are truncating and explicit.

  • Conversion from a string results in a std::runtime_error being thrown if the string can not be interpreted as a valid floating point number.
  • +
  • + The actual precision of a cpp_dec_float + is always slightly higher than the number of digits specified in the + template parameter, actually how much higher is an implementation detail + but is always at least 8 decimal digits. +
  • +
  • + Operations involving cpp_dec_float + are always truncating. However, note that since their are guard digits + in effect, in practice this has no real impact on accuracy for most + use cases. +
  • @@ -131,7 +163,7 @@
    -PrevUpHomeNext +PrevUpHomeNext
    diff --git a/doc/html/boost_multiprecision/tut/floats/fp_eg.html b/doc/html/boost_multiprecision/tut/floats/fp_eg.html index 238d5aff..a2567273 100644 --- a/doc/html/boost_multiprecision/tut/floats/fp_eg.html +++ b/doc/html/boost_multiprecision/tut/floats/fp_eg.html @@ -6,12 +6,12 @@ - +
    -PrevUpHomeNext +PrevUpHomeNext

    @@ -40,7 +40,7 @@
    -PrevUpHomeNext +PrevUpHomeNext
    diff --git a/doc/html/boost_multiprecision/tut/floats/gmp_float.html b/doc/html/boost_multiprecision/tut/floats/gmp_float.html index d420e0c4..a33583e7 100644 --- a/doc/html/boost_multiprecision/tut/floats/gmp_float.html +++ b/doc/html/boost_multiprecision/tut/floats/gmp_float.html @@ -6,12 +6,12 @@ - +
    -PrevUpHomeNext +PrevUpHomeNext

    @@ -177,7 +177,7 @@
    -PrevUpHomeNext +PrevUpHomeNext
    diff --git a/doc/html/boost_multiprecision/tut/floats/mpfr_float.html b/doc/html/boost_multiprecision/tut/floats/mpfr_float.html index 53692329..40126cf1 100644 --- a/doc/html/boost_multiprecision/tut/floats/mpfr_float.html +++ b/doc/html/boost_multiprecision/tut/floats/mpfr_float.html @@ -7,11 +7,11 @@ - +
    -PrevUpHomeNext +PrevUpHomeNext

    @@ -166,7 +166,7 @@
    -PrevUpHomeNext +PrevUpHomeNext
    diff --git a/doc/html/boost_multiprecision/tut/rational.html b/doc/html/boost_multiprecision/tut/rational.html index 9dcaf83e..712c33d3 100644 --- a/doc/html/boost_multiprecision/tut/rational.html +++ b/doc/html/boost_multiprecision/tut/rational.html @@ -7,19 +7,19 @@ - +
    -PrevUpHomeNext +PrevUpHomeNext
    -
    gmp_rational
    cpp_rational
    +
    gmp_rational
    tommath_rational
    Use With Boost.Rational
    rational_adapter
    @@ -70,6 +70,38 @@ + +

    + cpp_rational +

    + + +

    + boost/multiprecision/cpp_int.hpp +

    + + +

    + 2 +

    + + +

    + None +

    + + +

    + An all C++ Boost-licensed implementation. +

    + + +

    + Slower than GMP. +

    + + +

    gmp_rational @@ -103,38 +135,6 @@ - -

    - cpp_rational -

    - - -

    - boost/multiprecision/cpp_int.hpp -

    - - -

    - 2 -

    - - -

    - None -

    - - -

    - An all C++ Boost-licensed implementation. -

    - - -

    - Slower than GMP. -

    - - -

    tommath_rational @@ -246,7 +246,7 @@


    -PrevUpHomeNext +PrevUpHomeNext
    diff --git a/doc/html/boost_multiprecision/tut/rational/cpp_rational.html b/doc/html/boost_multiprecision/tut/rational/cpp_rational.html index 445989b1..22bf2a4c 100644 --- a/doc/html/boost_multiprecision/tut/rational/cpp_rational.html +++ b/doc/html/boost_multiprecision/tut/rational/cpp_rational.html @@ -6,12 +6,12 @@ - - + +
    -PrevUpHomeNext +PrevUpHomeNext

    @@ -107,7 +107,7 @@
    -PrevUpHomeNext +PrevUpHomeNext
    diff --git a/doc/html/boost_multiprecision/tut/rational/gmp_rational.html b/doc/html/boost_multiprecision/tut/rational/gmp_rational.html index 2d1f7fb8..a317321b 100644 --- a/doc/html/boost_multiprecision/tut/rational/gmp_rational.html +++ b/doc/html/boost_multiprecision/tut/rational/gmp_rational.html @@ -6,12 +6,12 @@ - - + +
    -PrevUpHomeNext +PrevUpHomeNext

    @@ -138,7 +138,7 @@
    -PrevUpHomeNext +PrevUpHomeNext
    diff --git a/doc/html/boost_multiprecision/tut/rational/tommath_rational.html b/doc/html/boost_multiprecision/tut/rational/tommath_rational.html index 432d1012..4ce58b60 100644 --- a/doc/html/boost_multiprecision/tut/rational/tommath_rational.html +++ b/doc/html/boost_multiprecision/tut/rational/tommath_rational.html @@ -6,12 +6,12 @@ - +
    -PrevUpHomeNext +PrevUpHomeNext

    @@ -113,7 +113,7 @@
    -PrevUpHomeNext +PrevUpHomeNext
    diff --git a/doc/html/index.html b/doc/html/index.html index 57fb5f19..2d72038a 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -46,9 +46,9 @@

    Floating Point Numbers
    +
    cpp_dec_float
    gmp_float
    mpfr_float
    -
    cpp_dec_float
    Examples
    Area of @@ -65,8 +65,8 @@
    Rational Number Types
    -
    gmp_rational
    cpp_rational
    +
    gmp_rational
    tommath_rational
    Use With Boost.Rational
    rational_adapter
    @@ -120,7 +120,7 @@
    - +

    Last revised: September 06, 2012 at 09:51:26 GMT

    Last revised: September 07, 2012 at 08:25:28 GMT


    diff --git a/doc/multiprecision.qbk b/doc/multiprecision.qbk index 1446586a..e765f0e9 100644 --- a/doc/multiprecision.qbk +++ b/doc/multiprecision.qbk @@ -47,6 +47,16 @@ '''] +[def __cpp_int [link boost_multiprecision.tut.ints.cpp_int cpp_int]] +[def __gmp_int [link boost_multiprecision.tut.ints.gmp_int gmp_int]] +[def __tom_int [link boost_multiprecision.tut.ints.tom_int tom_int]] +[def __gmp_float [link boost_multiprecision.tut.floats.gmp_float gmp_float]] +[def __mpfr_float_backend [link boost_multiprecision.tut.floats.mpfr_float mpfr_float]] +[def __cpp_dec_float [link boost_multiprecision.tut.floats.cpp_dec_float cpp_dec_float]] +[def __gmp_rational [link boost_multiprecision.tut.rational.gmp_rational gmp_rational]] +[def __cpp_rational [link boost_multiprecision.tut.rational.cpp_rational cpp_rational]] +[def __tommath_rational [link boost_multiprecision.tut.rational.tommath_rational tommath_rational]] + [section:intro Introduction] The Multiprecision Library provides ['User-defined] integer, rational and floating-point C++ types which @@ -504,11 +514,73 @@ The following back-ends provide floating point arithmetic: [table [[Backend Type][Header][Radix][Dependencies][Pros][Cons]] +[[`cpp_dec_float`][boost/multiprecision/cpp_dec_float.hpp][10][None][Header only, all C++ implementation. Boost licence.][Approximately 2x slower than the [mpfr] or [gmp] libraries.]] [[`mpf_float`][boost/multiprecision/gmp.hpp][2][[gmp]][Very fast and efficient back-end.][Dependency on GNU licensed [gmp] library.]] [[`mpfr_float`][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.]] -[[`cpp_dec_float`][boost/multiprecision/cpp_dec_float.hpp][10][None][Header only, all C++ implementation. Boost licence.][Approximately 2x slower than the [mpfr] or [gmp] libraries.]] ] +[section:cpp_dec_float cpp_dec_float] + +`#include ` + + namespace boost{ namespace multiprecision{ + + template + class cpp_dec_float; + + typedef number > cpp_dec_float_50; + typedef number > cpp_dec_float_100; + + }} // namespaces + +The `cpp_dec_float` back-end is used in conjunction with `number`: It acts as an entirely C++ (header only and dependency free) +real-number type that is a drop-in replacement for the native C++ floating-point types, but with +much greater precision. + +Type `cpp_dec_float` can be used at fixed precision by specifying a non-zero `Digits10` template parameter. +The typedefs `cpp_dec_float_50` and `cpp_dec_float_100` provide arithmetic types at 50 and 100 decimal digits precision +respectively. Optionally, you can specify an integer type to use for the exponent, this defaults to a 32-bit integer type +which is more than large enough for the vast majority of use cases, but larger types such as `long long` can also be specified +if you need a truely huge exponent range. + +Normally `cpp_dec_float` allocates no memory: all of the space required for it's digits are allocated +directly within the class. As a result care should be taken not to use the class with too high a digit count +as stack space requirements can grow out of control. If that represents a problem then providing an allocator +as the final template parameter causes `cpp_dec_float` to dynamically allocate the memory it needs: this +significantly reduces the size of `cpp_dec_float` and increases the viable upper limit on the number of digits +at the expense of performance. However, please bare in mind that arithmetic operations rapidly become ['very] expensive +as the digit count grows: the current implementation really isn't optimized or designed for large digit counts. + +There is full standard library and `numeric_limits` support available for this type. + +Things you should know when using this type: + +* Default constructed `cpp_dec_float`s have a value of zero. +* The radix of this type is 10. As a result it can behave subtly differently from base-2 types. +* It is not possible to round-trip this type to and from a string and get back to exactly the same value +(this is a result of the type having some hidden internal guard digits). +* The type has a number of internal guard digits over and above those specified in the template argument. +Normally these should not be visible to the user. +* The type supports both infinities and NaN's. An infinity is generated whenever the result would overflow, +and a NaN is generated for any mathematically undefined operation. +* There is a `std::numeric_limits` specialisation for this type. +* Any `number` instantiated on this type, is convertible to any other `number` instantiated on this type - +for example you can convert from `number >` to `number >`. +Narrowing conversions are truncating and `explicit`. +* Conversion from a string results in a `std::runtime_error` being thrown if the string can not be interpreted +as a valid floating point number. +* The actual precision of a `cpp_dec_float` is always slightly higher than the number of digits specified in +the template parameter, actually how much higher is an implementation detail but is always at least 8 decimal +digits. +* Operations involving `cpp_dec_float` are always truncating. However, note that since their are guard digits +in effect, in practice this has no real impact on accuracy for most use cases. + +[h5 cpp_dec_float example:] + +[cpp_dec_float_eg] + +[endsect] + [section:gmp_float gmp_float] `#include ` @@ -627,53 +699,6 @@ as a valid floating point number. [endsect] -[section:cpp_dec_float cpp_dec_float] - -`#include ` - - namespace boost{ namespace multiprecision{ - - template - class cpp_dec_float; - - typedef number > cpp_dec_float_50; - typedef number > cpp_dec_float_100; - - }} // namespaces - -The `cpp_dec_float` back-end is used in conjunction with `number`: It acts as an entirely C++ (header only and dependency free) -real-number type that is a drop-in replacement for the native C++ floating-point types, but with -much greater precision. - -Type `cpp_dec_float` can be used at fixed precision by specifying a non-zero `Digits10` template parameter. -The typedefs `cpp_dec_float_50` and `cpp_dec_float_100` provide arithmetic types at 50 and 100 decimal digits precision -respectively. - -There is full standard library and `numeric_limits` support available for this type. - -Things you should know when using this type: - -* Default constructed `cpp_dec_float`s have a value of zero. -* The radix of this type is 10. As a result it can behave subtly differently from base-2 types. -* It is not possible to round-trip this type to and from a string and get back to exactly the same value -(this is a result of the type having some hidden internal guard digits). -* The type has a number of internal guard digits over and above those specified in the template argument. -Normally these should not be visible to the user. -* The type supports both infinities and NaN's. An infinity is generated whenever the result would overflow, -and a NaN is generated for any mathematically undefined operation. -* There is a `std::numeric_limits` specialisation for this type. -* Any `number` instantiated on this type, is convertible to any other `number` instantiated on this type - -for example you can convert from `number >` to `number >`. -Narrowing conversions are truncating. -* Conversion from a string results in a `std::runtime_error` being thrown if the string can not be interpreted -as a valid floating point number. - -[h5 cpp_dec_float example:] - -[cpp_dec_float_eg] - -[endsect] - [section:fp_eg Examples] [import ../example/floating_point_examples.cpp] @@ -723,13 +748,53 @@ The following back-ends provide rational number arithmetic: [table [[Backend Type][Header][Radix][Dependencies][Pros][Cons]] -[[`gmp_rational`][boost/multiprecision/gmp.hpp][2][[gmp]][Very fast and efficient back-end.][Dependency on GNU licensed [gmp] library.]] [[`cpp_rational`][boost/multiprecision/cpp_int.hpp][2][None][An all C++ Boost-licensed implementation.][Slower than [gmp].]] +[[`gmp_rational`][boost/multiprecision/gmp.hpp][2][[gmp]][Very fast and efficient back-end.][Dependency on GNU licensed [gmp] library.]] [[`tommath_rational`][boost/multiprecision/tommath.hpp][2][[tommath]][All C/C++ implementation that's Boost Software Licence compatible.][Slower than [gmp].]] [[`rational_adapter`][boost/multiprecision/rational_adapter.hpp][N/A][none][All C++ adapter that allows any integer back-end type to be used as a rational type.][Requires an underlying integer back-end type.]] [[`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.]] ] +[section:cpp_rational cpp_rational] + +`#include ` + + namespace boost{ namespace multiprecision{ + + typedef rational_adapter > cpp_rational_backend; + + typedef number cpp_rational; + + }} // namespaces + +The `cpp_rational_backend` type is used via the typedef `boost::multiprecision::cpp_rational`. It provides +a rational number type that is a drop-in replacement for the native C++ number types, but with unlimited precision. + +As well as the usual conversions from arithmetic and string types, instances of `cpp_rational` are copy constructible +and assignable from type `cpp_int`. + +There is also a two argument constructor that accepts a numerator and denominator: both of type `cpp_int`. + +There are also non-member functions: + + cpp_int numerator(const cpp_rational&); + cpp_int denominator(const cpp_rational&); + +which return the numerator and denominator of the number. + +Things you should know when using this type: + +* Default constructed `cpp_rational`s have the value zero. +* Division by zero results in a `std::rumtime_error` being thrown. +* Conversion from a string results in a `std::runtime_error` being thrown if the string can not be +interpreted as a valid rational number. + +[h5 Example:] + +[cpp_rational_eg] + +[endsect] + [section:gmp_rational gmp_rational] `#include ` @@ -778,46 +843,6 @@ interpreted as a valid rational number. [endsect] -[section:cpp_rational cpp_rational] - -`#include ` - - namespace boost{ namespace multiprecision{ - - typedef rational_adapter > cpp_rational_backend; - - typedef number cpp_rational; - - }} // namespaces - -The `cpp_rational_backend` type is used via the typedef `boost::multiprecision::cpp_rational`. It provides -a rational number type that is a drop-in replacement for the native C++ number types, but with unlimited precision. - -As well as the usual conversions from arithmetic and string types, instances of `cpp_rational` are copy constructible -and assignable from type `cpp_int`. - -There is also a two argument constructor that accepts a numerator and denominator: both of type `cpp_int`. - -There are also non-member functions: - - cpp_int numerator(const cpp_rational&); - cpp_int denominator(const cpp_rational&); - -which return the numerator and denominator of the number. - -Things you should know when using this type: - -* Default constructed `cpp_rational`s have the value zero. -* Division by zero results in a `std::rumtime_error` being thrown. -* Conversion from a string results in a `std::runtime_error` being thrown if the string can not be -interpreted as a valid rational number. - -[h5 Example:] - -[cpp_rational_eg] - -[endsect] - [section:tommath_rational tommath_rational] `#include ` @@ -1494,7 +1519,7 @@ this library support all of the iostream formatting flags, field width and preci ``['unmentionable-expression-template-type]`` fmod (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&); ``['unmentionable-expression-template-type]`` atan2 (const ``['number-or-expression-template-type]``&, const ``['number-or-expression-template-type]``&); -These functions all behave exactly as their standard library counterparts do: their argument is either an instance of `number` or +These functions all behave exactly as their standard library C++11 counterparts do: their argument is either an instance of `number` or an expression template derived from it; If the argument is of type `number` then that is also the return type, otherwise the return type is an expression template. @@ -1506,6 +1531,35 @@ used at variable precision. Also note that with the exception of `abs` that these functions can only be used with floating-point Backend types (if any other types such as fixed precision or complex types are added to the library later, then these functions may be extended to support those number types). +The precision of these functions is generally deterimined by the backend implementation. For example the precision +of these functions when used with __mpfr_float_backend is determined entirely by [mpfr]. When these functions use our own +implementations, the accuracy of the transcendal functions is generally a few epsilon. Note however, that the trigonmetrical +functions incur the usual accuracy loss when reducing arguments by large multiples of [pi]. Also note that both __mpf_float +and __cpp_dec_float have a number of guard digits beyond their stated precision, so the error rates listed for these +are in some sense artificially low. + +The following table shows the error rates we observe for these functions with various backend types, functions not listed +here are exact (tested on Win32 with VC++10, MPFR-3.0.0, MPIR-2.1.1): + +[table +[[Function][mpfr_float_50][mpf_float_50][cpp_dec_float_50]] +[[sqrt][1eps][0eps][0eps]] +[[exp][1eps][0eps][0eps]] +[[log][1eps][0eps][0eps]] +[[log10][1eps][0eps][0eps]] +[[cos][700eps][0eps][0eps]] +[[sin][1eps][0eps][0eps]] +[[tan][][][]] +[[acos][][][]] +[[asin][][][]] +[[atan][][][]] +[[cosh][][][]] +[[sinh][][][]] +[[tanh][][][]] +[[pow][][][]] +[[fmod][][][]] +[[atan2][][][]] +] [h4 Traits Class Support] template @@ -2602,6 +2656,8 @@ Windows Vista machine. * Many functions made made `constexp`? * Differentiate between explicit and implicit conversions in the number constructor. * Removed "mp_" prefix from types. +* Allowed mixed precision arithmetic. +* Changed ExpressionTemplates parameter to class `number` to use enumerated values rather than true/false. [h4 Pre-review history] @@ -2632,18 +2688,18 @@ More a list of what ['could] be done, rather than what ['should] be done (which * Can ring types (exact floating point types) be supported? The answer should be yes, but someone needs to write it. * Make the exponent type for cpp_dec_float a templare parameter, maybe include support for big-integer exponents. -Open question - what should be the default - int32_t or int64_t? +Open question - what should be the default - int32_t or int64_t? (done 2012/09/06) * Document the size requirements of fixed precision ints. * Document std lib function accuracy. * Make fixed precision orthogonal to Allocator type in cpp_int. Possible solution - add an additional MaxBits template argument that defaults to 0 (meaning keep going till no more space/memory). * Add support for fused multiply add (and subtract). GMP mpz_t could use this. * Be a bit clearer on the effects of sign-magnitude representation of cpp_int - min == -max etc. -* Document cpp_dec_float precision, rounding, and exponent size. -* Can we be clearer in the docs that mixed arithmetic doesn't work? -* Document round functions behaviour better (they behave as in C99). +* Document cpp_dec_float precision, rounding, and exponent size (done 2012/09/06). +* Can we be clearer in the docs that mixed arithmetic doesn't work (no longer applicable as of 2012/09/06)? +* Document round functions behaviour better (they behave as in C++11) (added note 2012/09/06). * Should there be a choice of rounding mode (probably MPFR specific)? -* Document limits on size of cpp_dec_float. +* Document limits on size of cpp_dec_float (done 2012/09/06). [endsect] diff --git a/include/boost/multiprecision/cpp_dec_float.hpp b/include/boost/multiprecision/cpp_dec_float.hpp index 1a7241a5..73f85bff 100644 --- a/include/boost/multiprecision/cpp_dec_float.hpp +++ b/include/boost/multiprecision/cpp_dec_float.hpp @@ -26,17 +26,28 @@ namespace boost{ namespace multiprecision{ namespace backends{ -template +template class cpp_dec_float; } // namespace -template -struct number_category > : public mpl::int_{}; +template +struct number_category > : public mpl::int_{}; namespace backends{ -template +namespace detail{ + +template +struct dynamic_array : public std::vector +{ + dynamic_array() + : std::vector(static_cast::size_type>(S), static_cast(0)) {} +}; + +} + +template class cpp_dec_float { private: @@ -46,18 +57,18 @@ public: typedef mpl::list signed_types; typedef mpl::list unsigned_types; typedef mpl::list float_types; - typedef long long exponent_type; + typedef ExponentType exponent_type; static const boost::int32_t cpp_dec_float_radix = 10L; static const boost::int32_t cpp_dec_float_digits10_limit_lo = 9L; static const boost::int32_t cpp_dec_float_digits10_limit_hi = boost::integer_traits::const_max - 100; static const boost::int32_t cpp_dec_float_digits10 = ((cpp_dec_float_digits10_setting < cpp_dec_float_digits10_limit_lo) ? cpp_dec_float_digits10_limit_lo : ((cpp_dec_float_digits10_setting > cpp_dec_float_digits10_limit_hi) ? cpp_dec_float_digits10_limit_hi : cpp_dec_float_digits10_setting)); - static const boost::int64_t cpp_dec_float_max_exp10 = static_cast( 2776234983093287512LL); - static const boost::int64_t cpp_dec_float_min_exp10 = static_cast(-2776234983093287512LL); - static const boost::int64_t cpp_dec_float_max_exp = static_cast((cpp_dec_float_max_exp10 / 301LL) * 1000LL); - static const boost::int64_t cpp_dec_float_min_exp = static_cast((cpp_dec_float_min_exp10 / 301LL) * 1000LL); + static const ExponentType cpp_dec_float_max_exp10 = (static_cast(1) << (std::numeric_limits::digits - 5)); + static const ExponentType cpp_dec_float_min_exp10 = -cpp_dec_float_max_exp10; + static const ExponentType cpp_dec_float_max_exp = static_cast((cpp_dec_float_max_exp10 / 301LL) * 1000LL); + static const ExponentType cpp_dec_float_min_exp = static_cast((cpp_dec_float_min_exp10 / 301LL) * 1000LL); - BOOST_STATIC_ASSERT(cpp_dec_float_max_exp10 == -cpp_dec_float_min_exp10); + BOOST_STATIC_ASSERT((cpp_dec_float::cpp_dec_float_max_exp10 == -cpp_dec_float::cpp_dec_float_min_exp10)); private: static const boost::int32_t cpp_dec_float_elem_digits10 = 8L; @@ -89,10 +100,13 @@ private: } fpclass_type; - typedef boost::array array_type; + typedef typename mpl::if_, + boost::array, + detail::dynamic_array + >::type array_type; array_type data; - boost::int64_t exp; + ExponentType exp; bool neg; fpclass_type fpclass; boost::int32_t prec_elem; @@ -102,7 +116,7 @@ private: // cpp_dec_float(fpclass_type c) BOOST_NOEXCEPT : data(), - exp (static_cast(0)), + exp (static_cast(0)), neg (false), fpclass (c), prec_elem(cpp_dec_float_elem_number) { } @@ -114,23 +128,23 @@ private: { initializer() { - cpp_dec_float::nan(); - cpp_dec_float::inf(); - (cpp_dec_float::min)(); - (cpp_dec_float::max)(); - cpp_dec_float::zero(); - cpp_dec_float::one(); - cpp_dec_float::two(); - cpp_dec_float::half(); - cpp_dec_float::double_min(); - cpp_dec_float::double_max(); - cpp_dec_float::long_double_max(); - cpp_dec_float::long_double_min(); - cpp_dec_float::long_long_max(); - cpp_dec_float::long_long_min(); - cpp_dec_float::ulong_long_max(); - cpp_dec_float::eps(); - cpp_dec_float::pow2(0); + cpp_dec_float::nan(); + cpp_dec_float::inf(); + (cpp_dec_float::min)(); + (cpp_dec_float::max)(); + cpp_dec_float::zero(); + cpp_dec_float::one(); + cpp_dec_float::two(); + cpp_dec_float::half(); + cpp_dec_float::double_min(); + cpp_dec_float::double_max(); + cpp_dec_float::long_double_max(); + cpp_dec_float::long_double_min(); + cpp_dec_float::long_long_max(); + cpp_dec_float::long_long_min(); + cpp_dec_float::ulong_long_max(); + cpp_dec_float::eps(); + cpp_dec_float::pow2(0); } void do_nothing(){} }; @@ -141,14 +155,14 @@ public: // Constructors cpp_dec_float() BOOST_NOEXCEPT : data(), - exp (static_cast(0)), + exp (static_cast(0)), neg (false), fpclass (cpp_dec_float_finite), prec_elem(cpp_dec_float_elem_number) { } cpp_dec_float(const char* s) : data(), - exp (static_cast(0)), + exp (static_cast(0)), neg (false), fpclass (cpp_dec_float_finite), prec_elem(cpp_dec_float_elem_number) @@ -159,7 +173,7 @@ public: template cpp_dec_float(I i, typename enable_if >::type* = 0) BOOST_NOEXCEPT : data(), - exp (static_cast(0)), + exp (static_cast(0)), neg (false), fpclass (cpp_dec_float_finite), prec_elem(cpp_dec_float_elem_number) @@ -170,7 +184,7 @@ public: template cpp_dec_float(I i, typename enable_if >::type* = 0) BOOST_NOEXCEPT : data(), - exp (static_cast(0)), + exp (static_cast(0)), neg (false), fpclass (cpp_dec_float_finite), prec_elem(cpp_dec_float_elem_number) @@ -191,8 +205,8 @@ public: fpclass (f.fpclass), prec_elem(f.prec_elem) { } - template - cpp_dec_float(const cpp_dec_float& f, typename enable_if_c::type* = 0) BOOST_NOEXCEPT : + template + cpp_dec_float(const cpp_dec_float& f, typename enable_if_c::type* = 0) BOOST_NOEXCEPT : data(), exp (f.exp), neg (f.neg), @@ -201,8 +215,8 @@ public: { std::copy(f.data.begin(), f.data.begin() + f.prec_elem, data.begin()); } - template - explicit cpp_dec_float(const cpp_dec_float& f, typename disable_if_c::type* = 0) BOOST_NOEXCEPT : + template + explicit cpp_dec_float(const cpp_dec_float& f, typename disable_if_c::type* = 0) BOOST_NOEXCEPT : data(), exp (f.exp), neg (f.neg), @@ -216,7 +230,7 @@ public: template cpp_dec_float(const F val, typename enable_if >::type* = 0) BOOST_NOEXCEPT : data(), - exp (static_cast(0)), + exp (static_cast(0)), neg (false), fpclass (cpp_dec_float_finite), prec_elem(cpp_dec_float_elem_number) @@ -224,7 +238,7 @@ public: *this = val; } - cpp_dec_float(const double val, long long exponent) BOOST_NOEXCEPT; + cpp_dec_float(const double val, ExponentType exponent) BOOST_NOEXCEPT; // Specific special values. static const cpp_dec_float& nan() BOOST_NOEXCEPT @@ -440,7 +454,7 @@ public: template int compare(const V& v)const BOOST_NOEXCEPT { - cpp_dec_float t; + cpp_dec_float t; t = v; return compare(t); } @@ -458,7 +472,7 @@ public: long double extract_long_double (void) const BOOST_NOEXCEPT; signed long long extract_signed_long_long (void) const BOOST_NOEXCEPT; unsigned long long extract_unsigned_long_long(void) const BOOST_NOEXCEPT; - void extract_parts (double& mantissa, boost::int64_t& exponent) const BOOST_NOEXCEPT; + void extract_parts (double& mantissa, ExponentType& exponent) const BOOST_NOEXCEPT; cpp_dec_float extract_integer_part (void) const BOOST_NOEXCEPT; void precision(const boost::int32_t prec_digits) BOOST_NOEXCEPT { @@ -475,13 +489,13 @@ public: } } static cpp_dec_float pow2(long long i) BOOST_NOEXCEPT; - long long order()const BOOST_NOEXCEPT + ExponentType order()const BOOST_NOEXCEPT { const bool bo_order_is_zero = ((!isfinite()) || (data[0] == static_cast(0u))); // // Binary search to find the order of the leading term: // - boost::uint32_t prefix = 0; + ExponentType prefix = 0; if(data[0] >= 100000UL) { @@ -523,7 +537,7 @@ public: } } - return (bo_order_is_zero ? static_cast(0) : static_cast(exp + prefix)); + return (bo_order_is_zero ? static_cast(0) : static_cast(exp + prefix)); } private: @@ -542,44 +556,44 @@ private: bool rd_string(const char* const s); - template + template friend class cpp_dec_float; }; -template -typename cpp_dec_float::initializer cpp_dec_float::init; +template +typename cpp_dec_float::initializer cpp_dec_float::init; -template -const boost::int32_t cpp_dec_float::cpp_dec_float_radix; -template -const boost::int32_t cpp_dec_float::cpp_dec_float_digits10_setting; -template -const boost::int32_t cpp_dec_float::cpp_dec_float_digits10_limit_lo; -template -const boost::int32_t cpp_dec_float::cpp_dec_float_digits10_limit_hi; -template -const boost::int32_t cpp_dec_float::cpp_dec_float_digits10; -template -const boost::int64_t cpp_dec_float::cpp_dec_float_max_exp; -template -const boost::int64_t cpp_dec_float::cpp_dec_float_min_exp; -template -const boost::int64_t cpp_dec_float::cpp_dec_float_max_exp10; -template -const boost::int64_t cpp_dec_float::cpp_dec_float_min_exp10; -template -const boost::int32_t cpp_dec_float::cpp_dec_float_elem_digits10; -template -const boost::int32_t cpp_dec_float::cpp_dec_float_elem_number_request; -template -const boost::int32_t cpp_dec_float::cpp_dec_float_elem_number; -template -const boost::int32_t cpp_dec_float::cpp_dec_float_elem_mask; +template +const boost::int32_t cpp_dec_float::cpp_dec_float_radix; +template +const boost::int32_t cpp_dec_float::cpp_dec_float_digits10_setting; +template +const boost::int32_t cpp_dec_float::cpp_dec_float_digits10_limit_lo; +template +const boost::int32_t cpp_dec_float::cpp_dec_float_digits10_limit_hi; +template +const boost::int32_t cpp_dec_float::cpp_dec_float_digits10; +template +const ExponentType cpp_dec_float::cpp_dec_float_max_exp; +template +const ExponentType cpp_dec_float::cpp_dec_float_min_exp; +template +const ExponentType cpp_dec_float::cpp_dec_float_max_exp10; +template +const ExponentType cpp_dec_float::cpp_dec_float_min_exp10; +template +const boost::int32_t cpp_dec_float::cpp_dec_float_elem_digits10; +template +const boost::int32_t cpp_dec_float::cpp_dec_float_elem_number_request; +template +const boost::int32_t cpp_dec_float::cpp_dec_float_elem_number; +template +const boost::int32_t cpp_dec_float::cpp_dec_float_elem_mask; -template -cpp_dec_float& cpp_dec_float::operator+=(const cpp_dec_float& v) BOOST_NOEXCEPT +template +cpp_dec_float& cpp_dec_float::operator+=(const cpp_dec_float& v) BOOST_NOEXCEPT { if(isnan()) { @@ -601,9 +615,9 @@ cpp_dec_float& cpp_dec_float::operator+=(const cpp_dec_float } // Get the offset for the add/sub operation. - static const boost::int64_t max_delta_exp = static_cast((cpp_dec_float_elem_number - 1) * cpp_dec_float_elem_digits10); + static const ExponentType max_delta_exp = static_cast((cpp_dec_float_elem_number - 1) * cpp_dec_float_elem_digits10); - const boost::int64_t ofs_exp = static_cast(exp - v.exp); + const ExponentType ofs_exp = static_cast(exp - v.exp); // Check if the operation is out of range, requiring special handling. if(v.iszero() || (ofs_exp > max_delta_exp)) @@ -666,7 +680,7 @@ cpp_dec_float& cpp_dec_float::operator+=(const cpp_dec_float { std::copy_backward(data.begin(), data.end() - static_cast(1u), data.end()); data[0] = carry; - exp += static_cast(cpp_dec_float_elem_digits10); + exp += static_cast(cpp_dec_float_elem_digits10); } } else @@ -748,7 +762,7 @@ cpp_dec_float& cpp_dec_float::operator+=(const cpp_dec_float // This result of the subtraction is exactly zero. // Reset the sign and the exponent. neg = false; - exp = static_cast(0); + exp = static_cast(0); } else { @@ -758,7 +772,7 @@ cpp_dec_float& cpp_dec_float::operator+=(const cpp_dec_float std::copy(data.begin() + static_cast(sj), data.end(), data.begin()); std::fill(data.end() - sj, data.end(), static_cast(0u)); - exp -= static_cast(sj * static_cast(cpp_dec_float_elem_digits10)); + exp -= static_cast(sj * static_cast(cpp_dec_float_elem_digits10)); } } } @@ -798,8 +812,8 @@ cpp_dec_float& cpp_dec_float::operator+=(const cpp_dec_float return *this; } -template -cpp_dec_float& cpp_dec_float::operator-=(const cpp_dec_float& v) BOOST_NOEXCEPT +template +cpp_dec_float& cpp_dec_float::operator-=(const cpp_dec_float& v) BOOST_NOEXCEPT { // Use *this - v = -(-*this + v). negate(); @@ -808,8 +822,8 @@ cpp_dec_float& cpp_dec_float::operator-=(const cpp_dec_float return *this; } -template -cpp_dec_float& cpp_dec_float::operator*=(const cpp_dec_float& v) BOOST_NOEXCEPT +template +cpp_dec_float& cpp_dec_float::operator*=(const cpp_dec_float& v) BOOST_NOEXCEPT { // Evaluate the sign of the result. const bool b_result_is_neg = (neg != v.neg); @@ -846,17 +860,17 @@ cpp_dec_float& cpp_dec_float::operator*=(const cpp_dec_float } // Check for overflow or underflow. - const bool u_exp_is_neg = (exp < static_cast(0)); - const bool v_exp_is_neg = (v.exp < static_cast(0)); + const bool u_exp_is_neg = (exp < static_cast(0)); + const bool v_exp_is_neg = (v.exp < static_cast(0)); if(u_exp_is_neg == v_exp_is_neg) { // Get the unsigned base-10 exponents of *this and v and... - const boost::int64_t u_exp = ((!u_exp_is_neg) ? exp : static_cast( -exp)); - const boost::int64_t v_exp = ((!v_exp_is_neg) ? v.exp : static_cast(-v.exp)); + const ExponentType u_exp = ((!u_exp_is_neg) ? exp : static_cast( -exp)); + const ExponentType v_exp = ((!v_exp_is_neg) ? v.exp : static_cast(-v.exp)); // Check the range of the upcoming multiplication. - const bool b_result_is_out_of_range = (v_exp >= static_cast(cpp_dec_float_max_exp10 - u_exp)); + const bool b_result_is_out_of_range = (v_exp >= static_cast(cpp_dec_float_max_exp10 - u_exp)); if(b_result_is_out_of_range) { @@ -901,8 +915,8 @@ cpp_dec_float& cpp_dec_float::operator*=(const cpp_dec_float return *this; } -template -cpp_dec_float& cpp_dec_float::operator/=(const cpp_dec_float& v) BOOST_NOEXCEPT +template +cpp_dec_float& cpp_dec_float::operator/=(const cpp_dec_float& v) BOOST_NOEXCEPT { const bool u_and_v_are_finite_and_identical = ( isfinite() && (fpclass == v.fpclass) @@ -936,8 +950,8 @@ cpp_dec_float& cpp_dec_float::operator/=(const cpp_dec_float } } -template -cpp_dec_float& cpp_dec_float::mul_unsigned_long_long(const unsigned long long n) BOOST_NOEXCEPT +template +cpp_dec_float& cpp_dec_float::mul_unsigned_long_long(const unsigned long long n) BOOST_NOEXCEPT { // Multiply *this with a constant unsigned long long. @@ -991,7 +1005,7 @@ cpp_dec_float& cpp_dec_float::mul_unsigned_long_long(const u // Handle the carry and adjust the exponent. if(carry != static_cast(0u)) { - exp += static_cast(cpp_dec_float_elem_digits10); + exp += static_cast(cpp_dec_float_elem_digits10); // Shift the result of the multiplication one element to the right. std::copy_backward(data.begin(), @@ -1031,8 +1045,8 @@ cpp_dec_float& cpp_dec_float::mul_unsigned_long_long(const u return *this; } -template -cpp_dec_float& cpp_dec_float::div_unsigned_long_long(const unsigned long long n) BOOST_NOEXCEPT +template +cpp_dec_float& cpp_dec_float::div_unsigned_long_long(const unsigned long long n) BOOST_NOEXCEPT { // Divide *this by a constant unsigned long long. @@ -1097,7 +1111,7 @@ cpp_dec_float& cpp_dec_float::div_unsigned_long_long(const u if(data[0] == static_cast(0u)) { // Adjust the exponent - exp -= static_cast(cpp_dec_float_elem_digits10); + exp -= static_cast(cpp_dec_float_elem_digits10); // Shift result of the division one element to the left. std::copy(data.begin() + static_cast(1u), @@ -1120,8 +1134,8 @@ cpp_dec_float& cpp_dec_float::div_unsigned_long_long(const u return *this; } -template -cpp_dec_float& cpp_dec_float::calculate_inv() BOOST_NOEXCEPT +template +cpp_dec_float& cpp_dec_float::calculate_inv() BOOST_NOEXCEPT { // Compute the inverse of *this. const bool b_neg = neg; @@ -1155,17 +1169,17 @@ cpp_dec_float& cpp_dec_float::calculate_inv() BOOST_NOEXCEPT } // Save the original *this. - cpp_dec_float x(*this); + cpp_dec_float x(*this); // Generate the initial estimate using division. // Extract the mantissa and exponent for a "manual" // computation of the estimate. double dd; - boost::int64_t ne; + ExponentType ne; x.extract_parts(dd, ne); // Do the inverse estimate using double precision estimates of mantissa and exponent. - operator=(cpp_dec_float(1.0 / dd, -ne)); + operator=(cpp_dec_float(1.0 / dd, -ne)); // Compute the inverse of *this. Quadratically convergent Newton-Raphson iteration // is used. During the iterative steps, the precision of the calculation is limited @@ -1194,8 +1208,8 @@ cpp_dec_float& cpp_dec_float::calculate_inv() BOOST_NOEXCEPT return *this; } -template -cpp_dec_float& cpp_dec_float::calculate_sqrt(void) BOOST_NOEXCEPT +template +cpp_dec_float& cpp_dec_float::calculate_sqrt(void) BOOST_NOEXCEPT { // Compute the square root of *this. @@ -1211,17 +1225,17 @@ cpp_dec_float& cpp_dec_float::calculate_sqrt(void) BOOST_NOE } // Save the original *this. - cpp_dec_float x(*this); + cpp_dec_float x(*this); // Generate the initial estimate using division. // Extract the mantissa and exponent for a "manual" // computation of the estimate. double dd; - boost::int64_t ne; + ExponentType ne; extract_parts(dd, ne); // Force the exponent to be an even multiple of two. - if((ne % static_cast(2)) != static_cast(0)) + if((ne % static_cast(2)) != static_cast(0)) { ++ne; dd /= 10.0; @@ -1231,10 +1245,10 @@ cpp_dec_float& cpp_dec_float::calculate_sqrt(void) BOOST_NOE // Estimate the square root using simple manipulations. const double sqd = std::sqrt(dd); - *this = cpp_dec_float(sqd, static_cast(ne / static_cast(2))); + *this = cpp_dec_float(sqd, static_cast(ne / static_cast(2))); // Estimate 1.0 / (2.0 * x0) using simple manipulations. - cpp_dec_float vi(0.5 / sqd, static_cast(-ne / static_cast(2))); + cpp_dec_float vi(0.5 / sqd, static_cast(-ne / static_cast(2))); // Compute the square root of x. Coupled Newton iteration // as described in "Pi Unleashed" is used. During the @@ -1277,8 +1291,8 @@ cpp_dec_float& cpp_dec_float::calculate_sqrt(void) BOOST_NOE return *this; } -template -int cpp_dec_float::cmp_data(const array_type& vd) const BOOST_NOEXCEPT +template +int cpp_dec_float::cmp_data(const array_type& vd) const BOOST_NOEXCEPT { // Compare the data of *this with those of v. // Return +1 for *this > v @@ -1299,8 +1313,8 @@ int cpp_dec_float::cmp_data(const array_type& vd) const BOOST_NOEXCEPT } } -template -int cpp_dec_float::compare(const cpp_dec_float& v) const BOOST_NOEXCEPT +template +int cpp_dec_float::compare(const cpp_dec_float& v) const BOOST_NOEXCEPT { // Compare v with *this. // Return +1 for *this > v @@ -1377,8 +1391,8 @@ int cpp_dec_float::compare(const cpp_dec_float& v) const BOOST_NOEXCEP } } -template -bool cpp_dec_float::isone() const BOOST_NOEXCEPT +template +bool cpp_dec_float::isone() const BOOST_NOEXCEPT { // Check if the value of *this is identically 1 or very close to 1. @@ -1386,12 +1400,12 @@ bool cpp_dec_float::isone() const BOOST_NOEXCEPT if(not_negative_and_is_finite) { - if((data[0u] == static_cast(1u)) && (exp == static_cast(0))) + if((data[0u] == static_cast(1u)) && (exp == static_cast(0))) { const typename array_type::const_iterator it_non_zero = std::find_if(data.begin(), data.end(), data_elem_is_non_zero_predicate); return (it_non_zero == data.end()); } - else if((data[0u] == static_cast(cpp_dec_float_elem_mask - 1)) && (exp == static_cast(-cpp_dec_float_elem_digits10))) + else if((data[0u] == static_cast(cpp_dec_float_elem_mask - 1)) && (exp == static_cast(-cpp_dec_float_elem_digits10))) { const typename array_type::const_iterator it_non_nine = std::find_if(data.begin(), data.end(), data_elem_is_non_nine_predicate); return (it_non_nine == data.end()); @@ -1401,14 +1415,14 @@ bool cpp_dec_float::isone() const BOOST_NOEXCEPT return false; } -template -bool cpp_dec_float::isint() const BOOST_NOEXCEPT +template +bool cpp_dec_float::isint() const BOOST_NOEXCEPT { if(fpclass != cpp_dec_float_finite) { return false; } if(iszero()) { return true; } - if(exp < static_cast(0)) { return false; } // |*this| < 1. + if(exp < static_cast(0)) { return false; } // |*this| < 1. const typename array_type::size_type offset_decimal_part = static_cast(exp / cpp_dec_float_elem_digits10) + 1u; @@ -1424,10 +1438,10 @@ bool cpp_dec_float::isint() const BOOST_NOEXCEPT return (it_non_zero == data.end()); } -template -void cpp_dec_float::extract_parts(double& mantissa, boost::int64_t& exponent) const BOOST_NOEXCEPT +template +void cpp_dec_float::extract_parts(double& mantissa, ExponentType& exponent) const BOOST_NOEXCEPT { - // Extract the approximate parts mantissa and base-10 exponent from the input cpp_dec_float value x. + // Extract the approximate parts mantissa and base-10 exponent from the input cpp_dec_float value x. // Extracts the mantissa and exponent. exponent = exp; @@ -1457,12 +1471,12 @@ void cpp_dec_float::extract_parts(double& mantissa, boost::int64_t& ex if(neg) { mantissa = -mantissa; } } -template -double cpp_dec_float::extract_double(void) const BOOST_NOEXCEPT +template +double cpp_dec_float::extract_double(void) const BOOST_NOEXCEPT { - // Returns the double conversion of a cpp_dec_float. + // Returns the double conversion of a cpp_dec_float. - // Check for non-normal cpp_dec_float. + // Check for non-normal cpp_dec_float. if(!isfinite()) { if(isnan()) @@ -1476,17 +1490,17 @@ double cpp_dec_float::extract_double(void) const BOOST_NOEXCEPT } } - cpp_dec_float xx(*this); + cpp_dec_float xx(*this); if(xx.isneg()) xx.negate(); - // Check if *this cpp_dec_float is zero. + // Check if *this cpp_dec_float is zero. if(iszero() || (xx.compare(double_min()) < 0)) { return 0.0; } - // Check if *this cpp_dec_float exceeds the maximum of double. + // Check if *this cpp_dec_float exceeds the maximum of double. if(xx.compare(double_max()) > 0) { return ((!neg) ? std::numeric_limits::infinity() @@ -1503,12 +1517,12 @@ double cpp_dec_float::extract_double(void) const BOOST_NOEXCEPT return d; } -template -long double cpp_dec_float::extract_long_double(void) const BOOST_NOEXCEPT +template +long double cpp_dec_float::extract_long_double(void) const BOOST_NOEXCEPT { - // Returns the long double conversion of a cpp_dec_float. + // Returns the long double conversion of a cpp_dec_float. - // Check if *this cpp_dec_float is subnormal. + // Check if *this cpp_dec_float is subnormal. if(!isfinite()) { if(isnan()) @@ -1522,17 +1536,17 @@ long double cpp_dec_float::extract_long_double(void) const BOOST_NOEXC } } - cpp_dec_float xx(*this); + cpp_dec_float xx(*this); if(xx.isneg()) xx.negate(); - // Check if *this cpp_dec_float is zero. + // Check if *this cpp_dec_float is zero. if(iszero() || (xx.compare(long_double_min()) < 0)) { return static_cast(0.0); } - // Check if *this cpp_dec_float exceeds the maximum of double. + // Check if *this cpp_dec_float exceeds the maximum of double. if(xx.compare(long_double_max()) > 0) { return ((!neg) ? std::numeric_limits::infinity() @@ -1549,14 +1563,14 @@ long double cpp_dec_float::extract_long_double(void) const BOOST_NOEXC return ld; } -template -signed long long cpp_dec_float::extract_signed_long_long(void) const BOOST_NOEXCEPT +template +signed long long cpp_dec_float::extract_signed_long_long(void) const BOOST_NOEXCEPT { // Extracts a signed long long from *this. // If (x > maximum of signed long long) or (x < minimum of signed long long), // then the maximum or minimum of signed long long is returned accordingly. - if(exp < static_cast(0)) + if(exp < static_cast(0)) { return static_cast(0); } @@ -1576,7 +1590,7 @@ signed long long cpp_dec_float::extract_signed_long_long(void) const B else { // Extract the data into an unsigned long long value. - cpp_dec_float xn(extract_integer_part()); + cpp_dec_float xn(extract_integer_part()); if(xn.isneg()) xn.negate(); @@ -1594,8 +1608,8 @@ signed long long cpp_dec_float::extract_signed_long_long(void) const B return ((!b_neg) ? static_cast(val) : static_cast(-static_cast(val))); } -template -unsigned long long cpp_dec_float::extract_unsigned_long_long(void) const BOOST_NOEXCEPT +template +unsigned long long cpp_dec_float::extract_unsigned_long_long(void) const BOOST_NOEXCEPT { // Extracts an unsigned long long from *this. // If x exceeds the maximum of unsigned long long, @@ -1608,12 +1622,12 @@ unsigned long long cpp_dec_float::extract_unsigned_long_long(void) con return static_cast(extract_signed_long_long()); } - if(exp < static_cast(0)) + if(exp < static_cast(0)) { return static_cast(0u); } - const cpp_dec_float xn(extract_integer_part()); + const cpp_dec_float xn(extract_integer_part()); unsigned long long val; @@ -1638,8 +1652,8 @@ unsigned long long cpp_dec_float::extract_unsigned_long_long(void) con return val; } -template -cpp_dec_float cpp_dec_float::extract_integer_part(void) const BOOST_NOEXCEPT +template +cpp_dec_float cpp_dec_float::extract_integer_part(void) const BOOST_NOEXCEPT { // Compute the signed integer part of x. @@ -1648,7 +1662,7 @@ cpp_dec_float cpp_dec_float::extract_integer_part(void) cons return *this; } - if(exp < static_cast(0)) + if(exp < static_cast(0)) { // The absolute value of the number is smaller than 1. // Thus the integer part is zero. @@ -1662,7 +1676,7 @@ cpp_dec_float cpp_dec_float::extract_integer_part(void) cons } // Make a local copy. - cpp_dec_float x = *this; + cpp_dec_float x = *this; // Clear out the decimal portion const size_t first_clear = (static_cast(x.exp) / static_cast(cpp_dec_float_elem_digits10)) + 1u; @@ -1673,8 +1687,8 @@ cpp_dec_float cpp_dec_float::extract_integer_part(void) cons return x; } -template -std::string cpp_dec_float::str(boost::intmax_t number_of_digits, std::ios_base::fmtflags f) const +template +std::string cpp_dec_float::str(boost::intmax_t number_of_digits, std::ios_base::fmtflags f) const { if(this->isinf()) { @@ -1692,7 +1706,7 @@ std::string cpp_dec_float::str(boost::intmax_t number_of_digits, std:: std::string str; boost::intmax_t org_digits(number_of_digits); - boost::int64_t my_exp = order(); + ExponentType my_exp = order(); if(number_of_digits == 0) number_of_digits = cpp_dec_float_total_digits10; if(f & std::ios_base::fixed) @@ -1701,14 +1715,14 @@ std::string cpp_dec_float::str(boost::intmax_t number_of_digits, std:: } else if(f & std::ios_base::scientific) ++number_of_digits; - // Determine the number of elements needed to provide the requested digits from cpp_dec_float. + // Determine the number of elements needed to provide the requested digits from cpp_dec_float. const std::size_t number_of_elements = (std::min)(static_cast((number_of_digits / static_cast(cpp_dec_float_elem_digits10)) + 2u), static_cast(cpp_dec_float_elem_number)); - // Extract the remaining digits from cpp_dec_float after the decimal point. + // Extract the remaining digits from cpp_dec_float after the decimal point. str = boost::lexical_cast(data[0]); - // Extract all of the digits from cpp_dec_float, beginning with the first data element. + // Extract all of the digits from cpp_dec_float, beginning with the first data element. for(std::size_t i = static_cast(1u); i < number_of_elements; i++) { std::stringstream ss; @@ -1826,8 +1840,8 @@ std::string cpp_dec_float::str(boost::intmax_t number_of_digits, std:: return str; } -template -bool cpp_dec_float::rd_string(const char* const s) +template +bool cpp_dec_float::rd_string(const char* const s) { try{ @@ -1837,7 +1851,7 @@ bool cpp_dec_float::rd_string(const char* const s) // the code complexity (and perhaps the run-time) of rd_string(). // Get a possible exponent and remove it. - exp = static_cast(0); + exp = static_cast(0); std::size_t pos; @@ -1846,7 +1860,7 @@ bool cpp_dec_float::rd_string(const char* const s) ) { // Remove the exponent part from the string. - exp = boost::lexical_cast(static_cast(str.c_str() + (pos + 1u))); + exp = boost::lexical_cast(static_cast(str.c_str() + (pos + 1u))); str = str.substr(static_cast(0u), pos); } @@ -1903,7 +1917,7 @@ bool cpp_dec_float::rd_string(const char* const s) } } - // Put the input string into the standard cpp_dec_float input form + // Put the input string into the standard cpp_dec_float input form // aaa.bbbbE+/-n, where aaa has 1...cpp_dec_float_elem_digits10, bbbb has an // even multiple of cpp_dec_float_elem_digits10 which are possibly zero padded // on the right-end, and n is a signed 64-bit integer which is an @@ -1948,7 +1962,7 @@ bool cpp_dec_float::rd_string(const char* const s) // Bring one single digit into the mantissa and adjust the exponent accordingly. str.erase(str.begin(), it_non_zero); str.insert(static_cast(1u), "."); - exp -= static_cast(delta_exp + 1u); + exp -= static_cast(delta_exp + 1u); } } else @@ -1959,11 +1973,11 @@ bool cpp_dec_float::rd_string(const char* const s) // Shift the decimal point such that the exponent is an even multiple of cpp_dec_float_elem_digits10. std::size_t n_shift = static_cast(0u); - const std::size_t n_exp_rem = static_cast(exp % static_cast(cpp_dec_float_elem_digits10)); + const std::size_t n_exp_rem = static_cast(exp % static_cast(cpp_dec_float_elem_digits10)); - if((exp % static_cast(cpp_dec_float_elem_digits10)) != static_cast(0)) + if((exp % static_cast(cpp_dec_float_elem_digits10)) != static_cast(0)) { - n_shift = ((exp < static_cast(0)) + n_shift = ((exp < static_cast(0)) ? static_cast(n_exp_rem + static_cast(cpp_dec_float_elem_digits10)) : static_cast(n_exp_rem)); } @@ -1987,7 +2001,7 @@ bool cpp_dec_float::rd_string(const char* const s) str.erase(pos, static_cast(1u)); - exp -= static_cast(n_shift); + exp -= static_cast(n_shift); } // Cut the size of the mantissa to <= cpp_dec_float_elem_digits10. @@ -2004,7 +2018,7 @@ bool cpp_dec_float::rd_string(const char* const s) str.erase(pos_plus_one, static_cast(1u)); - exp += static_cast(static_cast(n) * static_cast(cpp_dec_float_elem_digits10)); + exp += static_cast(static_cast(n) * static_cast(cpp_dec_float_elem_digits10)); } // Pad the decimal part such that its value is an even @@ -2031,7 +2045,7 @@ bool cpp_dec_float::rd_string(const char* const s) static_cast(pos_plus_one + max_dec)); } - // Now the input string has the standard cpp_dec_float input form. + // Now the input string has the standard cpp_dec_float input form. // (See the comment above.) // Set all the data elements to 0. @@ -2070,9 +2084,9 @@ bool cpp_dec_float::rd_string(const char* const s) if(exp == cpp_dec_float_min_exp10) { // Check for identity with the minimum value. - cpp_dec_float test = *this; + cpp_dec_float test = *this; - test.exp = static_cast(0); + test.exp = static_cast(0); if(test.isone()) { @@ -2098,15 +2112,15 @@ bool cpp_dec_float::rd_string(const char* const s) return true; } -template -cpp_dec_float::cpp_dec_float(const double mantissa, const long long exponent) BOOST_NOEXCEPT +template +cpp_dec_float::cpp_dec_float(const double mantissa, const ExponentType exponent) BOOST_NOEXCEPT : data (), - exp (static_cast(0)), + exp (static_cast(0)), neg (false), fpclass (cpp_dec_float_finite), prec_elem(cpp_dec_float_elem_number) { - // Create *this cpp_dec_float from a given mantissa and exponent. + // Create *this cpp_dec_float from a given mantissa and exponent. // Note: This constructor does not maintain the full precision of double. const bool mantissa_is_iszero = (::fabs(mantissa) < ((std::numeric_limits::min)() * (1.0 + std::numeric_limits::epsilon()))); @@ -2120,7 +2134,7 @@ cpp_dec_float::cpp_dec_float(const double mantissa, const long long ex const bool b_neg = (mantissa < 0.0); double d = ((!b_neg) ? mantissa : -mantissa); - boost::int64_t e = exponent; + ExponentType e = exponent; while(d > 10.0) { d /= 10.0; ++e; } while(d < 1.0) { d *= 10.0; --e; } @@ -2150,8 +2164,8 @@ cpp_dec_float::cpp_dec_float(const double mantissa, const long long ex } } -template -cpp_dec_float& cpp_dec_float::operator = (long double a) BOOST_NOEXCEPT +template +cpp_dec_float& cpp_dec_float::operator = (long double a) BOOST_NOEXCEPT { // Christopher Kormanyos's original code used a cast to long long here, but that fails // when long double has more digits than a long long. @@ -2200,12 +2214,12 @@ cpp_dec_float& cpp_dec_float::operator = (long double a) BOO return *this; } -template -void cpp_dec_float::from_unsigned_long_long(const unsigned long long u) BOOST_NOEXCEPT +template +void cpp_dec_float::from_unsigned_long_long(const unsigned long long u) BOOST_NOEXCEPT { std::fill(data.begin(), data.end(), static_cast(0u)); - exp = static_cast(0); + exp = static_cast(0); neg = false; fpclass = cpp_dec_float_finite; prec_elem = cpp_dec_float_elem_number; @@ -2225,15 +2239,15 @@ void cpp_dec_float::from_unsigned_long_long(const unsigned long long u if(i > static_cast(1u)) { - exp += static_cast((i - 1u) * static_cast(cpp_dec_float_elem_digits10)); + exp += static_cast((i - 1u) * static_cast(cpp_dec_float_elem_digits10)); } std::reverse(temp, temp + i); std::copy(temp, temp + (std::min)(i, static_cast(cpp_dec_float_elem_number)), data.begin()); } -template -boost::uint32_t cpp_dec_float::mul_loop_uv(boost::uint32_t* const u, const boost::uint32_t* const v, const boost::int32_t p) BOOST_NOEXCEPT +template +boost::uint32_t cpp_dec_float::mul_loop_uv(boost::uint32_t* const u, const boost::uint32_t* const v, const boost::int32_t p) BOOST_NOEXCEPT { // // There is a limit on how many limbs this algorithm can handle without dropping digits @@ -2261,8 +2275,8 @@ boost::uint32_t cpp_dec_float::mul_loop_uv(boost::uint32_t* const u, c return static_cast(carry); } -template -boost::uint32_t cpp_dec_float::mul_loop_n(boost::uint32_t* const u, boost::uint32_t n, const boost::int32_t p) BOOST_NOEXCEPT +template +boost::uint32_t cpp_dec_float::mul_loop_n(boost::uint32_t* const u, boost::uint32_t n, const boost::int32_t p) BOOST_NOEXCEPT { boost::uint64_t carry = static_cast(0u); @@ -2277,8 +2291,8 @@ boost::uint32_t cpp_dec_float::mul_loop_n(boost::uint32_t* const u, bo return static_cast(carry); } -template -boost::uint32_t cpp_dec_float::div_loop_n(boost::uint32_t* const u, boost::uint32_t n, const boost::int32_t p) BOOST_NOEXCEPT +template +boost::uint32_t cpp_dec_float::div_loop_n(boost::uint32_t* const u, boost::uint32_t n, const boost::int32_t p) BOOST_NOEXCEPT { boost::uint64_t prev = static_cast(0u); @@ -2292,14 +2306,14 @@ boost::uint32_t cpp_dec_float::div_loop_n(boost::uint32_t* const u, bo return static_cast(prev); } -template -cpp_dec_float cpp_dec_float::pow2(const long long p) BOOST_NOEXCEPT +template +cpp_dec_float cpp_dec_float::pow2(const long long p) BOOST_NOEXCEPT { // Create a static const table of p^2 for -128 < p < +128. // Note: The size of this table must be odd-numbered and // symmetric about 0. init.do_nothing(); - static const boost::array, 255u> p2_data = + static const boost::array, 255u> p2_data = {{ cpp_dec_float("5.877471754111437539843682686111228389093327783860437607543758531392086297273635864257812500000000000e-39"), cpp_dec_float("1.175494350822287507968736537222245677818665556772087521508751706278417259454727172851562500000000000e-38"), @@ -2558,90 +2572,90 @@ cpp_dec_float cpp_dec_float::pow2(const long long p) BOOST_N cpp_dec_float("1.701411834604692317316873037158841057280000000000000000000000000000000000000000000000000000000000000e38") }}; - if((p > static_cast(-128)) && (p < static_cast(+128))) + if((p > static_cast(-128)) && (p < static_cast(+128))) { return p2_data[static_cast(p + ((p2_data.size() - 1u) / 2u))]; } // Compute and return 2^p. - if(p < static_cast(0)) + if(p < static_cast(0)) { - return pow2(static_cast(-p)).calculate_inv(); + return pow2(static_cast(-p)).calculate_inv(); } - else if(p < static_cast(std::numeric_limits::digits)) + else if(p < static_cast(std::numeric_limits::digits)) { const boost::uint64_t p2 = static_cast(static_cast(1uLL) << p); return cpp_dec_float(p2); } else { - cpp_dec_float t; + cpp_dec_float t; default_ops::detail::pow_imp(t, two(), p, mpl::true_()); return t; } } -template -inline void eval_add(cpp_dec_float& result, const cpp_dec_float& o) BOOST_NOEXCEPT +template +inline void eval_add(cpp_dec_float& result, const cpp_dec_float& o) BOOST_NOEXCEPT { result += o; } -template -inline void eval_subtract(cpp_dec_float& result, const cpp_dec_float& o) BOOST_NOEXCEPT +template +inline void eval_subtract(cpp_dec_float& result, const cpp_dec_float& o) BOOST_NOEXCEPT { result -= o; } -template -inline void eval_multiply(cpp_dec_float& result, const cpp_dec_float& o) BOOST_NOEXCEPT +template +inline void eval_multiply(cpp_dec_float& result, const cpp_dec_float& o) BOOST_NOEXCEPT { result *= o; } -template -inline void eval_divide(cpp_dec_float& result, const cpp_dec_float& o) BOOST_NOEXCEPT +template +inline void eval_divide(cpp_dec_float& result, const cpp_dec_float& o) BOOST_NOEXCEPT { result /= o; } -template -inline void eval_add(cpp_dec_float& result, const unsigned long long& o) BOOST_NOEXCEPT +template +inline void eval_add(cpp_dec_float& result, const unsigned long long& o) BOOST_NOEXCEPT { result.add_unsigned_long_long(o); } -template -inline void eval_subtract(cpp_dec_float& result, const unsigned long long& o) BOOST_NOEXCEPT +template +inline void eval_subtract(cpp_dec_float& result, const unsigned long long& o) BOOST_NOEXCEPT { result.sub_unsigned_long_long(o); } -template -inline void eval_multiply(cpp_dec_float& result, const unsigned long long& o) BOOST_NOEXCEPT +template +inline void eval_multiply(cpp_dec_float& result, const unsigned long long& o) BOOST_NOEXCEPT { result.mul_unsigned_long_long(o); } -template -inline void eval_divide(cpp_dec_float& result, const unsigned long long& o) BOOST_NOEXCEPT +template +inline void eval_divide(cpp_dec_float& result, const unsigned long long& o) BOOST_NOEXCEPT { result.div_unsigned_long_long(o); } -template -inline void eval_add(cpp_dec_float& result, long long o) BOOST_NOEXCEPT +template +inline void eval_add(cpp_dec_float& result, long long o) BOOST_NOEXCEPT { if(o < 0) result.sub_unsigned_long_long(-o); else result.add_unsigned_long_long(o); } -template -inline void eval_subtract(cpp_dec_float& result, long long o) BOOST_NOEXCEPT +template +inline void eval_subtract(cpp_dec_float& result, long long o) BOOST_NOEXCEPT { if(o < 0) result.add_unsigned_long_long(-o); else result.sub_unsigned_long_long(o); } -template -inline void eval_multiply(cpp_dec_float& result, long long o) BOOST_NOEXCEPT +template +inline void eval_multiply(cpp_dec_float& result, long long o) BOOST_NOEXCEPT { if(o < 0) { @@ -2651,8 +2665,8 @@ inline void eval_multiply(cpp_dec_float& result, long long o) BOOST_NO else result.mul_unsigned_long_long(o); } -template -inline void eval_divide(cpp_dec_float& result, long long o) BOOST_NOEXCEPT +template +inline void eval_divide(cpp_dec_float& result, long long o) BOOST_NOEXCEPT { if(o < 0) { @@ -2663,18 +2677,18 @@ inline void eval_divide(cpp_dec_float& result, long long o) BOOST_NOEX result.div_unsigned_long_long(o); } -template -inline void eval_convert_to(unsigned long long* result, const cpp_dec_float& val) BOOST_NOEXCEPT +template +inline void eval_convert_to(unsigned long long* result, const cpp_dec_float& val) BOOST_NOEXCEPT { *result = val.extract_unsigned_long_long(); } -template -inline void eval_convert_to(long long* result, const cpp_dec_float& val) BOOST_NOEXCEPT +template +inline void eval_convert_to(long long* result, const cpp_dec_float& val) BOOST_NOEXCEPT { *result = val.extract_signed_long_long(); } -template -inline void eval_convert_to(long double* result, cpp_dec_float& val) BOOST_NOEXCEPT +template +inline void eval_convert_to(long double* result, cpp_dec_float& val) BOOST_NOEXCEPT { *result = val.extract_long_double(); } @@ -2682,8 +2696,8 @@ inline void eval_convert_to(long double* result, cpp_dec_float& val) B // // Non member function support: // -template -inline int eval_fpclassify(const cpp_dec_float& x) BOOST_NOEXCEPT +template +inline int eval_fpclassify(const cpp_dec_float& x) BOOST_NOEXCEPT { if(x.isinf()) return FP_INFINITE; @@ -2694,31 +2708,31 @@ inline int eval_fpclassify(const cpp_dec_float& x) BOOST_NOEXCEPT return FP_NORMAL; } -template -inline void eval_abs(cpp_dec_float& result, const cpp_dec_float& x) BOOST_NOEXCEPT +template +inline void eval_abs(cpp_dec_float& result, const cpp_dec_float& x) BOOST_NOEXCEPT { result = x; if(x.isneg()) result.negate(); } -template -inline void eval_fabs(cpp_dec_float& result, const cpp_dec_float& x) BOOST_NOEXCEPT +template +inline void eval_fabs(cpp_dec_float& result, const cpp_dec_float& x) BOOST_NOEXCEPT { result = x; if(x.isneg()) result.negate(); } -template -inline void eval_sqrt(cpp_dec_float& result, const cpp_dec_float& x) BOOST_NOEXCEPT +template +inline void eval_sqrt(cpp_dec_float& result, const cpp_dec_float& x) BOOST_NOEXCEPT { result = x; result.calculate_sqrt(); } -template -inline void eval_floor(cpp_dec_float& result, const cpp_dec_float& x) BOOST_NOEXCEPT +template +inline void eval_floor(cpp_dec_float& result, const cpp_dec_float& x) BOOST_NOEXCEPT { result = x; if(!x.isfinite() || x.isint()) @@ -2727,12 +2741,12 @@ inline void eval_floor(cpp_dec_float& result, const cpp_dec_float::one(); + result -= cpp_dec_float::one(); result = result.extract_integer_part(); } -template -inline void eval_ceil(cpp_dec_float& result, const cpp_dec_float& x) BOOST_NOEXCEPT +template +inline void eval_ceil(cpp_dec_float& result, const cpp_dec_float& x) BOOST_NOEXCEPT { result = x; if(!x.isfinite() || x.isint()) @@ -2741,16 +2755,16 @@ inline void eval_ceil(cpp_dec_float& result, const cpp_dec_float::one(); + result += cpp_dec_float::one(); result = result.extract_integer_part(); } -template -inline void eval_trunc(cpp_dec_float& result, const cpp_dec_float& x) +template +inline void eval_trunc(cpp_dec_float& result, const cpp_dec_float& x) { if(!x.isfinite()) { - result = boost::math::policies::raise_rounding_error("boost::multiprecision::trunc<%1%>(%1%)", 0, number >(x), 0, boost::math::policies::policy<>()).backend(); + result = boost::math::policies::raise_rounding_error("boost::multiprecision::trunc<%1%>(%1%)", 0, number >(x), 0, boost::math::policies::policy<>()).backend(); return; } else if(x.isint()) @@ -2761,15 +2775,17 @@ inline void eval_trunc(cpp_dec_float& result, const cpp_dec_float -inline void eval_ldexp(cpp_dec_float& result, const cpp_dec_float& x, long long e) BOOST_NOEXCEPT +template +inline void eval_ldexp(cpp_dec_float& result, const cpp_dec_float& x, ArgType e) BOOST_NOEXCEPT { + if((static_cast(e) > (std::numeric_limits::max)()) || (static_cast(e) < (std::numeric_limits::min)())) + BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Exponent value is out of range."))); result = x; - result *= cpp_dec_float::pow2(e); + result *= cpp_dec_float::pow2(e); } -template -inline void eval_frexp(cpp_dec_float& result, const cpp_dec_float& x, long long* e) +template +inline void eval_frexp(cpp_dec_float& result, const cpp_dec_float& x, ExponentType* e) { result = x; if(result.isneg()) @@ -2781,9 +2797,9 @@ inline void eval_frexp(cpp_dec_float& result, const cpp_dec_float::max)() / 1000)) + if(abs(t) < ((std::numeric_limits::max)() / 1000)) { t *= 1000; t /= 301; @@ -2794,7 +2810,7 @@ inline void eval_frexp(cpp_dec_float& result, const cpp_dec_float::pow2(-t); + result *= cpp_dec_float::pow2(-t); if(result.iszero() || result.isinf() || result.isnan()) { @@ -2803,32 +2819,32 @@ inline void eval_frexp(cpp_dec_float& result, const cpp_dec_float::pow2(-t); + result *= cpp_dec_float::pow2(-t); } BOOST_MP_USING_ABS if(abs(result.order()) > 5) { // If our first estimate doesn't get close enough then try recursion until we do: - long long e2; - cpp_dec_float r2; + ExponentType e2; + cpp_dec_float r2; eval_frexp(r2, result, &e2); // overflow protection: - if((t > 0) && (e2 > 0) && (t > (std::numeric_limits::max)() - e2)) + if((t > 0) && (e2 > 0) && (t > (std::numeric_limits::max)() - e2)) BOOST_THROW_EXCEPTION(std::runtime_error("Exponent is too large to be represented as a power of 2.")); - if((t < 0) && (e2 < 0) && (t < (std::numeric_limits::min)() - e2)) + if((t < 0) && (e2 < 0) && (t < (std::numeric_limits::min)() - e2)) BOOST_THROW_EXCEPTION(std::runtime_error("Exponent is too large to be represented as a power of 2.")); t += e2; result = r2; } - while(result.compare(cpp_dec_float::one()) >= 0) + while(result.compare(cpp_dec_float::one()) >= 0) { - result /= cpp_dec_float::two(); + result /= cpp_dec_float::two(); ++t; } - while(result.compare(cpp_dec_float::half()) < 0) + while(result.compare(cpp_dec_float::half()) < 0) { - result *= cpp_dec_float::two(); + result *= cpp_dec_float::two(); --t; } *e = t; @@ -2836,23 +2852,23 @@ inline void eval_frexp(cpp_dec_float& result, const cpp_dec_float -inline void eval_frexp(cpp_dec_float& result, const cpp_dec_float& x, int* e) +template +inline typename disable_if >::type eval_frexp(cpp_dec_float& result, const cpp_dec_float& x, int* e) { - long long t; + ExponentType t; eval_frexp(result, x, &t); - if(t > (std::numeric_limits::max)()) + if((t > (std::numeric_limits::max)()) || (t < (std::numeric_limits::min)())) BOOST_THROW_EXCEPTION(std::runtime_error("Exponent is outside the range of an int")); *e = static_cast(t); } -template -inline bool eval_is_zero(const cpp_dec_float& val) BOOST_NOEXCEPT +template +inline bool eval_is_zero(const cpp_dec_float& val) BOOST_NOEXCEPT { return val.iszero(); } -template -inline int eval_get_sign(const cpp_dec_float& val) BOOST_NOEXCEPT +template +inline int eval_get_sign(const cpp_dec_float& val) BOOST_NOEXCEPT { return val.iszero() ? 0 : val.isneg() ? -1 : 1; } @@ -2869,8 +2885,8 @@ typedef number > cpp_dec_float_100; namespace detail{ -template -struct is_explicitly_convertible, cpp_dec_float > : public mpl::true_ {}; +template +struct is_explicitly_convertible, cpp_dec_float > : public mpl::true_ {}; } @@ -2881,8 +2897,8 @@ struct is_explicitly_convertible, cpp_dec_float > : public namespace std { - template - class numeric_limits, ExpressionTemplates> > + template + class numeric_limits, ExpressionTemplates> > { public: BOOST_STATIC_CONSTEXPR bool is_specialized = true; @@ -2892,14 +2908,14 @@ namespace std BOOST_STATIC_CONSTEXPR bool is_bounded = true; BOOST_STATIC_CONSTEXPR bool is_modulo = false; BOOST_STATIC_CONSTEXPR bool is_iec559 = false; - BOOST_STATIC_CONSTEXPR int digits = boost::multiprecision::cpp_dec_float::cpp_dec_float_digits10; - BOOST_STATIC_CONSTEXPR int digits10 = boost::multiprecision::cpp_dec_float::cpp_dec_float_digits10; - BOOST_STATIC_CONSTEXPR int max_digits10 = boost::multiprecision::cpp_dec_float::cpp_dec_float_total_digits10; - BOOST_STATIC_CONSTEXPR boost::int64_t min_exponent = boost::multiprecision::cpp_dec_float::cpp_dec_float_min_exp; // Type differs from int. - BOOST_STATIC_CONSTEXPR boost::int64_t min_exponent10 = boost::multiprecision::cpp_dec_float::cpp_dec_float_min_exp10; // Type differs from int. - BOOST_STATIC_CONSTEXPR boost::int64_t max_exponent = boost::multiprecision::cpp_dec_float::cpp_dec_float_max_exp; // Type differs from int. - BOOST_STATIC_CONSTEXPR boost::int64_t max_exponent10 = boost::multiprecision::cpp_dec_float::cpp_dec_float_max_exp10; // Type differs from int. - BOOST_STATIC_CONSTEXPR int radix = boost::multiprecision::cpp_dec_float::cpp_dec_float_radix; + BOOST_STATIC_CONSTEXPR int digits = boost::multiprecision::cpp_dec_float::cpp_dec_float_digits10; + BOOST_STATIC_CONSTEXPR int digits10 = boost::multiprecision::cpp_dec_float::cpp_dec_float_digits10; + BOOST_STATIC_CONSTEXPR int max_digits10 = boost::multiprecision::cpp_dec_float::cpp_dec_float_total_digits10; + BOOST_STATIC_CONSTEXPR ExponentType min_exponent = boost::multiprecision::cpp_dec_float::cpp_dec_float_min_exp; // Type differs from int. + BOOST_STATIC_CONSTEXPR ExponentType min_exponent10 = boost::multiprecision::cpp_dec_float::cpp_dec_float_min_exp10; // Type differs from int. + BOOST_STATIC_CONSTEXPR ExponentType max_exponent = boost::multiprecision::cpp_dec_float::cpp_dec_float_max_exp; // Type differs from int. + BOOST_STATIC_CONSTEXPR ExponentType max_exponent10 = boost::multiprecision::cpp_dec_float::cpp_dec_float_max_exp10; // Type differs from int. + BOOST_STATIC_CONSTEXPR int radix = boost::multiprecision::cpp_dec_float::cpp_dec_float_radix; BOOST_STATIC_CONSTEXPR std::float_round_style round_style = std::round_to_nearest; BOOST_STATIC_CONSTEXPR bool has_infinity = true; BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = true; @@ -2909,63 +2925,63 @@ namespace std BOOST_STATIC_CONSTEXPR bool traps = false; BOOST_STATIC_CONSTEXPR bool tinyness_before = false; - BOOST_STATIC_CONSTEXPR boost::multiprecision::number, ExpressionTemplates> (min) (void) { return (boost::multiprecision::cpp_dec_float::min)(); } - BOOST_STATIC_CONSTEXPR boost::multiprecision::number, ExpressionTemplates> (max) (void) { return (boost::multiprecision::cpp_dec_float::max)(); } - BOOST_STATIC_CONSTEXPR boost::multiprecision::number, ExpressionTemplates> lowest (void) { return boost::multiprecision::cpp_dec_float::zero(); } - BOOST_STATIC_CONSTEXPR boost::multiprecision::number, ExpressionTemplates> epsilon (void) { return boost::multiprecision::cpp_dec_float::eps(); } - BOOST_STATIC_CONSTEXPR boost::multiprecision::number, ExpressionTemplates> round_error (void) { return 0.5L; } - BOOST_STATIC_CONSTEXPR boost::multiprecision::number, ExpressionTemplates> infinity (void) { return boost::multiprecision::cpp_dec_float::inf(); } - BOOST_STATIC_CONSTEXPR boost::multiprecision::number, ExpressionTemplates> quiet_NaN (void) { return boost::multiprecision::cpp_dec_float::nan(); } - BOOST_STATIC_CONSTEXPR boost::multiprecision::number, ExpressionTemplates> signaling_NaN(void) { return boost::multiprecision::cpp_dec_float::zero(); } - BOOST_STATIC_CONSTEXPR boost::multiprecision::number, ExpressionTemplates> denorm_min (void) { return boost::multiprecision::cpp_dec_float::zero(); } + BOOST_STATIC_CONSTEXPR boost::multiprecision::number, ExpressionTemplates> (min) (void) { return (boost::multiprecision::cpp_dec_float::min)(); } + BOOST_STATIC_CONSTEXPR boost::multiprecision::number, ExpressionTemplates> (max) (void) { return (boost::multiprecision::cpp_dec_float::max)(); } + BOOST_STATIC_CONSTEXPR boost::multiprecision::number, ExpressionTemplates> lowest (void) { return boost::multiprecision::cpp_dec_float::zero(); } + BOOST_STATIC_CONSTEXPR boost::multiprecision::number, ExpressionTemplates> epsilon (void) { return boost::multiprecision::cpp_dec_float::eps(); } + BOOST_STATIC_CONSTEXPR boost::multiprecision::number, ExpressionTemplates> round_error (void) { return 0.5L; } + BOOST_STATIC_CONSTEXPR boost::multiprecision::number, ExpressionTemplates> infinity (void) { return boost::multiprecision::cpp_dec_float::inf(); } + BOOST_STATIC_CONSTEXPR boost::multiprecision::number, ExpressionTemplates> quiet_NaN (void) { return boost::multiprecision::cpp_dec_float::nan(); } + BOOST_STATIC_CONSTEXPR boost::multiprecision::number, ExpressionTemplates> signaling_NaN(void) { return boost::multiprecision::cpp_dec_float::zero(); } + BOOST_STATIC_CONSTEXPR boost::multiprecision::number, ExpressionTemplates> denorm_min (void) { return boost::multiprecision::cpp_dec_float::zero(); } }; #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION -template -BOOST_CONSTEXPR_OR_CONST int numeric_limits, ExpressionTemplates> >::digits; -template -BOOST_CONSTEXPR_OR_CONST int numeric_limits, ExpressionTemplates> >::digits10; -template -BOOST_CONSTEXPR_OR_CONST int numeric_limits, ExpressionTemplates> >::max_digits10; -template -BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::is_signed; -template -BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::is_integer; -template -BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::is_exact; -template -BOOST_CONSTEXPR_OR_CONST int numeric_limits, ExpressionTemplates> >::radix; -template -BOOST_CONSTEXPR_OR_CONST boost::int64_t numeric_limits, ExpressionTemplates> >::min_exponent; -template -BOOST_CONSTEXPR_OR_CONST boost::int64_t numeric_limits, ExpressionTemplates> >::min_exponent10; -template -BOOST_CONSTEXPR_OR_CONST boost::int64_t numeric_limits, ExpressionTemplates> >::max_exponent; -template -BOOST_CONSTEXPR_OR_CONST boost::int64_t numeric_limits, ExpressionTemplates> >::max_exponent10; -template -BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::has_infinity; -template -BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::has_quiet_NaN; -template -BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::has_signaling_NaN; -template -BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits, ExpressionTemplates> >::has_denorm; -template -BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::has_denorm_loss; -template -BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::is_iec559; -template -BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::is_bounded; -template -BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::is_modulo; -template -BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::traps; -template -BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::tinyness_before; -template -BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits, ExpressionTemplates> >::round_style; +template +BOOST_CONSTEXPR_OR_CONST int numeric_limits, ExpressionTemplates> >::digits; +template +BOOST_CONSTEXPR_OR_CONST int numeric_limits, ExpressionTemplates> >::digits10; +template +BOOST_CONSTEXPR_OR_CONST int numeric_limits, ExpressionTemplates> >::max_digits10; +template +BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::is_signed; +template +BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::is_integer; +template +BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::is_exact; +template +BOOST_CONSTEXPR_OR_CONST int numeric_limits, ExpressionTemplates> >::radix; +template +BOOST_CONSTEXPR_OR_CONST ExponentType numeric_limits, ExpressionTemplates> >::min_exponent; +template +BOOST_CONSTEXPR_OR_CONST ExponentType numeric_limits, ExpressionTemplates> >::min_exponent10; +template +BOOST_CONSTEXPR_OR_CONST ExponentType numeric_limits, ExpressionTemplates> >::max_exponent; +template +BOOST_CONSTEXPR_OR_CONST ExponentType numeric_limits, ExpressionTemplates> >::max_exponent10; +template +BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::has_infinity; +template +BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::has_quiet_NaN; +template +BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::has_signaling_NaN; +template +BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits, ExpressionTemplates> >::has_denorm; +template +BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::has_denorm_loss; +template +BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::is_iec559; +template +BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::is_bounded; +template +BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::is_modulo; +template +BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::traps; +template +BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::tinyness_before; +template +BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits, ExpressionTemplates> >::round_style; #endif } @@ -2974,12 +2990,12 @@ namespace boost{ namespace math{ namespace policies{ -template -struct precision< boost::multiprecision::number, ExpressionTemplates>, Policy> +template +struct precision< boost::multiprecision::number, ExpressionTemplates>, Policy> { // Define a local copy of cpp_dec_float_digits10 because it might differ // from the template parameter Digits10 for small or large digit counts. - static const boost::int32_t cpp_dec_float_digits10 = boost::multiprecision::cpp_dec_float::cpp_dec_float_digits10; + static const boost::int32_t cpp_dec_float_digits10 = boost::multiprecision::cpp_dec_float::cpp_dec_float_digits10; typedef typename Policy::precision_type precision_type; typedef digits2<((cpp_dec_float_digits10 + 1LL) * 1000LL) / 301LL> digits_2; diff --git a/test/math/log1p_expm1_test.cpp b/test/math/log1p_expm1_test.cpp index 4a53064b..4df662c6 100644 --- a/test/math/log1p_expm1_test.cpp +++ b/test/math/log1p_expm1_test.cpp @@ -140,7 +140,7 @@ int test_main(int, char* []) #ifdef TEST_CPP_DEC_FLOAT test(number >(), "number >"); test(number >(), "number >"); - test(number >(), "number >"); + test(number > >(), "number > >"); #endif return 0; } diff --git a/test/math/powm1_sqrtp1m1_test.cpp b/test/math/powm1_sqrtp1m1_test.cpp index db2621eb..1fa0f76d 100644 --- a/test/math/powm1_sqrtp1m1_test.cpp +++ b/test/math/powm1_sqrtp1m1_test.cpp @@ -132,7 +132,7 @@ int test_main(int, char* []) #ifdef TEST_CPP_DEC_FLOAT test_powm1_sqrtp1m1(number >(), "number >"); test_powm1_sqrtp1m1(number >(), "number >"); - test_powm1_sqrtp1m1(number >(), "number >"); + test_powm1_sqrtp1m1(number > >(), "number > >"); #endif return 0; } diff --git a/test/math/table_type.hpp b/test/math/table_type.hpp index a6a526e5..0b78ec0f 100644 --- a/test/math/table_type.hpp +++ b/test/math/table_type.hpp @@ -27,7 +27,7 @@ inline std::ostream& operator << (std::ostream& os, string_table_entry const & w return os << static_cast(what); } -template +template struct table_type > { typedef string_table_entry type; diff --git a/test/math/test_bessel_i.cpp b/test/math/test_bessel_i.cpp index c9e7bb3c..4fc0c100 100644 --- a/test/math/test_bessel_i.cpp +++ b/test/math/test_bessel_i.cpp @@ -101,7 +101,7 @@ int test_main(int, char* []) test_bessel(number >(), "number >"); test_bessel(number >(), "number >"); test_bessel(number >(), "number >"); - test_bessel(number >(), "number >"); + test_bessel(number > >(), "number > >"); #endif return 0; } diff --git a/test/math/test_bessel_j.cpp b/test/math/test_bessel_j.cpp index 7738d5ae..d0f2acd8 100644 --- a/test/math/test_bessel_j.cpp +++ b/test/math/test_bessel_j.cpp @@ -142,7 +142,7 @@ int test_main(int, char* []) #ifdef TEST_CPP_DEC_FLOAT test_bessel(number >(), "number >"); test_bessel(number >(), "number >"); - test_bessel(number >(), "number >"); + test_bessel(number > >(), "number > >"); #endif return 0; } diff --git a/test/math/test_bessel_k.cpp b/test/math/test_bessel_k.cpp index 46ce61b9..8c4d8e54 100644 --- a/test/math/test_bessel_k.cpp +++ b/test/math/test_bessel_k.cpp @@ -115,7 +115,7 @@ int test_main(int, char* []) #ifdef TEST_CPP_DEC_FLOAT test_bessel(number >(), "number >"); test_bessel(number >(), "number >"); - test_bessel(number >(), "number >"); + test_bessel(number > >(), "number > >"); #endif return 0; } diff --git a/test/math/test_bessel_y.cpp b/test/math/test_bessel_y.cpp index adb472ca..a3a7c91b 100644 --- a/test/math/test_bessel_y.cpp +++ b/test/math/test_bessel_y.cpp @@ -141,7 +141,7 @@ int test_main(int, char* []) #ifdef TEST_CPP_DEC_FLOAT test_bessel(number >(), "number >"); test_bessel(number >(), "number >"); - test_bessel(number >(), "number >"); + test_bessel(number > >(), "number > >"); #endif return 0; } diff --git a/test/math/test_beta.cpp b/test/math/test_beta.cpp index 39409cb7..92d0fb77 100644 --- a/test/math/test_beta.cpp +++ b/test/math/test_beta.cpp @@ -127,7 +127,7 @@ int test_main(int, char* []) #ifdef TEST_CPP_DEC_FLOAT test_beta(number >(), "number >"); test_beta(number >(), "number >"); - test_beta(number >(), "number >"); + test_beta(number > >(), "number > >"); #endif return 0; } diff --git a/test/math/test_binomial_coeff.cpp b/test/math/test_binomial_coeff.cpp index daae89b2..208c5dee 100644 --- a/test/math/test_binomial_coeff.cpp +++ b/test/math/test_binomial_coeff.cpp @@ -106,7 +106,7 @@ int test_main(int, char* []) #ifdef TEST_CPP_DEC_FLOAT test_binomial(number >(), "number >"); test_binomial(number >(), "number >"); - test_binomial(number >(), "number >"); + test_binomial(number > >(), "number > >"); #endif return 0; } diff --git a/test/math/test_carlson.cpp b/test/math/test_carlson.cpp index 30f96116..d5936f38 100644 --- a/test/math/test_carlson.cpp +++ b/test/math/test_carlson.cpp @@ -98,7 +98,7 @@ int test_main(int, char* []) #ifdef TEST_CPP_DEC_FLOAT test_spots(number >(), "number >"); test_spots(number >(), "number >"); - test_spots(number >(), "number >"); + test_spots(number > >(), "number > >"); #endif return 0; } diff --git a/test/math/test_cbrt.cpp b/test/math/test_cbrt.cpp index 156e0dd6..ca2af6d3 100644 --- a/test/math/test_cbrt.cpp +++ b/test/math/test_cbrt.cpp @@ -87,7 +87,7 @@ int test_main(int, char* []) #ifdef TEST_CPP_DEC_FLOAT test_cbrt(number >(), "number >"); test_cbrt(number >(), "number >"); - test_cbrt(number >(), "number >"); + test_cbrt(number > >(), "number > >"); #endif return 0; } diff --git a/test/math/test_digamma.cpp b/test/math/test_digamma.cpp index 16653f83..a090081d 100644 --- a/test/math/test_digamma.cpp +++ b/test/math/test_digamma.cpp @@ -101,7 +101,7 @@ int test_main(int, char* []) #ifdef TEST_CPP_DEC_FLOAT test_digamma(number >(), "number >"); test_digamma(number >(), "number >"); - test_digamma(number >(), "number >"); + test_digamma(number > >(), "number > >"); #endif return 0; } diff --git a/test/math/test_ellint_1.cpp b/test/math/test_ellint_1.cpp index b74c0f56..bf8eb4a3 100644 --- a/test/math/test_ellint_1.cpp +++ b/test/math/test_ellint_1.cpp @@ -94,7 +94,7 @@ int test_main(int, char* []) #ifdef TEST_CPP_DEC_FLOAT test_spots(number >(), "number >"); test_spots(number >(), "number >"); - test_spots(number >(), "number >"); + test_spots(number > >(), "number > >"); #endif return 0; } diff --git a/test/math/test_ellint_2.cpp b/test/math/test_ellint_2.cpp index 9529a21c..d12c1d50 100644 --- a/test/math/test_ellint_2.cpp +++ b/test/math/test_ellint_2.cpp @@ -87,7 +87,7 @@ int test_main(int, char* []) #ifdef TEST_CPP_DEC_FLOAT test_spots(number >(), "number >"); test_spots(number >(), "number >"); - test_spots(number >(), "number >"); + test_spots(number > >(), "number > >"); #endif return 0; } diff --git a/test/math/test_ellint_3.cpp b/test/math/test_ellint_3.cpp index 986b864b..abc6141a 100644 --- a/test/math/test_ellint_3.cpp +++ b/test/math/test_ellint_3.cpp @@ -108,7 +108,7 @@ int test_main(int, char* []) #ifdef TEST_CPP_DEC_FLOAT test_spots(number >(), "number >"); test_spots(number >(), "number >"); - test_spots(number >(), "number >"); + test_spots(number > >(), "number > >"); #endif return 0; } diff --git a/test/math/test_erf.cpp b/test/math/test_erf.cpp index 3ce56dfc..e9308d8c 100644 --- a/test/math/test_erf.cpp +++ b/test/math/test_erf.cpp @@ -108,7 +108,7 @@ int test_main(int, char* []) #ifdef TEST_CPP_DEC_FLOAT test_erf(number >(), "number >"); test_erf(number >(), "number >"); - test_erf(number >(), "number >"); + test_erf(number > >(), "number > >"); #endif return 0; } diff --git a/test/math/test_expint.cpp b/test/math/test_expint.cpp index 90b77e79..bf5b78eb 100644 --- a/test/math/test_expint.cpp +++ b/test/math/test_expint.cpp @@ -108,7 +108,7 @@ int test_main(int, char* []) #ifdef TEST_CPP_DEC_FLOAT test_expint(number >(), "number >"); test_expint(number >(), "number >"); - test_expint(number >(), "number >"); + test_expint(number > >(), "number > >"); #endif return 0; } diff --git a/test/math/test_gamma.cpp b/test/math/test_gamma.cpp index 4e4d5636..c853bdb4 100644 --- a/test/math/test_gamma.cpp +++ b/test/math/test_gamma.cpp @@ -122,7 +122,7 @@ int test_main(int, char* []) #ifdef TEST_CPP_DEC_FLOAT test_gamma(number >(), "number >"); test_gamma(number >(), "number >"); - test_gamma(number >(), "number >"); + test_gamma(number > >(), "number > >"); #endif return 0; } diff --git a/test/math/test_hermite.cpp b/test/math/test_hermite.cpp index 277e96a7..743a3de3 100644 --- a/test/math/test_hermite.cpp +++ b/test/math/test_hermite.cpp @@ -87,7 +87,7 @@ int test_main(int, char* []) #ifdef TEST_CPP_DEC_FLOAT test_hermite(number >(), "number >"); test_hermite(number >(), "number >"); - test_hermite(number >(), "number >"); + test_hermite(number > >(), "number > >"); #endif return 0; } diff --git a/test/math/test_ibeta.cpp b/test/math/test_ibeta.cpp index e48fb900..2f6902e0 100644 --- a/test/math/test_ibeta.cpp +++ b/test/math/test_ibeta.cpp @@ -118,7 +118,7 @@ int test_main(int, char* []) #ifdef TEST_CPP_DEC_FLOAT test_beta(number >(), "number >"); test_beta(number >(), "number >"); - test_beta(number >(), "number >"); + test_beta(number > >(), "number > >"); #endif return 0; } diff --git a/test/math/test_ibeta_2.cpp b/test/math/test_ibeta_2.cpp index 212056a7..72997385 100644 --- a/test/math/test_ibeta_2.cpp +++ b/test/math/test_ibeta_2.cpp @@ -118,7 +118,7 @@ int test_main(int, char* []) #ifdef TEST_CPP_DEC_FLOAT test_beta(number >(), "number >"); test_beta(number >(), "number >"); - test_beta(number >(), "number >"); + test_beta(number > >(), "number > >"); #endif return 0; } diff --git a/test/math/test_ibeta_3.cpp b/test/math/test_ibeta_3.cpp index 8bb2a9a9..c6602542 100644 --- a/test/math/test_ibeta_3.cpp +++ b/test/math/test_ibeta_3.cpp @@ -104,7 +104,7 @@ int test_main(int, char* []) #ifdef TEST_CPP_DEC_FLOAT test_beta(number >(), "number >"); test_beta(number >(), "number >"); - test_beta(number >(), "number >"); + test_beta(number > >(), "number > >"); #endif return 0; } diff --git a/test/math/test_ibeta_4.cpp b/test/math/test_ibeta_4.cpp index d4b224ff..c7a8b20f 100644 --- a/test/math/test_ibeta_4.cpp +++ b/test/math/test_ibeta_4.cpp @@ -111,7 +111,7 @@ int test_main(int, char* []) #ifdef TEST_CPP_DEC_FLOAT test_beta(number >(), "number >"); test_beta(number >(), "number >"); - test_beta(number >(), "number >"); + test_beta(number > >(), "number > >"); #endif return 0; } diff --git a/test/math/test_ibeta_inv_1.cpp b/test/math/test_ibeta_inv_1.cpp index 54cb44eb..b9f052ca 100644 --- a/test/math/test_ibeta_inv_1.cpp +++ b/test/math/test_ibeta_inv_1.cpp @@ -97,7 +97,7 @@ int test_main(int, char* []) #ifdef TEST_CPP_DEC_FLOAT test_beta(number >(), "number >"); test_beta(number >(), "number >"); - test_beta(number >(), "number >"); + test_beta(number > >(), "number > >"); #endif return 0; } diff --git a/test/math/test_ibeta_inv_ab_4.cpp b/test/math/test_ibeta_inv_ab_4.cpp index e9916b96..82eff4e6 100644 --- a/test/math/test_ibeta_inv_ab_4.cpp +++ b/test/math/test_ibeta_inv_ab_4.cpp @@ -90,7 +90,7 @@ int test_main(int, char* []) #ifdef TEST_CPP_DEC_FLOAT test_beta(number >(), "number >"); test_beta(number >(), "number >"); - test_beta(number >(), "number >"); + test_beta(number > >(), "number > >"); #endif return 0; } diff --git a/test/math/test_igamma.cpp b/test/math/test_igamma.cpp index 50aff1c5..063cbeaf 100644 --- a/test/math/test_igamma.cpp +++ b/test/math/test_igamma.cpp @@ -94,7 +94,7 @@ int test_main(int, char* []) #ifdef TEST_CPP_DEC_FLOAT test_gamma(number >(), "number >"); test_gamma(number >(), "number >"); - test_gamma(number >(), "number >"); + test_gamma(number > >(), "number > >"); #endif return 0; } diff --git a/test/math/test_igamma_inv.cpp b/test/math/test_igamma_inv.cpp index 697b58fd..5408444e 100644 --- a/test/math/test_igamma_inv.cpp +++ b/test/math/test_igamma_inv.cpp @@ -109,7 +109,7 @@ int test_main(int, char* []) #ifdef TEST_CPP_DEC_FLOAT test_gamma(number >(), "number >"); test_gamma(number >(), "number >"); - test_gamma(number >(), "number >"); + test_gamma(number > >(), "number > >"); #endif return 0; } diff --git a/test/math/test_igamma_inva.cpp b/test/math/test_igamma_inva.cpp index 8ff4e6d4..fdd330e9 100644 --- a/test/math/test_igamma_inva.cpp +++ b/test/math/test_igamma_inva.cpp @@ -88,7 +88,7 @@ int test_main(int, char* []) #ifdef TEST_CPP_DEC_FLOAT test_gamma(number >(), "number >"); test_gamma(number >(), "number >"); - test_gamma(number >(), "number >"); + test_gamma(number > >(), "number > >"); #endif return 0; } diff --git a/test/math/test_laguerre.cpp b/test/math/test_laguerre.cpp index 8f70b1ca..65840502 100644 --- a/test/math/test_laguerre.cpp +++ b/test/math/test_laguerre.cpp @@ -87,7 +87,7 @@ int test_main(int, char* []) #ifdef TEST_CPP_DEC_FLOAT test_laguerre(number >(), "number >"); test_laguerre(number >(), "number >"); - test_laguerre(number >(), "number >"); + test_laguerre(number > >(), "number > >"); #endif return 0; } diff --git a/test/math/test_legendre.cpp b/test/math/test_legendre.cpp index f855b9c3..237310e6 100644 --- a/test/math/test_legendre.cpp +++ b/test/math/test_legendre.cpp @@ -87,7 +87,7 @@ int test_main(int, char* []) #ifdef TEST_CPP_DEC_FLOAT test_legendre_p(number >(), "number >"); test_legendre_p(number >(), "number >"); - test_legendre_p(number >(), "number >"); + test_legendre_p(number > >(), "number > >"); #endif return 0; } diff --git a/test/math/test_tgamma_ratio.cpp b/test/math/test_tgamma_ratio.cpp index 931ffe3c..cae68344 100644 --- a/test/math/test_tgamma_ratio.cpp +++ b/test/math/test_tgamma_ratio.cpp @@ -101,7 +101,7 @@ int test_main(int, char* []) #ifdef TEST_CPP_DEC_FLOAT test_tgamma_ratio(number >(), "number >"); test_tgamma_ratio(number >(), "number >"); - test_tgamma_ratio(number >(), "number >"); + test_tgamma_ratio(number > >(), "number > >"); #endif return 0; } diff --git a/test/math/test_zeta.cpp b/test/math/test_zeta.cpp index 1d2184ce..4db422fe 100644 --- a/test/math/test_zeta.cpp +++ b/test/math/test_zeta.cpp @@ -96,7 +96,7 @@ int test_main(int, char* []) test_zeta(number >(), "number >"); test_zeta(number >(), "number >"); test_zeta(number >(), "number >"); - test_zeta(number >(), "number >"); + test_zeta(number > >(), "number > >"); #endif return 0; } diff --git a/test/test_acos.cpp b/test/test_acos.cpp index d0943592..c903613b 100644 --- a/test/test_acos.cpp +++ b/test/test_acos.cpp @@ -107,10 +107,10 @@ int main() test > >(); test > >(); test > >(); - test > >(); - test > >(); - test > >(); - test > >(); + test > >(); + test > >(); + test > > >(); + test > > >(); #endif return boost::report_errors(); } diff --git a/test/test_arithmetic.cpp b/test/test_arithmetic.cpp index f972d761..26e624c6 100644 --- a/test/test_arithmetic.cpp +++ b/test/test_arithmetic.cpp @@ -1654,7 +1654,8 @@ int main() #endif #ifdef TEST_CPP_DEC_FLOAT test(); - test, boost::multiprecision::et_off> >(); + test, boost::multiprecision::et_off> >(); + test >, boost::multiprecision::et_on> >(); #endif #ifdef TEST_MPFR test(); diff --git a/test/test_asin.cpp b/test/test_asin.cpp index 3c913082..3488f3d5 100644 --- a/test/test_asin.cpp +++ b/test/test_asin.cpp @@ -103,10 +103,10 @@ int main() test > >(); test > >(); test > >(); - test > >(); - test > >(); - test > >(); - test > >(); + test > >(); + test > >(); + test > > >(); + test > > >(); // Check low multiprecision digit counts. test > >(); test > >(); diff --git a/test/test_atan.cpp b/test/test_atan.cpp index cfb2de3d..9888673d 100644 --- a/test/test_atan.cpp +++ b/test/test_atan.cpp @@ -249,10 +249,10 @@ int main() test > >(); test > >(); test > >(); - test > >(); - test > >(); - test > >(); - test > >(); + test > >(); + test > >(); + test > > >(); + test > > >(); // Check low multiprecision digit counts. test > >(); test > >(); diff --git a/test/test_cos.cpp b/test/test_cos.cpp index c9c51068..55c6540b 100644 --- a/test/test_cos.cpp +++ b/test/test_cos.cpp @@ -47,6 +47,7 @@ template void test() { + std::cout << "Testing type " << typeid(T).name() << std::endl; static const boost::array data = {{ "-2.37609908807915949996042688873953402912174184373388399043229539427530802169622688886435380890546981798452174137747437590e-1", @@ -303,10 +304,10 @@ int main() test > >(); test > >(); test > >(); - test > >(); - test > >(); - test > >(); - test > >(); + test > >(); + test > >(); + test > > >(); + test > > >(); #endif return boost::report_errors(); } diff --git a/test/test_cosh.cpp b/test/test_cosh.cpp index 5e08ec0c..f98f6cbc 100644 --- a/test/test_cosh.cpp +++ b/test/test_cosh.cpp @@ -145,10 +145,10 @@ int main() test > >(); test > >(); test > >(); - test > >(); - test > >(); - test > >(); - test > >(); + test > >(); + test > >(); + test > > >(); + test > > >(); #endif return boost::report_errors(); } diff --git a/test/test_exp.cpp b/test/test_exp.cpp index f36d7c78..f9ca1cb1 100644 --- a/test/test_exp.cpp +++ b/test/test_exp.cpp @@ -47,6 +47,7 @@ template void test() { + std::cout << "Testing type " << typeid(T).name() << std::endl; static const boost::array data = {{ "1.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", @@ -185,10 +186,10 @@ int main() test > >(); test > >(); test > >(); - test > >(); - test > >(); - test > >(); - test > >(); + test > >(); + test > >(); + test > > >(); + test > > >(); // Check low multiprecision digit counts. test > >(); test > >(); diff --git a/test/test_log.cpp b/test/test_log.cpp index 5d6ea4e4..12961093 100644 --- a/test/test_log.cpp +++ b/test/test_log.cpp @@ -47,6 +47,7 @@ template void test() { + std::cout << "Testing type " << typeid(T).name() << std::endl; static const boost::array data = {{ "-2.3025850929940456840179914546843642076011014886287729760333279009675726096773524802359972050895982983419677840422862486334095254650828067566662873690987816894829072083255546808437998948262331985283935053089653777326288461633662222876982198867465436674744042432743651550489343149393914796194044002221051017141748003688084012647080685567743216228355220114804663715659121373450747856947683463616792101806", @@ -213,10 +214,10 @@ int main() test > >(); test > >(); test > >(); - test > >(); - test > >(); - test > >(); - test > >(); + test > >(); + test > >(); + test > > >(); + test > > >(); // Check low multiprecision digit counts. test > >(); test > >(); diff --git a/test/test_pow.cpp b/test/test_pow.cpp index 6f489637..f269ddd6 100644 --- a/test/test_pow.cpp +++ b/test/test_pow.cpp @@ -588,10 +588,10 @@ int main() test > >(); test > >(); test > >(); - test > >(); - test > >(); - test > >(); - test > >(); + test > >(); + test > >(); + test > > >(); + test > > >(); // Check low multiprecision digit counts. test > >(); test > >(); diff --git a/test/test_round.cpp b/test/test_round.cpp index f066a9d8..27fe149a 100644 --- a/test/test_round.cpp +++ b/test/test_round.cpp @@ -394,10 +394,10 @@ int main() test > >(); test > >(); test > >(); - test > >(); - test > >(); - test > >(); - test > >(); + test > >(); + test > >(); + test > > >(); + test > > >(); #endif #ifdef TEST_BACKEND test >(); diff --git a/test/test_sin.cpp b/test/test_sin.cpp index 1d208575..571beb4f 100644 --- a/test/test_sin.cpp +++ b/test/test_sin.cpp @@ -47,6 +47,7 @@ template void test() { + std::cout << "Testing type: " << typeid(T).name() << std::endl; static const boost::array data = {{ "-9.71360659712083391437631022096936715962104815777147739346439739644168480837178969413799829610404829247283169084501281105e-1", @@ -297,10 +298,10 @@ int main() test > >(); test > >(); test > >(); - test > >(); - test > >(); - test > >(); - test > >(); + test > >(); + test > >(); + test > > >(); + test > > >(); // Check low multiprecision digit counts. test > >(); test > >(); diff --git a/test/test_sinh.cpp b/test/test_sinh.cpp index bb47e54f..ec4f5365 100644 --- a/test/test_sinh.cpp +++ b/test/test_sinh.cpp @@ -221,10 +221,10 @@ int main() test > >(); test > >(); test > >(); - test > >(); - test > >(); - test > >(); - test > >(); + test > >(); + test > >(); + test > > >(); + test > > >(); // Check low multiprecision digit counts. test > >(); test > >(); diff --git a/test/test_sqrt.cpp b/test/test_sqrt.cpp index cd66f169..2ab95f28 100644 --- a/test/test_sqrt.cpp +++ b/test/test_sqrt.cpp @@ -191,10 +191,10 @@ int main() test > >(); test > >(); test > >(); - test > >(); - test > >(); - test > >(); - test > >(); + test > >(); + test > >(); + test > > >(); + test > > >(); // Check low multiprecision digit counts. test > >(); test > >(); diff --git a/test/test_tanh.cpp b/test/test_tanh.cpp index 2860fde9..18478a7d 100644 --- a/test/test_tanh.cpp +++ b/test/test_tanh.cpp @@ -140,10 +140,10 @@ int main() test > >(); test > >(); test > >(); - test > >(); - test > >(); - test > >(); - test > >(); + test > >(); + test > >(); + test > > >(); + test > > >(); #endif return boost::report_errors(); }