ExRandom  3.0
digit_arithmetic.hpp
Go to the documentation of this file.
1 /**
2  * @file digit_arithmetic.hpp
3  * @author Charles Karney <charles.karney@sri.com>
4  * @brief Definition of digit_arithmetic
5  *
6  * Copyright (c) Charles Karney (2014-2020) and licensed under the MIT/X11
7  * License. For more information, see http://exrandom.sourceforge.net/
8  */
9 
10 #if !defined(EXRANDOM_DIGIT_ARITHMETIC_HPP)
11 #define EXRANDOM_DIGIT_ARITHMETIC_HPP 1
12 
13 #include <cstdint> // for uint_fast32_t
14 #include <limits> // for numeric_limits<uint_t>::digits;
15 
17 
18 /**
19  * @brief The common namespace.
20  *
21  * The entire library resides in this namespace so avoid the possibility of
22  * name conflicts. For the same reason, all the headers are in the exrandom
23  * directory in the include path.
24  */
25 namespace exrandom {
26 
27  /**
28  * @relates digit_arithmetic
29  * The unsigned type used for random digits.
30  */
31  typedef std::uint_fast32_t uint_t;
32 
33  /**
34  * @relates digit_arithmetic
35  * The size of uint_t in bits.
36  */
37  const int uint_w = std::numeric_limits<uint_t>::digits;
38 
39  /**
40  * @relates digit_arithmetic
41  * A mask for uint_t.
42  */
43  const uint_t uint_m = 0xffffffffUL;
44 
45  /**
46  * @relates digit_arithmetic
47  * @param x
48  * @return the position of the most significant bit in @e x.
49  *
50  * returns 0 for @e x = 0, 32 for @e x = uint_m
51  */
52  constexpr int highest_bit_idx(unsigned x)
53  { return x == 0 ? 0 : 1 + highest_bit_idx(x >> 1); }
54 
55  /**
56  * @brief Machinery to manipulate bases.
57  *
58  * @tparam b the base as an unsigned.
59  *
60  * Base @e b = 0 is treated as 2<sup>32</sup>. @e b = 1 is disallowed.
61  */
62  template<uint_t b> class digit_arithmetic {
63  public:
64  /**
65  * The base (or 0 if the base is 2<sup>32</sup>).
66  */
67  static const uint_t base = b & uint_m;
68  /**
69  * The base less 1, in range [1, 2<sup>32</sup> &minus; 1].
70  */
71  static const uint_t basem1 = base ? base - 1UL : uint_m;
72  /**
73  * The number of bits needed to hold a digit in [0, @e basem1].
74  */
75  static const int bits = highest_bit_idx(unsigned(basem1));
76 
77  /**
78  * Is the base a power of 2?
79  */
80  static const bool power_of_two =
81  basem1 == (bits == uint_w ? ~uint_t(0) :
82  ~(~uint_t(0) << (bits < uint_w ? bits : 0)));
83  private:
84  // Require base > 1
85  static_assert(bits != 0, "base must be 2 or more");
86  };
87 
88 }
89 
90 #endif // EXRANDOM_DIGIT_ARITHMETIC_HPP
Machinery to manipulate bases.
Configuration for exrandom.
static const bool power_of_two
The common namespace.
Definition: aux_info.hpp:18
constexpr int highest_bit_idx(unsigned x)
static const uint_t basem1