diff --git a/config/Jamfile.v2 b/config/Jamfile.v2 index d5d2fee5..5fc023db 100644 --- a/config/Jamfile.v2 +++ b/config/Jamfile.v2 @@ -3,6 +3,13 @@ # (See accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt. +# Several tests to check configuration of multiprecision configuration. +# Note all are explicit, so much each or all be specified to actually check a specific configuration. +# Examples: +# \boost\libs\multiprecision\config>b2 toolset=clang-win-9.0.0 cxxstd=2a release address-model=64 has_float128 has_constexpr_limits has_is_constant_evaluated > MP_config_clangwin900.log +# \boost\libs\multiprecision\config>b2 -a --debug-configuration toolset=gcc-8.1.0 cxxstd=2a release address-model=64 has_float128 has_constexpr_limits has_is_constant_evaluated >MP_config_gcc810.log +# \boost\libs\multiprecision\config>b2 toolset=msvc-14.2 cxxstd=latest release address-model=64 has_float128 has_constexpr_limits has_is_constant_evaluated >MP_config_msvc142.log + import modules ; import path ; @@ -34,6 +41,7 @@ project : requirements msvc:all gcc:-Wall gcc:-Wextra + gcc:-fext-numeric-literals # enable suffix Q for float128. ; lib gmp ; @@ -74,6 +82,8 @@ exe has_eigen : has_eigen.cpp ; exe has_f2c : has_f2c.cpp f2c ; obj has_is_constant_evaluated : has_is_constant_evaluated.cpp ; obj has_constexpr_limits : has_constexpr_limits_cmd.cpp : -fconstexpr-ops-limit=268435456 ; +# gcc8.1 g++.exe: error: unrecognized command line option '-fconstexpr-ops-limit=268435456'; did you mean '-fconstexpr-loop-limit='? + explicit has_gmp ; explicit has_mpfr ; diff --git a/config/has_constexpr_limits_cmd.cpp b/config/has_constexpr_limits_cmd.cpp index 8c96958e..3532fccf 100644 --- a/config/has_constexpr_limits_cmd.cpp +++ b/config/has_constexpr_limits_cmd.cpp @@ -3,11 +3,13 @@ // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// This determines if std::numeric_limits can be constexpr for the compiler/configuration. + #ifndef __GNUC__ -#error "Compiler is not GCC" +# error "Compiler is not GCC." #endif #if __GNUC__ < 9 -#error "Older GCC versions don't support -fconstexpr-ops-limit" +# error "Older GCC versions don't support -fconstexpr-ops-limit (aka -fconstexpr-loop-limit=n) ." #endif int main() diff --git a/config/has_float128.cpp b/config/has_float128.cpp index f46dbdcc..4e7846ac 100644 --- a/config/has_float128.cpp +++ b/config/has_float128.cpp @@ -3,10 +3,12 @@ // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// This program tests if a configuration can use type __float128. + #include #ifndef BOOST_HAS_FLOAT128 -#error "This doesn't work unless Boost.Config enables __float128 support" +# error "This doesn't work unless Boost.Config enables __float128 support. Requires GCC using GNU C++compiler and option -fext-numeric-literals. For example: b2/bjam command "b2 float128_snips toolset=gcc-8.1.0 cxxstd=17 cxxstd-dialect=gnu address-model=64 release " #endif extern "C" { diff --git a/config/has_is_constant_evaluated.cpp b/config/has_is_constant_evaluated.cpp index 808c396f..9cffbfc5 100644 --- a/config/has_is_constant_evaluated.cpp +++ b/config/has_is_constant_evaluated.cpp @@ -3,8 +3,44 @@ // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// This program determines if std::is_constant_evaluated is available to switch within a function to use compile-time constexp calculations. +// See https://en.cppreference.com/w/cpp/types/is_constant_evaluated +// and https://en.cppreference.com/w/cpp/compiler_support +// Currently only GCC 9 and Clang 9 and -std=c++2a or b2 cxxstd=2a + +// https://clang.llvm.org/docs/LanguageExtensions.html#builtin-macros + +// From Clang 10 onwards, __has_builtin(__X) can be used. but also works for Clang 9 + +// boost\libs\multiprecision\config>b2 has_is_constant_evaluated toolset=clang-win-9.0.0 cxxstd=2a address-model=64 release > mp_is_const_eval_30Sep2019.log + +#include + #include -#ifdef BOOST_MP_NO_CONSTEXPR_DETECTION -#error 1 +#ifdef __has_builtin +# warning " __has_builtin is defined." + +# if __has_builtin(__builtin_is_constant_evaluated) +# warning " __has_builtin(__builtin_is_constant_evaluated), so BOOST_MP_NO_CONSTEXPR_DETECTION should NOT be defined." +# endif // __has_builtin(__builtin_is_constant_evaluated) + +#endif // __has_builtin + +#ifdef BOOST_MP_HAS_IS_CONSTANT_EVALUATED +# warning "BOOST_MP_HAS_IS_CONSTANT_EVALUATED defined." +#else +# warning "BOOST_MP_HAS_IS_CONSTANT_EVALUATED is NOT defined, so no std::is_constant_evaluated() from std library." +#endif + +#ifdef BOOST_NO_CXX14_CONSTEXPR +# warning "BOOST_NO_CXX14_CONSTEXPR is defined." +#endif + +#ifdef BOOST_NO_CXX17_CONSTEXPR +# warning "BOOST_NO_CXX17_CONSTEXPR is defined." +#endif + +#ifdef BOOST_MP_NO_CONSTEXPR_DETECTION +# error 1 "std::is_constant_evaluated is NOT available to determine if a calculation can use constexpr." #endif diff --git a/doc/html/boost_multiprecision/indexes/s01.html b/doc/html/boost_multiprecision/indexes/s01.html index 0636a0c6..4d675e66 100644 --- a/doc/html/boost_multiprecision/indexes/s01.html +++ b/doc/html/boost_multiprecision/indexes/s01.html @@ -36,7 +36,7 @@
  • @@ -540,7 +540,7 @@

    exp

  • @@ -567,7 +567,7 @@

    f

  • @@ -588,7 +588,7 @@
    I @@ -622,7 +622,10 @@
  • infinity

    - +
  • integer_modulus

    @@ -814,7 +817,10 @@
    • of

      - +
    • overlap

      @@ -1001,7 +1007,7 @@
      Z diff --git a/doc/html/boost_multiprecision/map/hist.html b/doc/html/boost_multiprecision/map/hist.html index 32bc041f..0093f3d8 100644 --- a/doc/html/boost_multiprecision/map/hist.html +++ b/doc/html/boost_multiprecision/map/hist.html @@ -520,9 +520,10 @@ updated random examples to match.
    • - Fixed a bug in cpp_int's right shift operator when shifting negative - values - semantics now gives the same values as shifting 2's compliment - integers, though not the same bit pattern. + Fixed a bug in cpp_int + right shift operator when shifting negative values - semantics now gives + the same values as shifting 2's compliment integers, though not the same + bit pattern.
    • Fixed support for GCC-4.6.4 in C++0x mode by disabling conditional noexcept @@ -791,7 +792,7 @@
      • - 2011-2012, John Maddock adds an expression template enabled front end + 2011-2012, John Maddock adds an expression template enabled front-end to Christopher's code, and adds support for other backends.
      • diff --git a/doc/html/boost_multiprecision/ref/backendconc.html b/doc/html/boost_multiprecision/ref/backendconc.html index 3e024909..9809b033 100644 --- a/doc/html/boost_multiprecision/ref/backendconc.html +++ b/doc/html/boost_multiprecision/ref/backendconc.html @@ -38,7 +38,7 @@

        Optional requirements have default implementations that are called if the - backend doesn't provide it's own. Typically the backend will implement these + backend doesn't provide its own. Typically the backend will implement these to improve performance.

        diff --git a/doc/html/boost_multiprecision/ref/cpp_bin_float_ref.html b/doc/html/boost_multiprecision/ref/cpp_bin_float_ref.html index 64ca0063..3e33d776 100644 --- a/doc/html/boost_multiprecision/ref/cpp_bin_float_ref.html +++ b/doc/html/boost_multiprecision/ref/cpp_bin_float_ref.html @@ -113,7 +113,7 @@

        Internally, an N-bit cpp_bin_float is represented as an N-bit unsigned integer along with an exponent and a - sign. The integer part is normalized so that it's most significant bit is + sign. The integer part is normalized so that its most significant bit is always 1. The decimal point is assumed to be directly after the most significant bit of the integer part. The special values zero, infinity and NaN all have the integer part set to zero, and the exponent to one of 3 special values diff --git a/doc/html/boost_multiprecision/tut.html b/doc/html/boost_multiprecision/tut.html index 7c9151c9..40da2aaa 100644 --- a/doc/html/boost_multiprecision/tut.html +++ b/doc/html/boost_multiprecision/tut.html @@ -49,6 +49,8 @@

        Area of Circle
        +
        Drop-in + Caveats
        Defining a Special Function.
        Calculating @@ -57,8 +59,8 @@ an Integral
        Polynomial Evaluation
        -
        Variable - Precision Newton Evaluation
        +
        Variable-Precision + Newton Evaluation
    Interval Number Types
    diff --git a/doc/html/boost_multiprecision/tut/complex.html b/doc/html/boost_multiprecision/tut/complex.html index 694db34d..171ff662 100644 --- a/doc/html/boost_multiprecision/tut/complex.html +++ b/doc/html/boost_multiprecision/tut/complex.html @@ -202,7 +202,7 @@

    - Not a numbe rin it's own right, and hard to use as a result. + Not a number in its own right, and hard to use as a result.

    diff --git a/doc/html/boost_multiprecision/tut/complex/mpc_complex.html b/doc/html/boost_multiprecision/tut/complex/mpc_complex.html index d2ca6dd1..9190cff7 100644 --- a/doc/html/boost_multiprecision/tut/complex/mpc_complex.html +++ b/doc/html/boost_multiprecision/tut/complex/mpc_complex.html @@ -89,7 +89,8 @@

    It's also possible to access the underlying mpc_t - via the data() member function of mpfr_float_backend. + via the data() + member function of mpfr_float_backend.

    Things you should know when using this type: diff --git a/doc/html/boost_multiprecision/tut/conversions.html b/doc/html/boost_multiprecision/tut/conversions.html index e7550090..b8c8b028 100644 --- a/doc/html/boost_multiprecision/tut/conversions.html +++ b/doc/html/boost_multiprecision/tut/conversions.html @@ -77,8 +77,10 @@

  • Conversions to floating-point numbers from rational ones are rounded - to nearest (less than 0.5ulp error) as long as the floating-point number - is binary, and the integer type used by the rational number is unbounded. + to nearest (less than 0.5 Unit + in the last place (ULP) error) as long as the floating-point + number is binary, and the integer type used by the rational number is + unbounded.
  • diff --git a/doc/html/boost_multiprecision/tut/floats.html b/doc/html/boost_multiprecision/tut/floats.html index cd23879d..f89bb867 100644 --- a/doc/html/boost_multiprecision/tut/floats.html +++ b/doc/html/boost_multiprecision/tut/floats.html @@ -36,6 +36,8 @@

    Area of Circle
    +
    Drop-in + Caveats
    Defining a Special Function.
    Calculating @@ -44,8 +46,8 @@ an Integral
    Polynomial Evaluation
    -
    Variable - Precision Newton Evaluation
    +
    Variable-Precision + Newton Evaluation

    diff --git a/doc/html/boost_multiprecision/tut/floats/cpp_bin_float.html b/doc/html/boost_multiprecision/tut/floats/cpp_bin_float.html index 75b2cd9f..3f6943c1 100644 --- a/doc/html/boost_multiprecision/tut/floats/cpp_bin_float.html +++ b/doc/html/boost_multiprecision/tut/floats/cpp_bin_float.html @@ -159,6 +159,7 @@

    #include <boost/multiprecision/cpp_bin_float.hpp>
     #include <boost/math/special_functions/gamma.hpp>
    +
     #include <iostream>
     
     int main()
    @@ -169,14 +170,17 @@
        cpp_bin_float_100 b = 2;
        std::cout << std::numeric_limits<cpp_bin_float_100>::digits << std::endl;
        std::cout << std::numeric_limits<cpp_bin_float_100>::digits10 << std::endl;
    +
        // We can use any C++ std lib function, lets print all the digits as well:
        std::cout << std::setprecision(std::numeric_limits<cpp_bin_float_100>::max_digits10)
           << log(b) << std::endl; // print log(2)
    +
        // We can also use any function from Boost.Math:
        std::cout << boost::math::tgamma(b) << std::endl;
        // These even work when the argument is an expression template:
        std::cout << boost::math::tgamma(b * b) << std::endl;
    -   // And since we have an extended exponent range we can generate some really large 
    +
    +   // And since we have an extended exponent range we can generate some really large
        // numbers here (4.0238726007709377354370243e+2564):
        std::cout << boost::math::tgamma(cpp_bin_float_100(1000)) << std::endl;
        return 0;
    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 4f7b80ce..086a425e 100644
    --- a/doc/html/boost_multiprecision/tut/floats/cpp_dec_float.html
    +++ b/doc/html/boost_multiprecision/tut/floats/cpp_dec_float.html
    @@ -75,7 +75,7 @@
               digit counts.
             

    - There is full standard library and numeric_limits + There is full standard library and std::numeric_limits support available for this type.

    diff --git a/doc/html/boost_multiprecision/tut/floats/float128.html b/doc/html/boost_multiprecision/tut/floats/float128.html index 601d1bb2..68e0ddfa 100644 --- a/doc/html/boost_multiprecision/tut/floats/float128.html +++ b/doc/html/boost_multiprecision/tut/floats/float128.html @@ -46,7 +46,7 @@ with FORTRAN's 128-bit QUAD real.

    - All the usual standard library and numeric_limits + All the usual standard library and std::numeric_limits support are available, performance should be equivalent to the underlying native types: for example the LINPACK benchmarks for GCC's float128 and boost::multiprecision::float128 both achieved 5.6 MFLOPS[3]. @@ -129,6 +129,18 @@ as the suffix 'Q' is a GNU extension. Compilation fails with the flag --std=c++11/14/17 unless you also use -fext-numeric-literals. +

  • + You will need to link to libquadmath.dll + with the link command -lquadmath and ensure that the DLL + is visible by the linker. If you are using the B2/bjam build system + then commands<linkflags>-lQUADMATH + and <linkflags>-L"path/to/lib" will be needed. +
  • +
  • + The values shown by std::numeric_limits<float128> and extremely close but + not identical to those from the equivalent precision and + range multiprecision types std::numeric_limits<cpp_bin_float_quad> and std::numeric_limits<cpp_dec_float_quad>. +
  • @@ -141,30 +153,93 @@ int main() { - using namespace boost::multiprecision; + using namespace boost::multiprecision; // Potential to cause name collisions? + // using boost::multiprecision::float128; // is safer. +
    +

    + The type float128 provides operations at 128-bit precision with Quadruple-precision + floating-point format and have full std::numeric_limits + support: +

    +
    float128 b = 2;
    +
    +

    + There are 15 bits of (biased) binary exponent and 113-bits of significand + precision +

    +
    std::cout << std::numeric_limits<float128>::digits << std::endl;
    +
    +

    + or 33 decimal places: +

    +
    std::cout << std::numeric_limits<float128>::digits10 << std::endl;
    +
    +

    + We can use any C++ std library function, so let's show all the at-most + 36 potentially significant digits, and any trailing zeros, as well: +

    +
     std::cout.setf(std::ios_base::showpoint); // Include any trailing zeros.
    +std::cout << std::setprecision(std::numeric_limits<float128>::max_digits10)
    +   << log(b) << std::endl; // Shows log(2) = 0.693147180559945309417232121458176575
    +
    +

    + We can also use any function from Boost.Math, for example, the 'true gamma' + function tgamma: +

    +
    std::cout << boost::math::tgamma(b) << std::endl;
    +
    +

    + And since we have an extended exponent range, we can generate some really + large numbers here (4.02387260077093773543702433923004111e+2564): +

    +
    std::cout << boost::math::tgamma(float128(1000)) << std::endl;
    +
    +

    + We can declare constants using GCC or Intel's native types, and literals + with the Q suffix, and these can be declared constexpr + if required: +

    +
    constexpr float128 pi = 3.14159265358979323846264338327950Q;
    +
    +

    + Values for std::numeric_limits<float128> + are: +

    +
    GCC 8.1.0
     
    -   // Operations at 128-bit precision and full numeric_limits support:
    -   float128 b = 2;
    -   // There are 113-bits of precision:
    -   std::cout << std::numeric_limits<float128>::digits << std::endl;
    -   // Or 34 decimal places:
    -   std::cout << std::numeric_limits<float128>::digits10 << std::endl;
    -   // We can use any C++ std lib function, lets print all the digits as well:
    -   std::cout << std::setprecision(std::numeric_limits<float128>::max_digits10)
    -      << log(b) << std::endl; // print log(2) = 0.693147180559945309417232121458176575
    -   // We can also use any function from Boost.Math:
    -   std::cout << boost::math::tgamma(b) << std::endl;
    -   // And since we have an extended exponent range we can generate some really large 
    -   // numbers here (4.02387260077093773543702433923004111e+2564):
    -   std::cout << boost::math::tgamma(float128(1000)) << std::endl;
    -   //
    -   // We can declare constants using GCC or Intel's native types, and the Q suffix,
    -   // these can be declared constexpr if required:
    -
    -   constexpr float128 pi = 3.1415926535897932384626433832795028841971693993751058Q;
    -
    -   return 0;
    -}
    +Type name is float128_t:
    +Type is g
    +std::is_fundamental<> = true
    +std::is_signed<> = true
    +std::is_unsigned<> = false
    +std::is_integral<> = false
    +std::is_arithmetic<> = true
    +std::is_const<> = false
    +std::is_trivial<> = true
    +std::is_standard_layout<> = true
    +std::is_pod<> = true
    +std::numeric_limits::<>is_exact = false
    +std::numeric_limits::<>is bounded = true
    +std::numeric_limits::<>is_modulo = false
    +std::numeric_limits::<>is_iec559 = true
    +std::numeric_limits::<>traps = false
    +std::numeric_limits::<>tinyness_before = false
    +std::numeric_limits::<>max() = 1.18973149535723176508575932662800702e+4932
    +std::numeric_limits::<>min() = 3.36210314311209350626267781732175260e-4932
    +std::numeric_limits::<>lowest() = -1.18973149535723176508575932662800702e+4932
    +std::numeric_limits::<>min_exponent = -16381
    +std::numeric_limits::<>max_exponent = 16384
    +std::numeric_limits::<>epsilon() = 1.92592994438723585305597794258492732e-34
    +std::numeric_limits::<>radix = 2
    +std::numeric_limits::<>digits = 113
    +std::numeric_limits::<>digits10 = 33
    +std::numeric_limits::<>max_digits10 = 36
    +std::numeric_limits::<>has denorm = true
    +std::numeric_limits::<>denorm min = 6.47517511943802511092443895822764655e-4966
    +std::denorm_loss = false
    +limits::has_signaling_NaN == false
    +std::numeric_limits::<>quiet_NaN = nan
    +std::numeric_limits::<>infinity = inf
     


    diff --git a/doc/html/boost_multiprecision/tut/floats/fp_eg.html b/doc/html/boost_multiprecision/tut/floats/fp_eg.html index fd4e4b29..f24d37d9 100644 --- a/doc/html/boost_multiprecision/tut/floats/fp_eg.html +++ b/doc/html/boost_multiprecision/tut/floats/fp_eg.html @@ -29,6 +29,8 @@
    diff --git a/doc/html/boost_multiprecision/tut/floats/fp_eg/aos.html b/doc/html/boost_multiprecision/tut/floats/fp_eg/aos.html index 23f66721..120c42ba 100644 --- a/doc/html/boost_multiprecision/tut/floats/fp_eg/aos.html +++ b/doc/html/boost_multiprecision/tut/floats/fp_eg/aos.html @@ -7,7 +7,7 @@ - +
    @@ -20,7 +20,7 @@

    -PrevUpHomeNext +PrevUpHomeNext
    @@ -114,7 +114,7 @@
    -PrevUpHomeNext +PrevUpHomeNext
    diff --git a/doc/html/boost_multiprecision/tut/floats/fp_eg/jel.html b/doc/html/boost_multiprecision/tut/floats/fp_eg/jel.html index f2fac970..2b13a9e0 100644 --- a/doc/html/boost_multiprecision/tut/floats/fp_eg/jel.html +++ b/doc/html/boost_multiprecision/tut/floats/fp_eg/jel.html @@ -6,7 +6,7 @@ - + @@ -20,7 +20,7 @@
    -PrevUpHomeNext +PrevUpHomeNext
    @@ -210,7 +210,7 @@
    -PrevUpHomeNext +PrevUpHomeNext
    diff --git a/doc/html/boost_multiprecision/tut/floats/fp_eg/poly_eg.html b/doc/html/boost_multiprecision/tut/floats/fp_eg/poly_eg.html index 905f29f3..1366fe03 100644 --- a/doc/html/boost_multiprecision/tut/floats/fp_eg/poly_eg.html +++ b/doc/html/boost_multiprecision/tut/floats/fp_eg/poly_eg.html @@ -7,7 +7,7 @@ - + diff --git a/doc/html/boost_multiprecision/tut/floats/fp_eg/variable_precision.html b/doc/html/boost_multiprecision/tut/floats/fp_eg/variable_precision.html index bcccef3d..e3d4d2fe 100644 --- a/doc/html/boost_multiprecision/tut/floats/fp_eg/variable_precision.html +++ b/doc/html/boost_multiprecision/tut/floats/fp_eg/variable_precision.html @@ -1,7 +1,7 @@ -Variable Precision Newton Evaluation +Variable-Precision Newton Evaluation @@ -24,8 +24,8 @@

    This example illustrates the use of variable-precision arithmetic with diff --git a/doc/html/boost_multiprecision/tut/floats/mpfr_float.html b/doc/html/boost_multiprecision/tut/floats/mpfr_float.html index 02f9d4fe..bf4dd5e9 100644 --- a/doc/html/boost_multiprecision/tut/floats/mpfr_float.html +++ b/doc/html/boost_multiprecision/tut/floats/mpfr_float.html @@ -3,7 +3,7 @@ mpfr_float - + @@ -76,11 +76,13 @@ types is stored within mpfr_float_backend). The latter option can result in significantly faster code, at the expense of growing the size of mpfr_float_backend. - It can only be used at fixed precision, and should only be used for lower - digit counts. Note that we can not guarantee that using allocate_stack - won't cause any calls to mpfr's allocation routines, as mpfr may call these - inside it's own code. The following table gives an idea of the performance - tradeoff's at 50 decimal digits precision[2]: + It can only be used at fixed precision, and should + only be used for lower digit counts. Note that we can not guarantee that + using allocate_stack won't + cause any calls to mpfr's + allocation routines, as mpfr + may call these inside its own code. The following table gives an idea of + the performance tradeoff's at 50 decimal digits precision[2]:

    @@ -277,7 +279,7 @@ }
    -

    +

    [2] Compiled with VC++10 and /Ox, with MPFR-3.0.0 and MPIR-2.3.0

    diff --git a/doc/html/boost_multiprecision/tut/gen_int.html b/doc/html/boost_multiprecision/tut/gen_int.html index a414deea..c9b56794 100644 --- a/doc/html/boost_multiprecision/tut/gen_int.html +++ b/doc/html/boost_multiprecision/tut/gen_int.html @@ -162,7 +162,8 @@

    The regular Miller-Rabin functions in <boost/multiprecision/miller_rabin.hpp> are defined in terms of the above generic operations, and so function equally - well for built-in or __fundamental_types and multiprecision types. + well for fundamental + (built-in) types and multiprecision types.

    diff --git a/doc/html/boost_multiprecision/tut/import_export.html b/doc/html/boost_multiprecision/tut/import_export.html index 0fbce909..2028b142 100644 --- a/doc/html/boost_multiprecision/tut/import_export.html +++ b/doc/html/boost_multiprecision/tut/import_export.html @@ -30,7 +30,7 @@

    Any integer number type that uses cpp_int_backend - as it's implementation layer can import or export its bits via two non-member + as its implementation layer can import or export its bits via two non-member functions:

    template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator,
    diff --git a/doc/html/boost_multiprecision/tut/interval.html b/doc/html/boost_multiprecision/tut/interval.html
    index e949a7a2..0cef232e 100644
    --- a/doc/html/boost_multiprecision/tut/interval.html
    +++ b/doc/html/boost_multiprecision/tut/interval.html
    @@ -6,7 +6,7 @@
     
     
     
    -
    +
     
     
     
    diff --git a/doc/html/boost_multiprecision/tut/interval/mpfi.html b/doc/html/boost_multiprecision/tut/interval/mpfi.html
    index f6b7ad2d..ad29bfe6 100644
    --- a/doc/html/boost_multiprecision/tut/interval/mpfi.html
    +++ b/doc/html/boost_multiprecision/tut/interval/mpfi.html
    @@ -58,7 +58,7 @@
               mpfi_float_500, mpfi_float_1000 provide arithmetic types
               at 50, 100, 500 and 1000 decimal digits precision respectively. The typedef mpfi_float
               provides a variable precision type whose precision can be controlled via
    -          the numbers member functions.
    +          theF numbers member functions.
             

    @@ -93,7 +93,8 @@

    It's also possible to access the underlying mpfi_t - via the data() member function of mpfi_float_backend. + via the data() + member function of mpfi_float_backend.

    Things you should know when using this type: diff --git a/doc/html/boost_multiprecision/tut/ints/cpp_int.html b/doc/html/boost_multiprecision/tut/ints/cpp_int.html index 8f9df800..0633293d 100644 --- a/doc/html/boost_multiprecision/tut/ints/cpp_int.html +++ b/doc/html/boost_multiprecision/tut/ints/cpp_int.html @@ -267,14 +267,15 @@ The type uses a sign-magnitude representation internally, so type int128_t has 128-bits of precision plus an extra sign bit. In this respect the behaviour - of these types differs from built-in 2's complement types. In might - be tempting to use a 127-bit type instead, and indeed this does work, - but behaviour is still slightly different from a 2's complement built-in - type as the min and max values are identical (apart from the sign), - where as they differ by one for a true 2's complement type. That said - it should be noted that there's no requirement for built-in types to - be 2's complement either - it's simply that this is the most common - format by far. + of these types differs from fundamental + (built-in) 2's complement types. In might be tempting to use + a 127-bit type instead, and indeed this does work, but behaviour is + still slightly different from a 2's complement fundamental + (built-in) type as the minimum and maximum values are identical + (apart from the sign), where as they differ by one for a true 2's complement + type. That said it should be noted that there's no requirement for + fundamental_types to be 2's complement either - it's simply that this + is the most common format by far.

  • Attempting to print negative values as either an Octal or Hexadecimal @@ -340,12 +341,12 @@ have some support for constexpr values and user-defined literals, see here for the full description. For example 0xfffff_cppi1024 specifies a 1024-bit integer - with the value 0xffff. This can be used to generate compile time constants + with the value 0xffff. This can be used to generate compile-time constants that are too large to fit into any built in number type.
  • The cpp_int - types support constexpr arithmetic, provided it is a fixed precision + types support constexpr arithmetic, provided it is a fixed-precision type with no allocator. It may also be a checked integer: in which case a compiler error will be generated on overflow or undefined behaviour. In addition the free functions abs, diff --git a/doc/html/boost_multiprecision/tut/limits.html b/doc/html/boost_multiprecision/tut/limits.html index 917e5e4a..1d7b5d98 100644 --- a/doc/html/boost_multiprecision/tut/limits.html +++ b/doc/html/boost_multiprecision/tut/limits.html @@ -59,7 +59,8 @@ for Binary Floating-Point Arithmetic

    - There is a useful summary at C++ + There is a useful summary of std::numeric_limits + at C++ reference.

    @@ -76,10 +77,10 @@

  • Warning

    - GMP's mpf_t does not have - a concept of overflow: operations that lead to overflow eventually run - of out of resources and terminate with stack overflow (often after several - seconds). + GMP's extendable floatin-point mpf_t + does not have a concept of overflow: operations that lead to overflow eventually + run of out of resources and terminate with stack overflow (often after + several seconds).

    diff --git a/doc/html/boost_multiprecision/tut/limits/constants.html b/doc/html/boost_multiprecision/tut/limits/constants.html index 0bb2adc3..09aff5d8 100644 --- a/doc/html/boost_multiprecision/tut/limits/constants.html +++ b/doc/html/boost_multiprecision/tut/limits/constants.html @@ -84,10 +84,16 @@

    and using tests like this is strongly recommended to improve portability.

    -

    - If the backend is switched to a type that does not support infinity then, - without checks like this, there will be trouble. -

    +
    + + + + + +
    [Warning]Warning

    + If the backend is switched to a type that does not support infinity (or + similarly NaNs) then, without checks like this, there will be trouble. +

    is_signed @@ -98,9 +104,11 @@ is signed.

    - For built-in binary types, the sign is held in a single bit, but for other - types (cpp_dec_float and cpp_bin_float) it may be a separate storage element, - usually bool. + For fundamental + (built-in) binary types, the sign is held in a single bit, but + for other types (cpp_dec_float + and cpp_bin_float) it may + be a separate storage element, usually bool.

    @@ -169,8 +177,9 @@ by the type T is finite.

    - This is true for all built-in - integer, fixed and floating-point types, and most multi-precision types. + This is true for all fundamental (built-in) + type integer, fixed and floating-point types, and most multi-precision + types.

    It is only false for a few @@ -195,7 +204,8 @@ value.

    - For most built-in integer types, std::numeric_limits<>::is_modulo + For most fundamental + (built-in) integer types, std::numeric_limits<>::is_modulo is true.

    @@ -221,7 +231,9 @@ be raised).

    - Built-in and multi-precision floating-point types are normally not modulo. + fundamental + (built-in) and multi-precision floating-point types are normally + not modulo.

    Where possible, overflow is to std::numeric_limits<>::infinity(), provided std::numeric_limits<>::has_infinity @@ -388,7 +400,8 @@

    For most purposes, you will much more likely want std::numeric_limits<>::max_digits10, the number of decimal digits that ensure that a change of one least significant - bit (ULP) produces a different decimal digits string. + bit (Unit + in the last place (ULP)) produces a different decimal digits string.

    For the most common double @@ -596,10 +609,14 @@ std::cout.precision(max_digits10<T>()); #else #if(_MSC_VER <= 1600) - // Wrong value for std::numeric_limits<float>::max_digits10. + // The MSVC 2010 version had the wrong value for std::numeric_limits<float>::max_digits10. std::cout.precision(max_digits10<T>()); #else // Use the C++11 max_digits10. std::cout.precision(std::numeric_limits<T>::max_digits10); + std::cout.precision(std::numeric_limits<T>::digits10); + std::cout.setf(std::ios_base::showpoint); // Append any trailing zeros, + // or more memorably + std::cout << std::showpoint << std::endl; // #endif #endif @@ -726,7 +743,7 @@

    Generally true for is_iec559 - floating-point built-in types, but false for integer types. + floating-point __fundamantal types, but false for integer types.

    Standard-compliant IEEE 754 floating-point implementations may detect the diff --git a/doc/html/boost_multiprecision/tut/limits/functions.html b/doc/html/boost_multiprecision/tut/limits/functions.html index f7efe8c0..cb8851ea 100644 --- a/doc/html/boost_multiprecision/tut/limits/functions.html +++ b/doc/html/boost_multiprecision/tut/limits/functions.html @@ -36,7 +36,8 @@ then returns T().

    - For built-in types there is usually a corresponding MACRO value TYPE_MAX, + For fundamental + (built-in) types there is usually a corresponding MACRO value TYPE_MAX, where TYPE is CHAR, INT, FLOAT etc.

    @@ -85,8 +86,9 @@ can be represented by the type T.

    - For built-in types, there is usually a corresponding MACRO value TYPE_MIN, - where TYPE is CHAR, INT, FLOAT etc. + For fundamental + (built-in) types, there is usually a corresponding MACRO value + TYPE_MIN, where TYPE is CHAR, INT, FLOAT etc.

    Other types, including those provided by a typedef, @@ -158,8 +160,9 @@

    Function std::numeric_limits<T>::round_error() - returns the maximum error (in units of ULP) - that can be caused by any basic arithmetic operation. + returns the maximum error (in units of Unit + in the last place (ULP)) that can be caused by any basic arithmetic + operation.

    round_style == std::round_indeterminate;
     
    @@ -276,7 +279,9 @@

    The C++ standard specifies std::numeric_limits<>::epsilon() and Boost.Multiprecision implements this (where possible) for its program-defined - types analogous to the __fundamental floating-point types like double float. + types analogous to the fundamental + (built-in) floating-point types like double + float.

    For more information than you probably want (but still need) see What @@ -395,11 +400,13 @@

    This implementation-defined-ness has hampered use of infinity (and NaNs) - but Boost.Math and Boost.Multiprecision work hard to provide a sensible - representation for all floating-point - types, not just the built-in types, which with the use of suitable facets - to define the input and output strings, makes it possible to use these - useful features portably and including Boost.Serialization. + but Boost.Math + and Boost.Multiprecision + work hard to provide a sensible representation for all + floating-point types, not just the fundamental + (built-in) types, which with the use of suitable facets to define + the input and output strings, makes it possible to use these useful features + portably and including Boost.Serialization.

    diff --git a/doc/html/boost_multiprecision/tut/lits.html b/doc/html/boost_multiprecision/tut/lits.html index 7b81e2f8..a9d093dd 100644 --- a/doc/html/boost_multiprecision/tut/lits.html +++ b/doc/html/boost_multiprecision/tut/lits.html @@ -156,9 +156,7 @@

    Examples:

    -
    //
    -// Any use of user defined literals requires that we import the literal-operators
    -// into current scope first:
    +
    // Any use of user defined literals requires that we import the literal-operators into current scope first:
     using namespace boost::multiprecision::literals;
     //
     // To keep things simple in the example, we'll make our types used visible to this scope as well:
    @@ -179,21 +177,22 @@
     // Constants can be padded out with leading zeros to generate wider types:
     constexpr uint256_t e = 0x0000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFF_cppui; // OK
     //
    -// However, specific width types are best produced with specific-width suffixes,
    +// However, specific-width types are best produced with specific-width suffixes,
     // ones supported by default are `_cpp[u]i128`, `_cpp[u]i256`, `_cpp[u]i512`, `_cpp[u]i1024`.
     //
     constexpr int128_t f = 0x1234_cppi128; // OK, always produces an int128_t as the result.
    -constexpr uint1024_t g = 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccc_cppui1024;
    +constexpr uint1024_t g = 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccc_cppui1024; // OK,
    +//  always produces an uint1024_t as the result.
     //
    -// If other specific width types are required, then there is a macro for generating the operators
    -// for these.  The macro can be used at namespace scope only:
    +// If other specific-width types are required, then there is a macro for generating the operators for these.
    +// The macro can be used at namespace scope only:
     //
     BOOST_MP_DEFINE_SIZED_CPP_INT_LITERAL(2048);
     //
     // Now we can create 2048-bit literals as well:
     constexpr auto h = 0xff_cppi2048; // h is of type number<cpp_int_backend<2048,2048,signed_magnitude,unchecked,void> >
     //
    -// Finally negative values are handled via the unary minus operator:
    +// Finally, negative values are handled via the unary minus operator:
     //
     constexpr int1024_t i = -0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_cppui1024;
     //
    @@ -207,7 +206,7 @@
           

    The front end of the library is all constexpr - from C++14 and later. Currently there are only two back end types that are + from C++14 and later. Currently there are only two backend types that are constexpr aware: float128 and cpp_int. More backends will follow at a later date. @@ -238,10 +237,17 @@ or GCC-6 or later in C++14 mode. Compilers other than GCC and without std::is_constant_evaluated() will support a very limited set of operations: expect to hit roadblocks rather easily.

    +

    + See compiler + support for std::is_constant_evaluated; +

    For example given:

    -
    template <class T>
    +
    #include <boost/math/constants/constants.hpp> // For constant pi with full precision of type T.
    +// using  boost::math::constants::pi;
    +
    +template <class T>
     inline constexpr T circumference(T radius)
     {
        return 2 * boost::math::constants::pi<T>() * radius;
    @@ -254,7 +260,7 @@
     }
     

    - We can now calculate areas and circumferences using all constexpr arithmetic: + We can now calculate areas and circumferences, using all compile-time constexpr arithmetic:

    using boost::multiprecision::float128;
     
    @@ -266,9 +272,16 @@
     std::cout << "Area = " << a << std::endl;
     

    - Note that these make use of the numeric constants from the Math library, - which also happen to be constexpr. + Note that these make use of the numeric constants from the Boost.Math + constants library, which also happen to be constexpr. + These usually have the full precision of the floating-point type, here 128-bit, + about 36 decimal digits.

    +
    + + Calculating + Hermite Polynomial coefficients at compile time +

    For a more interesting example, in constexpr_float_arithmetic_examples.cpp we define a simple class for constexpr @@ -279,8 +292,8 @@

    Given this, we can use recurrence relations to calculate the coefficients - for various orthogonal polynomials - in the example we use the Hermite polynomials, - only the constructor does any work - it uses the recurrence relations to + for various orthogonal polynomials - in the example we use the Hermite polynomials. + Only the constructor does any work - it uses the recurrence relations to calculate the coefficient array:

    template <class T, unsigned Order>
    @@ -308,7 +321,8 @@
     };
     

    - Now we just need to define H0 and H1 as termination conditions for the recurrence: + Now we just need to define H0 and H1 + as termination conditions for the recurrence:

    template <class T>
     class hermite_polynomial<T, 0>
    @@ -355,8 +369,9 @@
     };
     

    - We can now declare H9 as a constexpr object, access the coefficients, and - evaluate at an abscissa value, all using constexpr + We can now declare H9 as a constexpr + object, access the coefficients, and evaluate at an abscissa value, all at + compile-time using constexpr arithmetic:

    constexpr hermite_polynomial<float128, 9> h9;
    @@ -375,20 +390,26 @@
     static_assert(h9[9] == 512);
     //
     // Define an abscissa value to evaluate at:
    -//
     constexpr float128 abscissa(0.5);
     //
    -// Evaluate H_9(0.5) using all constexpr arithmetic:
    -//
    +// Evaluate H_9(0.5) using all constexpr arithmetic, and check that it has the expected result:
     static_assert(h9(abscissa) == 6481);
     

    - Also since the coefficients to the Hermite polynomials are integers, we can - also generate the Hermite coefficients using (fixed precision) cpp_int's: - see constexpr_test_cpp_int_6.cpp. + See constexpr_float_arithmetic_examples.cpp + for working code.

    - We can also generate factorials (and validate the result) like so: + Also since the coefficients to the Hermite polynomials are integers, we can + also generate the Hermite coefficients using (fixed precision) cpp_ints: see constexpr_test_cpp_int_6.cpp. +

    +
    + + constexpr Factorials +
    +

    + We can also generate integer factorials in constexpr_test_cpp_int_5.cpp + like so:

    template <class T>
     constexpr T factorial(const T& a)
    @@ -396,12 +417,30 @@
        return a ? a * factorial(a - 1) : 1;
     }
     
    -
    constexpr uint1024_t f1 = factorial(uint1024_t(31));
    -static_assert(f1 == 0x1956ad0aae33a4560c5cd2c000000_cppi);
    +

    + and validate the result: +

    +
    constexpr uint1024_t f1 = factorial(uint1024_t(31)); // Factorial 31!
    +static_assert(f1 == 0x1956ad0aae33a4560c5cd2c000000_cppi); // Expected result as an Boost.Multiprecision integer literal. 
     
    +
    + + Random + constexpr values +

    Another example in constexpr_test_cpp_int_7.cpp generates a fresh multiprecision random number each time the file is compiled. + It includes an C++ template implementation of the KISS + random number algorithm by George Marsaglia for cpp_int + integers. +

    +
    constexpr uint1024_t rand = nth_random_value<uint1024_t>(1000);
    +std::cout << std::hex << rand << std::endl;
    +
    +

    + See also the random number + generation section.

    diff --git a/doc/html/boost_multiprecision/tut/mixed.html b/doc/html/boost_multiprecision/tut/mixed.html index 2f7faf1d..7f5b5883 100644 --- a/doc/html/boost_multiprecision/tut/mixed.html +++ b/doc/html/boost_multiprecision/tut/mixed.html @@ -149,10 +149,10 @@ With Optimized Mixed Precision Arithmetic

    - The following backends have at least some direct support for mixed precision + The following backends have at least some direct support for mixed-precision arithmetic, and therefore avoid creating unnecessary temporaries when using the interfaces above. Therefore when using these types it's more efficient - to use mixed precision arithmetic, than it is to explicitly cast the operands + to use mixed-precision arithmetic, than it is to explicitly cast the operands to the result type:

    diff --git a/example/Jamfile.v2 b/example/Jamfile.v2 index 0e09c848..b3d3bc08 100644 --- a/example/Jamfile.v2 +++ b/example/Jamfile.v2 @@ -1,4 +1,4 @@ -# \libs\math\example\jamfile.v2 +# \libs\multiprecision\example\jamfile.v2 # Runs multiprecision examples. # Copyright 2014 John Maddock # Copyright Paul A. Bristow 2014. @@ -7,7 +7,7 @@ # Distributed under the Boost Software License, Version 1.0. # (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -# bring in the rules for testing +# Bring in the rules for testing. import testing ; import modules ; import path ; @@ -60,7 +60,19 @@ project msvc:/wd4701 msvc:/wd4127 msvc:/wd4305 - ; + clang-win:static # Clang-win does not generate .dlls. + clang:static # Clang-linux does not generate .dlls. + clang:-Wno-unused-variable # warning: unused variable 'tolerance' [-Wunused-variable] + clang:-Wno-delete-non-abstract-non-virtual-dtor # delete called on non-final that has virtual functions but non-virtual destructor. + # This does not seem to suppress the warning in boost exception + clang:-Wno-unused-comparison # warning: equality comparison result unused. + clang:-Wno-unused-variable # unused variable 'd'. + clang:-Wno-unused-value # warning: expression result unused. + clang:-Wno-unused-const-variable + clang:-Wno-unused-local-typedef + clang:-Wno-self-assign-overloaded # explicitly assigning value of variable of type 'Real' to itself. + # clang:-v + ; # project lib gmp : : $(gmp_path) ; lib mpfr : : $(gmp_path) $(mpfr_path) $(mpfr_path)/build.vc10/lib/Win32/Debug ; diff --git a/example/constexpr_float_arithmetic_examples.cpp b/example/constexpr_float_arithmetic_examples.cpp index ef2c4579..8d7a2d9a 100644 --- a/example/constexpr_float_arithmetic_examples.cpp +++ b/example/constexpr_float_arithmetic_examples.cpp @@ -3,13 +3,18 @@ // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// Contains Quickbook snippets used by boost/libs/multiprecision/doc/multiprecision.qbk, +// section Literal Types and constexpr Support. + #include -#include + #ifdef BOOST_HAS_FLOAT128 #include #endif //[constexpr_circle +#include // For constant pi with full precision of type T. +// using boost::math::constants::pi; template inline constexpr T circumference(T radius) @@ -22,7 +27,7 @@ inline constexpr T area(T radius) { return boost::math::constants::pi() * radius * radius; } -//] +//] [/constexpr_circle] template struct const_polynomial @@ -35,7 +40,7 @@ struct const_polynomial constexpr const_polynomial(const std::initializer_list& init) : data{} { if (init.size() > Order + 1) - throw std::range_error("Too many initializers in list"); + throw std::range_error("Too many initializers in list!"); for (unsigned i = 0; i < init.size(); ++i) data[i] = init.begin()[i]; } @@ -208,7 +213,8 @@ class hermite_polynomial return m_data(val); } }; -//] +//] [/hermite_example] + //[hermite_example2 template class hermite_polynomial @@ -253,7 +259,8 @@ class hermite_polynomial return m_data(val); } }; -//] +//] [/hermite_example2] + void test_double() { @@ -315,7 +322,7 @@ void test_double() void test_float128() { #ifdef BOOST_HAS_FLOAT128 - //[constexpr_circle_usage +//[constexpr_circle_usage using boost::multiprecision::float128; @@ -326,7 +333,8 @@ void test_float128() std::cout << "Circumference = " << c << std::endl; std::cout << "Area = " << a << std::endl; - //] + //] [/constexpr_circle_usage] + constexpr hermite_polynomial h1; static_assert(h1[0] == -2); @@ -356,11 +364,9 @@ void test_float128() static_assert(h9[9] == 512); // // Define an abscissa value to evaluate at: - // constexpr float128 abscissa(0.5); // - // Evaluate H_9(0.5) using all constexpr arithmetic: - // + // Evaluate H_9(0.5) using all constexpr arithmetic, and check that it has the expected result: static_assert(h9(abscissa) == 6481); //] #endif diff --git a/example/cpp_bin_float_snips.cpp b/example/cpp_bin_float_snips.cpp index ac378e05..271a600f 100644 --- a/example/cpp_bin_float_snips.cpp +++ b/example/cpp_bin_float_snips.cpp @@ -6,6 +6,7 @@ //[cpp_bin_float_eg #include #include + #include int main() @@ -16,14 +17,17 @@ int main() cpp_bin_float_100 b = 2; std::cout << std::numeric_limits::digits << std::endl; std::cout << std::numeric_limits::digits10 << std::endl; + // We can use any C++ std lib function, lets print all the digits as well: - std::cout << std::setprecision(std::numeric_limits::max_digits10) + std::cout << std::setprecision(std::numeric_limits::max_digits10) << log(b) << std::endl; // print log(2) + // We can also use any function from Boost.Math: std::cout << boost::math::tgamma(b) << std::endl; // These even work when the argument is an expression template: std::cout << boost::math::tgamma(b * b) << std::endl; - // And since we have an extended exponent range we can generate some really large + + // And since we have an extended exponent range we can generate some really large // numbers here (4.0238726007709377354370243e+2564): std::cout << boost::math::tgamma(cpp_bin_float_100(1000)) << std::endl; return 0; diff --git a/example/float128_snips.cpp b/example/float128_snips.cpp index 5d059252..72a9da2e 100644 --- a/example/float128_snips.cpp +++ b/example/float128_snips.cpp @@ -3,6 +3,9 @@ // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt +// Demonstrations of using Boost.Multiprecision float128 type. +// Contains Quickbook markup in comments. + //[float128_eg #include #include @@ -10,33 +13,81 @@ int main() { - using namespace boost::multiprecision; + using namespace boost::multiprecision; // Potential to cause name collisions? + // using boost::multiprecision::float128; // is safer. - // Operations at 128-bit precision and full numeric_limits support: +/*`The type float128 provides operations at 128-bit precision with +[@https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format#IEEE_754_quadruple-precision_binary_floating-point_format:_binary128 Quadruple-precision floating-point format] +and have full `std::numeric_limits` support: +*/ float128 b = 2; - // There are 113-bits of precision: +//` There are 15 bits of (biased) binary exponent and 113-bits of significand precision std::cout << std::numeric_limits::digits << std::endl; - // Or 34 decimal places: +//` or 33 decimal places: std::cout << std::numeric_limits::digits10 << std::endl; - // We can use any C++ std lib function, lets print all the digits as well: - std::cout << std::setprecision(std::numeric_limits::max_digits10) - << log(b) << std::endl; // print log(2) = 0.693147180559945309417232121458176575 - // We can also use any function from Boost.Math: + //` We can use any C++ std library function, so let's show all the at-most 36 potentially significant digits, and any trailing zeros, as well: + std::cout.setf(std::ios_base::showpoint); // Include any trailing zeros. + std::cout << std::setprecision(std::numeric_limits::max_digits10) + << log(b) << std::endl; // Shows log(2) = 0.693147180559945309417232121458176575 + //` We can also use any function from Boost.Math, for example, the 'true gamma' function `tgamma`: std::cout << boost::math::tgamma(b) << std::endl; - // And since we have an extended exponent range we can generate some really large - // numbers here (4.02387260077093773543702433923004111e+2564): + /*` And since we have an extended exponent range, we can generate some really large + numbers here (4.02387260077093773543702433923004111e+2564): + */ std::cout << boost::math::tgamma(float128(1000)) << std::endl; - // - // We can declare constants using GCC or Intel's native types, and the Q suffix, - // these can be declared constexpr if required: + /*` We can declare constants using GCC or Intel's native types, and literals with the Q suffix, and these can be declared `constexpr` if required: + */ /*<-*/ #ifndef BOOST_NO_CXX11_CONSTEXPR /*->*/ - constexpr float128 pi = 3.1415926535897932384626433832795028841971693993751058Q; + constexpr float128 pi = 3.14159265358979323846264338327950Q; /*<-*/ #endif /*->*/ +//] [/float128_eg] return 0; } -//] + +/* +//[float128_numeric_limits + +GCC 8.1.0 + +Type name is float128_t: +Type is g +std::is_fundamental<> = true +std::is_signed<> = true +std::is_unsigned<> = false +std::is_integral<> = false +std::is_arithmetic<> = true +std::is_const<> = false +std::is_trivial<> = true +std::is_standard_layout<> = true +std::is_pod<> = true +std::numeric_limits::<>is_exact = false +std::numeric_limits::<>is bounded = true +std::numeric_limits::<>is_modulo = false +std::numeric_limits::<>is_iec559 = true +std::numeric_limits::<>traps = false +std::numeric_limits::<>tinyness_before = false +std::numeric_limits::<>max() = 1.18973149535723176508575932662800702e+4932 +std::numeric_limits::<>min() = 3.36210314311209350626267781732175260e-4932 +std::numeric_limits::<>lowest() = -1.18973149535723176508575932662800702e+4932 +std::numeric_limits::<>min_exponent = -16381 +std::numeric_limits::<>max_exponent = 16384 +std::numeric_limits::<>epsilon() = 1.92592994438723585305597794258492732e-34 +std::numeric_limits::<>radix = 2 +std::numeric_limits::<>digits = 113 +std::numeric_limits::<>digits10 = 33 +std::numeric_limits::<>max_digits10 = 36 +std::numeric_limits::<>has denorm = true +std::numeric_limits::<>denorm min = 6.47517511943802511092443895822764655e-4966 +std::denorm_loss = false +limits::has_signaling_NaN == false +std::numeric_limits::<>quiet_NaN = nan +std::numeric_limits::<>infinity = inf + +//] [/float128_numeric_limits] +*/ + diff --git a/example/numeric_limits_snips.cpp b/example/numeric_limits_snips.cpp index e114f0a2..c72c8dbe 100644 --- a/example/numeric_limits_snips.cpp +++ b/example/numeric_limits_snips.cpp @@ -7,17 +7,10 @@ // (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) -// Examples of numeric_limits usage as snippets for multiprecision documentation. +// Examples of std::numeric_limits usage as snippets for multiprecision documentation at multiprecision.qbk. // Includes text as Quickbook comments. -#include -#include -#include -#include -#include // numeric_limits -#include -#include #include #include @@ -33,7 +26,27 @@ #include // Boost.Test #include -static long double const log10Two = 0.30102999566398119521373889472449L; // log10(2.) +#include +#include +#include +#include +#include // numeric_limits +#include +#include + +// static long double const log10Two = 0.30102999566398119521373889472449L; // log10(2.) +// It is more portable useful to use a Boost macro +// See https://www.boost.org/doc/libs/release/libs/config/doc/html/boost_config/boost_macro_reference.html +BOOST_STATIC_CONSTEXPR long double log10Two = 0.30102999566398119521373889472449L; +// which expands to static constexpr on standard C++11 and up, but static const on earlier versions. + + /*`By default, output would only show the standard 6 decimal digits, + so set precision to show all 50 significant digits, including any trailing zeros. + This is generally useful to show the implicit precision of the type of the value. +*/ + + + template int max_digits10() @@ -66,10 +79,14 @@ BOOST_AUTO_TEST_CASE(test_numeric_limits_snips) std::cout.precision(max_digits10()); #else #if(_MSC_VER <= 1600) - // Wrong value for std::numeric_limits::max_digits10. + // The MSVC 2010 version had the wrong value for std::numeric_limits::max_digits10. std::cout.precision(max_digits10()); #else // Use the C++11 max_digits10. std::cout.precision(std::numeric_limits::max_digits10); + std::cout.precision(std::numeric_limits::digits10); + std::cout.setf(std::ios_base::showpoint); // Append any trailing zeros, + // or more memorably + std::cout << std::showpoint << std::endl; // #endif #endif diff --git a/include/boost/multiprecision/detail/number_base.hpp b/include/boost/multiprecision/detail/number_base.hpp index 4630e3dd..e5276a58 100644 --- a/include/boost/multiprecision/detail/number_base.hpp +++ b/include/boost/multiprecision/detail/number_base.hpp @@ -8,7 +8,6 @@ #include #include -#include #include #include #include @@ -49,6 +48,7 @@ #define BOOST_MP_THREAD_LOCAL #endif +// Test if the std library provides std::is_constant_evaluated() and signal by defining BOOST_MP_HAS_IS_CONSTANT_EVALUATED #ifdef __has_include # if __has_include() # include @@ -59,18 +59,23 @@ # endif #endif -#ifdef __has_builtin -#if __has_builtin(__builtin_is_constant_evaluated) && !defined(BOOST_NO_CXX14_CONSTEXPR) && !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) -#define BOOST_MP_CLANG_CD -#endif -#endif - +// BOOST_MP_HAS_IS_CONSTANT_EVALUATED(x) controls how to do std::is_constant_evaluated() or equivalents. +// Use the real std::is_constant_evaluated() if the std library provides it. #if defined(BOOST_MP_HAS_IS_CONSTANT_EVALUATED) && !defined(BOOST_NO_CXX14_CONSTEXPR) # define BOOST_MP_IS_CONST_EVALUATED(x) std::is_constant_evaluated() -#elif (defined(BOOST_GCC) && !defined(BOOST_NO_CXX14_CONSTEXPR) && (__GNUC__ >= 9)) || defined(BOOST_MP_CLANG_CD) + +// if not look for an equivalent builtin function (Clang and GCC) +// Might check first for #ifdef __has_builtin although we know that Clang >= 9 has this anyway? +#elif defined(BOOST_GCC) && !defined(BOOST_NO_CXX14_CONSTEXPR) && (__GNUC__ >= 9) # define BOOST_MP_IS_CONST_EVALUATED(x) __builtin_is_constant_evaluated() + +#elif defined(BOOST_CLANG) && !defined(BOOST_NO_CXX14_CONSTEXPR) && (__clang_major__ >= 9) +# define BOOST_MP_IS_CONST_EVALUATED(x) __builtin_is_constant_evaluated() + +// Older GCC #elif !defined(BOOST_NO_CXX14_CONSTEXPR) && defined(BOOST_GCC) && (__GNUC__ >= 6) # define BOOST_MP_IS_CONST_EVALUATED(x) __builtin_constant_p(x) + #else # define BOOST_MP_NO_CONSTEXPR_DETECTION #endif @@ -104,6 +109,14 @@ #endif namespace boost { + +namespace serialization { +template +struct nvp; +template +const nvp make_nvp(const char* name, T& t); +} // namespace serialization + namespace multiprecision { enum expression_template_option diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 9d025c67..c1208ca8 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -30,7 +30,7 @@ local tommath_path = [ modules.peek : TOMMATH_PATH ] ; # concepts # examples # -# You can run an individual suite by passing it's name to b2 on the command line. +# You can run an individual suite by passing its name to b2 on the command line. # Or you can run all except the "specfun" tests (which are very slow) by not specifying anything. # # Please make sure that any new tests are added to one of the test suites, and that the @@ -58,8 +58,11 @@ project : requirements msvc:/fp\:precise intel-win:static intel-win:static - clang-win:static - + clang-win:static # Clang-win does not generate .dlls. + clang:static # Clang-linux does not generate .dlls. + clang:-Wno-unused-variable # warning: unused variable 'tolerance' [-Wunused-variable] + clang:-v + # Assembler error "File too big" caused by lots of C++ templates, for example, math/floating_point_examples.cpp. # Some projects on some toolsets may require # gcc-mingw:\"-Wa,-mbig-obj\" @@ -331,7 +334,6 @@ test-suite functions_and_limits : [ check-target-builds ../config//has_mpfi : : no ] : test_numeric_limits_mpfi_50 ] - [ run test_numeric_limits.cpp quadmath no_eh_support : # command line : # input files diff --git a/test/constexpr_test_cpp_int_5.cpp b/test/constexpr_test_cpp_int_5.cpp index 0d71df48..684c53ab 100644 --- a/test/constexpr_test_cpp_int_5.cpp +++ b/test/constexpr_test_cpp_int_5.cpp @@ -3,6 +3,8 @@ // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// Contains Quickbook markup, using in Boost.Multiprecision.qbk section on Literals and constexpr, penultimate section on factorials. + #include "constexpr_arithmetric_test.hpp" #include "boost/multiprecision/cpp_int.hpp" #include "boost/multiprecision/integer.hpp" diff --git a/test/constexpr_test_cpp_int_7.cpp b/test/constexpr_test_cpp_int_7.cpp index 9e1676f2..b108b6d6 100644 --- a/test/constexpr_test_cpp_int_7.cpp +++ b/test/constexpr_test_cpp_int_7.cpp @@ -1,9 +1,16 @@ /////////////////////////////////////////////////////////////// // Copyright 2018 John Maddock. Distributed under the Boost // Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_ +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt). + +// Contains Quickbook snippets used by boost/libs/multiprecision/doc/multiprecision.qbk, +// used in section Literal Types and constexpr Support, last example on constexpr randoms. + +// A implementation and demonstration of the Keep It Simple Stupid random number generator algorithm https://en.wikipedia.org/wiki/KISS_(algorithm) for cpp_int integers. +// b2 --abbreviate-paths toolset=clang-9.0.0 address-model=64 cxxstd=2a release misc > multiprecision_clang_misc.log #include + #include struct kiss_rand @@ -54,8 +61,7 @@ inline constexpr void hash_combine(std::uint64_t& h, std::uint64_t k) h ^= k; h *= m; - // Completely arbitrary number, to prevent 0's - // from hashing to 0. + // Completely arbitrary number, to prevent 0's from hashing to 0. h += 0xe6546b64; } @@ -116,7 +122,9 @@ int main() { using namespace boost::multiprecision; +//[random_constexpr_cppint constexpr uint1024_t rand = nth_random_value(1000); std::cout << std::hex << rand << std::endl; +//] [/random_constexpr_cppint] return 0; }