integer_examples.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. ///////////////////////////////////////////////////////////////
  2. // Copyright 2012 John Maddock. Distributed under the Boost
  3. // Software License, Version 1.0. (See accompanying file
  4. // LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
  5. #include <boost/multiprecision/cpp_int.hpp>
  6. #include <iostream>
  7. #include <iomanip>
  8. #include <vector>
  9. // Includes Quickbook code snippets as comments.
  10. //[FAC1
  11. /*`
  12. In this simple example, we'll write a routine to print out all of the factorials
  13. which will fit into a 128-bit integer. At the end of the routine we do some
  14. fancy iostream formatting of the results:
  15. */
  16. /*=
  17. #include <boost/multiprecision/cpp_int.hpp>
  18. #include <iostream>
  19. #include <iomanip>
  20. #include <vector>
  21. */
  22. void print_factorials()
  23. {
  24. using boost::multiprecision::cpp_int;
  25. //
  26. // Print all the factorials that will fit inside a 128-bit integer.
  27. //
  28. // Begin by building a big table of factorials, once we know just how
  29. // large the largest is, we'll be able to "pretty format" the results.
  30. //
  31. // Calculate the largest number that will fit inside 128 bits, we could
  32. // also have used numeric_limits<int128_t>::max() for this value:
  33. cpp_int limit = (cpp_int(1) << 128) - 1;
  34. //
  35. // Our table of values:
  36. std::vector<cpp_int> results;
  37. //
  38. // Initial values:
  39. unsigned i = 1;
  40. cpp_int factorial = 1;
  41. //
  42. // Cycle through the factorials till we reach the limit:
  43. while(factorial < limit)
  44. {
  45. results.push_back(factorial);
  46. ++i;
  47. factorial *= i;
  48. }
  49. //
  50. // Lets see how many digits the largest factorial was:
  51. unsigned digits = results.back().str().size();
  52. //
  53. // Now print them out, using right justification, while we're at it
  54. // we'll indicate the limit of each integer type, so begin by defining
  55. // the limits for 16, 32, 64 etc bit integers:
  56. cpp_int limits[] = {
  57. (cpp_int(1) << 16) - 1,
  58. (cpp_int(1) << 32) - 1,
  59. (cpp_int(1) << 64) - 1,
  60. (cpp_int(1) << 128) - 1,
  61. };
  62. std::string bit_counts[] = { "16", "32", "64", "128" };
  63. unsigned current_limit = 0;
  64. for(unsigned j = 0; j < results.size(); ++j)
  65. {
  66. if(limits[current_limit] < results[j])
  67. {
  68. std::string message = "Limit of " + bit_counts[current_limit] + " bit integers";
  69. std::cout << std::setfill('.') << std::setw(digits+1) << std::right << message << std::setfill(' ') << std::endl;
  70. ++current_limit;
  71. }
  72. std::cout << std::setw(digits + 1) << std::right << results[j] << std::endl;
  73. }
  74. }
  75. /*`
  76. The output from this routine is:
  77. [pre
  78. 1
  79. 2
  80. 6
  81. 24
  82. 120
  83. 720
  84. 5040
  85. 40320
  86. ................Limit of 16 bit integers
  87. 362880
  88. 3628800
  89. 39916800
  90. 479001600
  91. ................Limit of 32 bit integers
  92. 6227020800
  93. 87178291200
  94. 1307674368000
  95. 20922789888000
  96. 355687428096000
  97. 6402373705728000
  98. 121645100408832000
  99. 2432902008176640000
  100. ................Limit of 64 bit integers
  101. 51090942171709440000
  102. 1124000727777607680000
  103. 25852016738884976640000
  104. 620448401733239439360000
  105. 15511210043330985984000000
  106. 403291461126605635584000000
  107. 10888869450418352160768000000
  108. 304888344611713860501504000000
  109. 8841761993739701954543616000000
  110. 265252859812191058636308480000000
  111. 8222838654177922817725562880000000
  112. 263130836933693530167218012160000000
  113. 8683317618811886495518194401280000000
  114. 295232799039604140847618609643520000000
  115. ]
  116. */
  117. //]
  118. //[BITOPS
  119. /*`
  120. In this example we'll show how individual bits within an integer may be manipulated,
  121. we'll start with an often needed calculation of ['2[super n] - 1], which we could obviously
  122. implement like this:
  123. */
  124. using boost::multiprecision::cpp_int;
  125. cpp_int b1(unsigned n)
  126. {
  127. cpp_int r(1);
  128. return (r << n) - 1;
  129. }
  130. /*`
  131. Calling:
  132. std::cout << std::hex << std::showbase << b1(200) << std::endl;
  133. Yields as expected:
  134. [pre 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF]
  135. However, we could equally just set the n'th bit in the result, like this:
  136. */
  137. cpp_int b2(unsigned n)
  138. {
  139. cpp_int r(0);
  140. return --bit_set(r, n);
  141. }
  142. /*`
  143. Note how the `bit_set` function sets the specified bit in its argument and then returns a reference to the result -
  144. which we can then simply decrement. The result from a call to `b2` is the same as that to `b1`.
  145. We can equally test bits, so for example the n'th bit of the result returned from `b2` shouldn't be set
  146. unless we increment it first:
  147. BOOST_ASSERT(!bit_test(b1(200), 200)); // OK
  148. BOOST_ASSERT(bit_test(++b1(200), 200)); // OK
  149. And of course if we flip the n'th bit after increment, then we should get back to zero:
  150. BOOST_ASSERT(!bit_flip(++b1(200), 200)); // OK
  151. */
  152. //]
  153. int main()
  154. {
  155. print_factorials();
  156. std::cout << std::hex << std::showbase << b1(200) << std::endl;
  157. std::cout << std::hex << std::showbase << b2(200) << std::endl;
  158. BOOST_ASSERT(!bit_test(b1(200), 200)); // OK
  159. BOOST_ASSERT(bit_test(++b1(200), 200)); // OK
  160. BOOST_ASSERT(!bit_flip(++b1(200), 200)); // OK
  161. return 0;
  162. }
  163. /*
  164. Program output:
  165. 1
  166. 2
  167. 6
  168. 24
  169. 120
  170. 720
  171. 5040
  172. 40320
  173. ................Limit of 16 bit integers
  174. 362880
  175. 3628800
  176. 39916800
  177. 479001600
  178. ................Limit of 32 bit integers
  179. 6227020800
  180. 87178291200
  181. 1307674368000
  182. 20922789888000
  183. 355687428096000
  184. 6402373705728000
  185. 121645100408832000
  186. 2432902008176640000
  187. ................Limit of 64 bit integers
  188. 51090942171709440000
  189. 1124000727777607680000
  190. 25852016738884976640000
  191. 620448401733239439360000
  192. 15511210043330985984000000
  193. 403291461126605635584000000
  194. 10888869450418352160768000000
  195. 304888344611713860501504000000
  196. 8841761993739701954543616000000
  197. 265252859812191058636308480000000
  198. 8222838654177922817725562880000000
  199. 263130836933693530167218012160000000
  200. 8683317618811886495518194401280000000
  201. 295232799039604140847618609643520000000
  202. 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  203. 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  204. */