Skip to content

Commit 41bbd82

Browse files
committed
Add constexpr Float power(Float base, Exponent exponent).
1 parent a78f904 commit 41bbd82

3 files changed

Lines changed: 39 additions & 1 deletion

File tree

include/bitcoin/system/impl/math/power.ipp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,23 @@ constexpr Value power2(Exponent exponent) NOEXCEPT
112112
possible_narrow_and_sign_cast<unsigned>(exponent));
113113
}
114114

115+
template <typename Float, typename Exponent,
116+
if_floating_point<Float>,
117+
if_unsigned_integer<Exponent>>
118+
constexpr Float power(Float base, Exponent exponent) NOEXCEPT
119+
{
120+
// 0^0 is undefined, return 0.
121+
if ((base == 0.0) && is_zero(exponent))
122+
return 0.0;
123+
124+
Float product{ 1.0 };
125+
while (exponent-- > 0u)
126+
if ((product *= base) == 0.0)
127+
break;
128+
129+
return product;
130+
}
131+
115132
} // namespace system
116133
} // namespace libbitcoin
117134

include/bitcoin/system/math/power.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ template <typename Value = size_t, typename Exponent,
5454
if_unsigned_integer<Exponent> = true>
5555
constexpr Value power2(Exponent exponent) NOEXCEPT;
5656

57+
/// Floating point constexpr optimization for integer exponent.
58+
template <typename Float, typename Exponent,
59+
if_floating_point<Float> = true,
60+
if_unsigned_integer<Exponent> = true>
61+
constexpr Float power(Float base, Exponent exponent) NOEXCEPT;
62+
5763
} // namespace system
5864
} // namespace libbitcoin
5965

test/math/power.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,25 @@ static_assert(power<3, size_t>(0u) == 1u);
6666
// uint256_t
6767
static_assert(power<2u, uint256_t>(10u) == 1024u);
6868

69-
// uintx is not constexpr.
69+
70+
// floating point
71+
static_assert(is_same_type<decltype(power(0.0f, 0u)), float>);
72+
static_assert(is_same_type<decltype(power(0.0, 0u)), double>);
73+
74+
static_assert(power(0.0f, 0u) == 0.0f);
75+
static_assert(power(0.0, 0u) == 0.0);
76+
static_assert(power(1.0, 0u) == 1.0);
77+
static_assert(power(1.0, 1u) == 1.0);
78+
static_assert(power(2.0, 1u) == 2.0);
79+
static_assert(power(2.0, 2u) == 4.0);
80+
static_assert(power(3.0, 3u) == 27.0);
81+
82+
// Actually 311.1696 but this is the floating point representation.
83+
static_assert(power(4.2, 4u) == 311.16960000000006);
7084

7185
BOOST_AUTO_TEST_SUITE(power_tests)
7286

87+
// uintx is not constexpr.
7388
BOOST_AUTO_TEST_CASE(power_uintx_tests)
7489
{
7590
BOOST_REQUIRE(true);

0 commit comments

Comments
 (0)