C++ Utilities  5.10.5
Useful C++ classes and routines such as argument parser, IO and conversion utilities
math.h
Go to the documentation of this file.
1 #ifndef MATHUTILITIES_H
2 #define MATHUTILITIES_H
3 
4 #include "../global.h"
5 #include "./traits.h"
6 
7 #include <cstdint>
8 #include <limits>
9 
10 namespace CppUtilities {
11 
15 template <typename IntegralType, Traits::EnableIf<std::is_integral<IntegralType>> * = nullptr>
16 constexpr IntegralType digitsum(IntegralType number, IntegralType base = 10)
17 {
18  IntegralType res = 0;
19  while (number > 0) {
20  res += number % base;
21  number /= base;
22  }
23  return res;
24 }
25 
29 template <typename IntegralType, Traits::EnableIf<std::is_integral<IntegralType>> * = nullptr> constexpr IntegralType factorial(IntegralType number)
30 {
31  IntegralType res = 1;
32  for (IntegralType i = 1; i <= number; ++i) {
33  res *= i;
34  }
35  return res;
36 }
37 
41 template <typename IntegralType, Traits::EnableIf<std::is_integral<IntegralType>, std::is_unsigned<IntegralType>> * = nullptr>
42 constexpr IntegralType powerModulo(const IntegralType base, const IntegralType exponent, const IntegralType module)
43 {
44  IntegralType res = 1;
45  for (IntegralType mask = static_cast<IntegralType>(1) << static_cast<IntegralType>(sizeof(IntegralType) * 8 - 1); mask; mask >>= 1) {
46  if (mask & exponent) {
47  res *= base;
48  }
49  if (mask != 1) {
50  res *= res;
51  }
52  res %= module;
53  }
54  return res;
55 }
56 
60 template <typename IntegralType, Traits::EnableIf<std::is_integral<IntegralType>, std::is_unsigned<IntegralType>> * = nullptr>
61 constexpr IntegralType inverseModulo(IntegralType number, IntegralType module)
62 {
63  IntegralType y1 = 0, y2 = 1;
64  while (number != 1) {
65  IntegralType tmp = y1 - (module / number) * y2;
66  y1 = y2;
67  y2 = tmp;
68  tmp = module % number;
69  module = number;
70  number = tmp;
71  }
72  return y2;
73 }
74 
78 template <typename IntegralType, Traits::EnableIf<std::is_integral<IntegralType>, std::is_unsigned<IntegralType>> * = nullptr>
79 constexpr IntegralType orderModulo(const IntegralType number, const IntegralType module)
80 {
81  IntegralType order = 1;
82  for (; powerModulo(number, order, module) != 1 && order != module; ++order)
83  ;
84  return order != module ? order : 0;
85 }
86 
88 template <typename T> constexpr T min(T first, T second)
89 {
90  return first < second ? first : second;
91 }
92 
94 template <typename T1, typename... T2> constexpr T1 min(T1 first, T1 second, T2... remaining)
95 {
96  return first < second ? min(first, remaining...) : min(second, remaining...);
97 }
98 
100 template <typename T> constexpr T max(T first, T second)
101 {
102  return first > second ? first : second;
103 }
104 
106 template <typename T1, typename... T2> constexpr T1 max(T1 first, T1 second, T2... remaining)
107 {
108  return first > second ? max(first, remaining...) : max(second, remaining...);
109 }
110 
111 } // namespace CppUtilities
112 
113 #endif // MATHUTILITIES_H
Contains all utilities provides by the c++utilities library.
constexpr IntegralType factorial(IntegralType number)
Returns the factorial of the given number.
Definition: math.h:29
constexpr IntegralType inverseModulo(IntegralType number, IntegralType module)
Computes the inverse of number modulo module.
Definition: math.h:61
constexpr IntegralType digitsum(IntegralType number, IntegralType base=10)
Returns the digitsum of the given number using the specified base.
Definition: math.h:16
constexpr T max(T first, T second)
Returns the greatest of the given items.
Definition: math.h:100
constexpr IntegralType powerModulo(const IntegralType base, const IntegralType exponent, const IntegralType module)
Computes base power exponent modulo module.
Definition: math.h:42
constexpr T min(T first, T second)
Returns the smallest of the given items.
Definition: math.h:88
constexpr IntegralType orderModulo(const IntegralType number, const IntegralType module)
Computes the order of number modulo module.
Definition: math.h:79
constexpr int i