123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- ///////////////////////////////////////////////////////////////
- // 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;
- }
- //
- // Lets 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_ASSERT(!bit_test(b1(200), 200)); // OK
- BOOST_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_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_ASSERT(!bit_test(b1(200), 200)); // OK
- BOOST_ASSERT(bit_test(++b1(200), 200)); // OK
- BOOST_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
- */
|