Skip to content

Commit

Permalink
Merge dfa0f33 into e91f457
Browse files Browse the repository at this point in the history
  • Loading branch information
ts826848 committed Oct 26, 2020
2 parents e91f457 + dfa0f33 commit 78ed82c
Showing 1 changed file with 24 additions and 2 deletions.
26 changes: 24 additions & 2 deletions include/units/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -1703,18 +1703,40 @@ namespace units
: std::numeric_limits<FloatingPoint>::quiet_NaN();
}

namespace detail
{
template<typename T1, typename T2>
constexpr auto pow_acc(T1 acc, T1 x, T2 y)
{
if (y == 0)
{
return acc;
}
if (y % 2 == 0)
{
return pow_acc(acc, x * x, y / 2);
}
return pow_acc(acc * x, x * x, (y - 1) / 2);
}
}

template<typename T1, typename T2,
std::enable_if_t<std::conjunction_v<std::is_arithmetic<T1>, std::is_unsigned<T2>>, int> = 0>
constexpr detail::floating_point_promotion_t<T1> pow(T1 x, T2 y)
{
return y == 0 ? 1.0 : x * pow(x, y - 1);
using promoted_t = detail::floating_point_promotion_t<T1>;
return detail::pow_acc(static_cast<promoted_t>(1.0), static_cast<promoted_t>(x), y);
}

template<typename T1, typename T2,
std::enable_if_t<std::conjunction_v<std::is_arithmetic<T1>, std::is_signed<T2>>, int> = 0>
constexpr detail::floating_point_promotion_t<T1> pow(T1 x, T2 y)
{
return y == 0 ? 1.0 : (y < 0 ? 1.0 / x * pow(x, y + 1) : x * pow(x, static_cast<unsigned long long>(y - 1)));
if (y >= 0)
{
return pow(x, static_cast<unsigned long long>(y));
}
return 1 / (x * pow(x, static_cast<unsigned long long>(-(y + 1))));
}

template<typename T, std::enable_if_t<std::is_arithmetic_v<T>, int> = 0>
Expand Down

0 comments on commit 78ed82c

Please sign in to comment.