我需要一个整数的pow版本。我有两个问题需要用pow来解决
numeric_limits::max()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;
}发布于 2017-06-15 15:28:35
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;
}对于一个更通用的方法,您可能也想考虑下流。
还有其他一些比线性算法更快的整数指数算法(例如,通过平方求幂),但我不确定是否值得考虑它们,除非您处理任意精度的算术,或者一个没有浮点单元的嵌入式系统。
发布于 2017-06-15 15:50:53
您的代码没有编译,如果可能的话,应该先检查代码编译,使用编译器,或者首先在编译器资源管理器上检查它。
另外,你忘了考虑负值。这是积分幂的一个非常重要的特征。下面的代码是普通int类型的代码。我将让您探索如何将其扩展到其他整数类型。
#include <type_traits>
#include <iostream>
#include <cmath>
#include <limits>
using namespace std;
template <typename T>
enable_if_t< is_integral<T>::value, T>
mypow(T base, unsigned int exp)
{
T result = T(1);
bool sign = (base < 0);
if (sign) base = -base;
T temp = result;
while(exp-- != 0)
{
temp *= base;
if (temp < result)
{
return (sign) ? numeric_limits<T>::min()
: numeric_limits<T>::max();
}
result = temp;
}
return (sign && (exp & 1)) ? -result : result;
}
template <typename T>
enable_if_t< !is_integral<T>::value, int>
mypow(const T& base, unsigned int exp)
{
T result = T(1);
int i_base = int(floor(base + .5));
bool sign = (i_base < 0);
if (sign) i_base = -i_base;
int temp = result;
while(exp-- != 0)
{
temp *= i_base;
if (temp < result)
{
return (sign) ? numeric_limits<int>::min() : numeric_limits<int>::max();
}
result = temp;
}
return (sign && (exp & 1)) ? -result : result;
}在现实生活中,我会做这个笔记地板的使用,即使在整体的情况下。
template<typename T>
enable_if_t< is_integral<T>::value, T>
mypow(T x, unsigned int y) { return T(floor(pow(x, y) + .5)); }
template<typename T>
enable_if_t< !is_integral<T>::value, int>
mypow(T x, unsigned int y) { return int(floor(pow(floor(x + .5), y) + .5)); }https://stackoverflow.com/questions/44571032
复制相似问题