WPILibC++ 2023.4.3-108-ge5452e3
pow_integral.hpp
Go to the documentation of this file.
1/*################################################################################
2 ##
3 ## Copyright (C) 2016-2022 Keith O'Hara
4 ##
5 ## This file is part of the GCE-Math C++ library.
6 ##
7 ## Licensed under the Apache License, Version 2.0 (the "License");
8 ## you may not use this file except in compliance with the License.
9 ## You may obtain a copy of the License at
10 ##
11 ## http://www.apache.org/licenses/LICENSE-2.0
12 ##
13 ## Unless required by applicable law or agreed to in writing, software
14 ## distributed under the License is distributed on an "AS IS" BASIS,
15 ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 ## See the License for the specific language governing permissions and
17 ## limitations under the License.
18 ##
19 ################################################################################*/
20
21/*
22 * compile-time power function
23 */
24
25#ifndef _gcem_pow_integral_HPP
26#define _gcem_pow_integral_HPP
27
28namespace internal
29{
30
31template<typename T1, typename T2>
32constexpr T1 pow_integral_compute(const T1 base, const T2 exp_term) noexcept;
33
34// integral-valued powers using method described in
35// https://en.wikipedia.org/wiki/Exponentiation_by_squaring
36
37template<typename T1, typename T2>
38constexpr
39T1
40pow_integral_compute_recur(const T1 base, const T1 val, const T2 exp_term)
41noexcept
42{
43 return( exp_term > T2(1) ? \
44 (is_odd(exp_term) ? \
45 pow_integral_compute_recur(base*base,val*base,exp_term/2) :
46 pow_integral_compute_recur(base*base,val,exp_term/2)) :
47 (exp_term == T2(1) ? val*base : val) );
48}
49
50template<typename T1, typename T2, typename std::enable_if<std::is_signed<T2>::value>::type* = nullptr>
51constexpr
52T1
53pow_integral_sgn_check(const T1 base, const T2 exp_term)
54noexcept
55{
56 return( exp_term < T2(0) ? \
57 //
58 T1(1) / pow_integral_compute(base, - exp_term) :
59 //
60 pow_integral_compute_recur(base,T1(1),exp_term) );
61}
62
63template<typename T1, typename T2, typename std::enable_if<!std::is_signed<T2>::value>::type* = nullptr>
64constexpr
65T1
66pow_integral_sgn_check(const T1 base, const T2 exp_term)
67noexcept
68{
69 return( pow_integral_compute_recur(base,T1(1),exp_term) );
70}
71
72template<typename T1, typename T2>
73constexpr
74T1
75pow_integral_compute(const T1 base, const T2 exp_term)
76noexcept
77{
78 return( exp_term == T2(3) ? \
79 base*base*base :
80 exp_term == T2(2) ? \
81 base*base :
82 exp_term == T2(1) ? \
83 base :
84 exp_term == T2(0) ? \
85 T1(1) :
86 // check for overflow
87 exp_term == GCLIM<T2>::min() ? \
88 T1(0) :
89 exp_term == GCLIM<T2>::max() ? \
90 GCLIM<T1>::infinity() :
91 // else
92 pow_integral_sgn_check(base,exp_term) );
93}
94
95template<typename T1, typename T2, typename std::enable_if<std::is_integral<T2>::value>::type* = nullptr>
96constexpr
97T1
98pow_integral_type_check(const T1 base, const T2 exp_term)
99noexcept
100{
101 return pow_integral_compute(base,exp_term);
102}
103
104template<typename T1, typename T2, typename std::enable_if<!std::is_integral<T2>::value>::type* = nullptr>
105constexpr
106T1
107pow_integral_type_check(const T1 base, const T2 exp_term)
108noexcept
109{
110 // return GCLIM<return_t<T1>>::quiet_NaN();
111 return pow_integral_compute(base,static_cast<llint_t>(exp_term));
112}
113
114//
115// main function
116
117template<typename T1, typename T2>
118constexpr
119T1
120pow_integral(const T1 base, const T2 exp_term)
121noexcept
122{
123 return internal::pow_integral_type_check(base,exp_term);
124}
125
126}
127
128#endif
type
Definition: core.h:575
constexpr common_t< T1, T2 > max(const T1 x, const T2 y) noexcept
Compile-time pairwise maximum function.
Definition: max.hpp:35
constexpr common_t< T1, T2 > min(const T1 x, const T2 y) noexcept
Compile-time pairwise minimum function.
Definition: min.hpp:35
long long int llint_t
Definition: gcem_options.hpp:71
Definition: Eigen_Colamd.h:50
constexpr T1 pow_integral_compute(const T1 base, const T2 exp_term) noexcept
Definition: pow_integral.hpp:75
constexpr T1 pow_integral_sgn_check(const T1 base, const T2 exp_term) noexcept
Definition: pow_integral.hpp:53
constexpr T1 pow_integral(const T1 base, const T2 exp_term) noexcept
Definition: pow_integral.hpp:120
constexpr T1 pow_integral_compute_recur(const T1 base, const T1 val, const T2 exp_term) noexcept
Definition: pow_integral.hpp:40
constexpr T1 pow_integral_type_check(const T1 base, const T2 exp_term) noexcept
Definition: pow_integral.hpp:98
constexpr bool is_odd(const llint_t x) noexcept
Definition: is_odd.hpp:33