pow for Integral Values

Jon*_*Mee 6 c++ floating-point integer pow clamp

我需要一个pow整数版本.我有两个问题需要解决pow:

  1. 如果结果大于我的整数类型,我需要夹紧 numeric_limits::max()
  2. 我需要能够处理41.99999四舍五入到42,而不是下降到41

C++是否在这里为我提供了某种内联解决方案,或者我是不是在编写自己的函数:

template <typename T>
enable_if_t<is_integral_v<T>, T> mypow(const T base, unsigned int exp) {
    T result = exp == 0U ? base : 1;

    while(exp-- > 1U) {
        if(numeric_limits<T>::max() / result <= base) return numeric_limits<T>::max();
        result *= base;
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

eer*_*ika 3

C++ 在这里为我提供某种内联解决方案吗

pow不,标准库中没有整数。

还是我一直在编写自己的函数

是的,您可以编写自己的函数。请注意,您显示的乘法循环可能比用于std::pow实现该函数的速度慢,特别是因为循环中还有分支和除法:

template<class I>
I int_pow_no_overflow(I base, I exp)
{
    double max = std::numeric_limits<I>::max();
    double result = std::round(std::pow(base, exp));
    return result >= max
        ? max
        : result;
}
Run Code Online (Sandbox Code Playgroud)

对于更通用的方法,您可能还需要考虑下溢。

还有其他比您展示的线性算法更快的整数求幂算法(例如,参见Exponentiation by squareing),但我不确定是否值得考虑它们,除非您处理任意精度算术或嵌入式系统没有浮点单元。

  • 包装 `std::pow` 的问题在于它与 `double` 一起使用,并且(至少在某些平台上)`long long` 具有一些无法由 `double` 精确表示的值。 (4认同)