我需要从pow(a,b)
得到一个整数的结果(a和b都是整数)。目前包含(int) pow( (double)a, (double)b)
的计算是错误的。也许有人可以帮助一个用整数做pow(a,b)的函数并返回一个整数?
但是这里有一个奇怪的部分:我使用Geany(和g ++ / gcc编译器)在Linux中创建了我的脚本,只编译了pow(a,b)
脚本并且工作正常。但在大学里我有Dev-C ++(和MS Windows)。在Dev-C ++中,脚本没有使用[Warning] converting to
double'
int'进行编译
我需要在Windows(和Mingw编译器)下使这个scrpit工作。
答案 0 :(得分:54)
比Zed更好的递归方法。
int myPow(int x, int p)
{
if (p == 0) return 1;
if (p == 1) return x;
int tmp = myPow(x, p/2);
if (p%2 == 0) return tmp * tmp;
else return x * tmp * tmp;
}
更好的复杂性有O(log²(p))而不是O(p)。
答案 1 :(得分:17)
或者你可以使用一点点的模板元编程:)
template<int X, int P>
struct Pow
{
enum { result = X*Pow<X,P-1>::result };
};
template<int X>
struct Pow<X,0>
{
enum { result = 1 };
};
template<int X>
struct Pow<X,1>
{
enum { result = X };
};
int main()
{
std::cout << "pow(3,7) is " << Pow<3,7>::result << std::endl;
return 0;
}
此代码具有最佳复杂性 O(1),因为评估将在编译时进行。当然,这只适用于整数值。 但是,此功能仅用于完整性(和乐趣)。
答案 2 :(得分:13)
主要是回复Zeds的简单递归......
为什么递归假定比迭代更好?特别是在C ++中。怎么了......
int myPow (int x, int p) {
int i = 1;
for (int j = 1; j <= p; j++) i *= x;
return i;
}
我并不是说你的回答是错误的,或者更糟糕的是 - 只是因为我认为它很好因为它是递归的。 IMO,特别是在C ++中,这种偏见会导致程序缓慢甚至破坏。缓慢的程序,因为你正在增长一个巨大的堆栈,导致缓存和虚拟内存分页。程序损坏,因为你得到一个堆栈溢出,迭代解决方案可以工作。
有些人会看你的答案并认为它是尾递归的,并且无论如何都会被优化为迭代。当然这不是真的 - 在每次递归调用退出之后,还有一个繁殖仍然要做,因此它不是尾递归。问题是,在C ++中,有许多更微妙的东西阻止了尾递归优化 - 即使编译器完全执行它们。例如......
void myrecurse (plan *p)
{
plan i;
i.prev = p;
// more plan setup, checks, and special case handling
myrecurse (&i);
}
在这种情况下,所有“计划”实例都必须保留在堆栈中。因此,不能丢弃堆栈帧。因此,即使在递归调用之后完成零操作,这也不能在迭代中进行优化。甚至没有像析构函数清理这样的隐藏操作,因为计划被假定为POD结构。
顺便提一下,这是基于我在实际代码中所做的事情 - 在递归期间计划的数据结构操作,但在递归到达根/叶子之前,原始节点中没有任何改变,需要所有新节点已经成功分配,获得了所有锁,并且没有任何限制可以使情况变得更糟。此时,通过该链接的计划实例列表进行迭代以提交更改 - 逻辑作为迭代更清晰,而不是分解为与递归调用的展开相关的片段。
这里的要点显然不是声称递归是自动坏的。当人们似乎假设递归比默认迭代更好时,这只会让我感到紧张。
答案 3 :(得分:3)
我假设你的家庭作业是写一个积分指数函数。首先,看看指数是什么:
http://en.wikipedia.org/wiki/Exponent
然后,在教科书中查看如何在C中乘以数字。您将要使用for
循环。
答案 4 :(得分:3)
尾递归函数不是最好的吗?类似的东西:
int myPow_helper(int x, int p, int result) {
if (p == 0) {
return result;
} else {
return myPow_helper(x, p-1, result*x);
}
}
int myPow(int x, int p) {
return myPow_helper(x, p, 1);
}
答案 5 :(得分:2)
不要将double转换为(int) pow((double)a, (double)b)
行中的int,而是尝试舍入pow的结果,然后在必要时转换为int。
当你截断时,这可能是浮点问题之一,特别是当你的结果被一个人关闭时。
答案 6 :(得分:2)
Binary powering,又名exponentiation by squaring。
int powi (int base, unsigned int exp)
{
int res = 1;
while (exp) {
if (exp & 1)
res *= base;
exp >>= 1;
base *= base;
}
return res;
}
请注意,这为powi(0,0)返回1。
答案 7 :(得分:1)
C ++标准没有int pow(int, int)
(它有double pow(double, int)
,float ...
)。微软的cmath使用的是没有ip的C math.h。某些cmath标头定义了pow
的模板版本。
$ cat main.cpp
#include <cmath>
int main() {
std::pow(2,2);
}
$ gcc main.cpp # this cmath has template pow
...snip... std::pow<int, int>(int, int)]+0x16): undefined reference to `pow'
collect2: ld returned 1 exit status
1 ;( user@host:
$ gcc main.cpp -lm
在Google Code上搜索function:ipow lang:c++。
以下是第一个链接的示例:
template <typename Type1, typename Type2>
Type1 ipow(Type1 a, Type2 ex)
// Return a**ex
{
if ( 0==ex ) return 1;
else
{
Type1 z = a;
Type1 y = 1;
while ( 1 )
{
if ( ex & 1 ) y *= z;
ex /= 2;
if ( 0==ex ) break;
z *= z;
}
return y;
}
}
请参阅calculating integer powers (squares, cubes, etc.) in C++ code。
答案 8 :(得分:0)
一个很好的递归方法,你可以炫耀:
int myPow(int x, int p) {
if (p == 0) return 1;
if (p == 1) return x;
return x * myPow(x, p-1);
}
答案 9 :(得分:0)
为何线性? 试试对数!!
long long powx( int val, int exp )
{
long long actual = val;
long long prod = 1;
int i;
for ( i = 0; i < 32; i++ )
{
if ( exp & 0x1 )
{
prod *= actual;
}
exp >>= 1;
actual *= actual;
}
return prod;
}
答案 10 :(得分:0)
这里有两种选择,当我们想要计算功率(a,n)时,我们可以编写非常短且在O(logn)时间内工作的代码,但是是递归的,因此需要为每个调用创建新的堆栈帧,需要比循环迭代更多的时间。所以简短的代码是:
int power(int a, int n){
if(n == 0) return 1;
int keep = power(a,n/2);
if(n & 1) return keep*keep*a; // (n & 1) is and operation of 1 and the
return keep*keep; // last bit of n
}
至于更快的代码,这里是使用while循环:
int power(int a, int n) {
int res = 1;
while (n) {
if (n & 1)
res *= a;
a *= a;
n >>= 1;
}
return res;
}