WPILibC++ 2024.3.2
pow_integral.hpp
Go to the documentation of this file.
1/*################################################################################
2 ##
3 ## Copyright (C) 2016-2023 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 gcem
29{
30
31namespace internal
32{
33
34template<typename T1, typename T2>
35constexpr T1 pow_integral_compute(const T1 base, const T2 exp_term) noexcept;
36
37// integral-valued powers using method described in
38// https://en.wikipedia.org/wiki/Exponentiation_by_squaring
39
40template<typename T1, typename T2>
41constexpr
42T1
43pow_integral_compute_recur(const T1 base, const T1 val, const T2 exp_term)
44noexcept
45{
46 return( exp_term > T2(1) ? \
47 (is_odd(exp_term) ? \
48 pow_integral_compute_recur(base*base,val*base,exp_term/2) :
49 pow_integral_compute_recur(base*base,val,exp_term/2)) :
50 (exp_term == T2(1) ? val*base : val) );
51}
52
53template<typename T1, typename T2, typename std::enable_if<std::is_signed<T2>::value>::type* = nullptr>
54constexpr
55T1
56pow_integral_sgn_check(const T1 base, const T2 exp_term)
57noexcept
58{
59 return( exp_term < T2(0) ? \
60 //
61 T1(1) / pow_integral_compute(base, - exp_term) :
62 //
63 pow_integral_compute_recur(base,T1(1),exp_term) );
64}
65
66template<typename T1, typename T2, typename std::enable_if<!std::is_signed<T2>::value>::type* = nullptr>
67constexpr
68T1
69pow_integral_sgn_check(const T1 base, const T2 exp_term)
70noexcept
71{
72 return( pow_integral_compute_recur(base,T1(1),exp_term) );
73}
74
75template<typename T1, typename T2>
76constexpr
77T1
78pow_integral_compute(const T1 base, const T2 exp_term)
79noexcept
80{
81 return( exp_term == T2(3) ? \
82 base*base*base :
83 exp_term == T2(2) ? \
84 base*base :
85 exp_term == T2(1) ? \
86 base :
87 exp_term == T2(0) ? \
88 T1(1) :
89 // check for overflow
90 exp_term == GCLIM<T2>::min() ? \
91 T1(0) :
92 exp_term == GCLIM<T2>::max() ? \
94 // else
95 pow_integral_sgn_check(base,exp_term) );
96}
97
98template<typename T1, typename T2, typename std::enable_if<std::is_integral<T2>::value>::type* = nullptr>
99constexpr
100T1
101pow_integral_type_check(const T1 base, const T2 exp_term)
102noexcept
103{
104 return pow_integral_compute(base,exp_term);
105}
106
107template<typename T1, typename T2, typename std::enable_if<!std::is_integral<T2>::value>::type* = nullptr>
108constexpr
109T1
110pow_integral_type_check(const T1 base, const T2 exp_term)
111noexcept
112{
113 // return GCLIM<return_t<T1>>::quiet_NaN();
114 return pow_integral_compute(base,static_cast<llint_t>(exp_term));
115}
116
117//
118// main function
119
120template<typename T1, typename T2>
121constexpr
122T1
123pow_integral(const T1 base, const T2 exp_term)
124noexcept
125{
126 return internal::pow_integral_type_check(base,exp_term);
127}
128
129}
130
131}
132
133#endif
type
Definition: core.h:556
constexpr T1 pow_integral_compute_recur(const T1 base, const T1 val, const T2 exp_term) noexcept
Definition: pow_integral.hpp:43
constexpr T1 pow_integral_sgn_check(const T1 base, const T2 exp_term) noexcept
Definition: pow_integral.hpp:56
constexpr T1 pow_integral(const T1 base, const T2 exp_term) noexcept
Definition: pow_integral.hpp:123
constexpr bool is_odd(const llint_t x) noexcept
Definition: is_odd.hpp:36
constexpr T1 pow_integral_type_check(const T1 base, const T2 exp_term) noexcept
Definition: pow_integral.hpp:101
constexpr T1 pow_integral_compute(const T1 base, const T2 exp_term) noexcept
Definition: pow_integral.hpp:78
Definition: is_even.hpp:29
long long int llint_t
Definition: gcem_options.hpp:71
std::numeric_limits< T > GCLIM
Definition: gcem_options.hpp:74