Files
multiprecision/example/integer_examples.cpp
ivanpanch 55bf069621 Fix mistakes (#729)
* Update Jamfile.v2

* Update introduction.qbk

* Update tutorial.qbk

* Update tutorial_cpp_int.qbk

* Update tutorial_gmp_int.qbk

* Update tutorial_tommath.qbk

* Update integer_examples.cpp

* Update tutorial_cpp_bin_float.qbk

* Update tutorial_cpp_dec_float.qbk

* Update tutorial_gmp_float.qbk

* Update tutorial_mpfr_float.qbk

* Update tutorial_float128.qbk

* Update tutorial_float_builtin_ctor.qbk

* Update big_seventh.cpp

* Update tutorial_float_eg.qbk

* Update floating_point_examples.cpp

* Update mpfr_precision.cpp

* Update gauss_laguerre_quadrature.cpp

* Update tutorial_interval_mpfi.qbk

* Update tutorial_cpp_complex.qbk

* Update tutorial_mpc_complex.qbk

* Update tutorial_float128_complex.qbk

* Update tutorial_complex_adaptor.qbk

* Update tutorial_rational.qbk

* Update tutorial_tommath_rational.qbk

* Update tutorial_logged_adaptor.qbk

* Update tutorial_debug_adaptor.qbk

* Update tutorial_visualizers.qbk

* Update tutorial_fwd.qbk

* Update tutorial_conversions.qbk

* Update tutorial_random.qbk

* Update random_snips.cpp

* Update tutorial_constexpr.qbk

* Update tutorial_import_export.qbk

* Update cpp_int_import_export.cpp

* Update tutorial_mixed_precision.qbk

* Update tutorial_variable_precision.qbk

* Update scoped_precision_example.cpp

* Update tutorial_numeric_limits.qbk

* Update tutorial_numeric_limits.qbk

* Update numeric_limits_snips.cpp

* Update numeric_limits_snips.cpp

* Update tutorial_numeric_limits.qbk

* Update numeric_limits_snips.cpp

* Update numeric_limits_snips.cpp

* Update tutorial_io.qbk

* Update reference_number.qbk

* Update reference_cpp_bin_float.qbk

* Update reference_cpp_double_fp_backend.qbk

* Update reference_internal_support.qbk

* Update reference_backend_requirements.qbk

* Update performance.qbk

* Update performance_overhead.qbk

* Update performance_real_world.qbk

* Update performance_integer_real_world.qbk

* Update performance_rational_real_world.qbk

* Update reference_number.qbk

* Update tutorial_numeric_limits.qbk

* Update reference_backend_requirements.qbk
2025-08-18 13:14:39 +02:00

233 lines
7.2 KiB
C++

///////////////////////////////////////////////////////////////
// Copyright 2012 John Maddock. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
#include <boost/multiprecision/cpp_int.hpp>
#include <iostream>
#include <iomanip>
#include <vector>
// Includes Quickbook code snippets as comments.
//[FAC1
/*`
In this simple example, we'll write a routine to print out all of the factorials
which will fit into a 128-bit integer. At the end of the routine we do some
fancy iostream formatting of the results:
*/
/*=
#include <boost/multiprecision/cpp_int.hpp>
#include <iostream>
#include <iomanip>
#include <vector>
*/
void print_factorials()
{
using boost::multiprecision::cpp_int;
//
// Print all the factorials that will fit inside a 128-bit integer.
//
// Begin by building a big table of factorials, once we know just how
// large the largest is, we'll be able to "pretty format" the results.
//
// Calculate the largest number that will fit inside 128 bits, we could
// also have used numeric_limits<int128_t>::max() for this value:
cpp_int limit = (cpp_int(1) << 128) - 1;
//
// Our table of values:
std::vector<cpp_int> results;
//
// Initial values:
unsigned i = 1;
cpp_int factorial = 1;
//
// Cycle through the factorials till we reach the limit:
while(factorial < limit)
{
results.push_back(factorial);
++i;
factorial *= i;
}
//
// Let's see how many digits the largest factorial was:
unsigned digits = results.back().str().size();
//
// Now print them out, using right justification, while we're at it
// we'll indicate the limit of each integer type, so begin by defining
// the limits for 16, 32, 64 etc. bit integers:
cpp_int limits[] = {
(cpp_int(1) << 16) - 1,
(cpp_int(1) << 32) - 1,
(cpp_int(1) << 64) - 1,
(cpp_int(1) << 128) - 1,
};
std::string bit_counts[] = { "16", "32", "64", "128" };
unsigned current_limit = 0;
for(unsigned j = 0; j < results.size(); ++j)
{
if(limits[current_limit] < results[j])
{
std::string message = "Limit of " + bit_counts[current_limit] + " bit integers";
std::cout << std::setfill('.') << std::setw(digits+1) << std::right << message << std::setfill(' ') << std::endl;
++current_limit;
}
std::cout << std::setw(digits + 1) << std::right << results[j] << std::endl;
}
}
/*`
The output from this routine is:
[pre
1
2
6
24
120
720
5040
40320
................Limit of 16 bit integers
362880
3628800
39916800
479001600
................Limit of 32 bit integers
6227020800
87178291200
1307674368000
20922789888000
355687428096000
6402373705728000
121645100408832000
2432902008176640000
................Limit of 64 bit integers
51090942171709440000
1124000727777607680000
25852016738884976640000
620448401733239439360000
15511210043330985984000000
403291461126605635584000000
10888869450418352160768000000
304888344611713860501504000000
8841761993739701954543616000000
265252859812191058636308480000000
8222838654177922817725562880000000
263130836933693530167218012160000000
8683317618811886495518194401280000000
295232799039604140847618609643520000000
]
*/
//]
//[BITOPS
/*`
In this example we'll show how individual bits within an integer may be manipulated,
we'll start with an often needed calculation of ['2[super n] - 1], which we could obviously
implement like this:
*/
using boost::multiprecision::cpp_int;
cpp_int b1(unsigned n)
{
cpp_int r(1);
return (r << n) - 1;
}
/*`
Calling:
std::cout << std::hex << std::showbase << b1(200) << std::endl;
Yields as expected:
[pre 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF]
However, we could equally just set the n'th bit in the result, like this:
*/
cpp_int b2(unsigned n)
{
cpp_int r(0);
return --bit_set(r, n);
}
/*`
Note how the `bit_set` function sets the specified bit in its argument and then returns a reference to the result -
which we can then simply decrement. The result from a call to `b2` is the same as that to `b1`.
We can equally test bits, so for example the n'th bit of the result returned from `b2` shouldn't be set
unless we increment it first:
BOOST_MP_ASSERT(!bit_test(b1(200), 200)); // OK
BOOST_MP_ASSERT(bit_test(++b1(200), 200)); // OK
And of course if we flip the n'th bit after increment, then we should get back to zero:
BOOST_MP_ASSERT(!bit_flip(++b1(200), 200)); // OK
*/
//]
int main()
{
print_factorials();
std::cout << std::hex << std::showbase << b1(200) << std::endl;
std::cout << std::hex << std::showbase << b2(200) << std::endl;
BOOST_MP_ASSERT(!bit_test(b1(200), 200)); // OK
BOOST_MP_ASSERT(bit_test(++b1(200), 200)); // OK
BOOST_MP_ASSERT(!bit_flip(++b1(200), 200)); // OK
return 0;
}
/*
Program output:
1
2
6
24
120
720
5040
40320
................Limit of 16 bit integers
362880
3628800
39916800
479001600
................Limit of 32 bit integers
6227020800
87178291200
1307674368000
20922789888000
355687428096000
6402373705728000
121645100408832000
2432902008176640000
................Limit of 64 bit integers
51090942171709440000
1124000727777607680000
25852016738884976640000
620448401733239439360000
15511210043330985984000000
403291461126605635584000000
10888869450418352160768000000
304888344611713860501504000000
8841761993739701954543616000000
265252859812191058636308480000000
8222838654177922817725562880000000
263130836933693530167218012160000000
8683317618811886495518194401280000000
295232799039604140847618609643520000000
0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
*/