如果没有 pow()、函数或递归,我怎么能在 c/c++ 中使用幂函数
how could I use the power function in c/c++ without pow(), functions, or recursion
我使用的是 C++ 编译器,但用 C 编写代码(如果有帮助的话)
有一串数字
(-1^(a-1)/2a-1)B^(2a-1)
A 和 X 是用户定义的...A 必须为正数,但 X 可以是任何值 (+,-)...
解码这个序列...我需要使用exponents/powers,但有一些限制...我不能创建另一个函数,使用递归,或pow()
(以及其他高级cmath 或 math.h).
附带的数学函数
有很多类似的问题,但是很多答案都使用了与这个问题没有直接关系的函数和递归。
这是与 pow()
完美配合的代码,我花了很多时间试图修改它以用我自己的代码替换 pow()
,但似乎没有任何效果......主要是得到错误的结果。 X 和 J 是用户输入的变量
for (int i = 1; i < j; i++)
sum += (pow(-1, i - 1)) / (5 * i - 1) * (pow(x, 5 * i - 1));
}
您可以使用 宏 来避开 无函数调用 限制,因为宏将生成内联代码,这在技术上不是函数调用
然而,在更复杂的操作的情况下,宏不能有 return 值,因此您需要为结果使用一些局部变量(在不止一个表达式的情况下),例如:
int ret;
#define my_pow_notemp(a,b) (b==0)?1:(b==1)?a:(b==2)?a*a:(b==3)?a*a*a:0
#define my_pow(a,b)\
{\
ret=1;\
if (int(b& 1)) ret*=a;\
if (int(b& 2)) ret*=a*a;\
if (int(b& 4)) ret*=a*a*a*a;\
if (int(b& 8)) ret*=a*a*a*a*a*a*a*a;\
if (int(b&16)) ret*=a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a;\
if (int(b&32)) ret*=a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a;\
}
void main()
{
int a=2,b=3,c;
c=my_pow_notemp(a,b); // c = a^b
my_pow(a,b); c = ret; // c = a^b
}
如您所见,您可以直接使用 my_pow_notemp
,但代码是硬编码的,因此最多只能使用 a^3
,如果您需要更多,则必须将其添加到代码中。 my_pow
接受最大为 a^63 的指数,它也是一个关于如何在宏中有更复杂代码的情况下 return 值的示例。如果您需要非整数或负指数,这里有一些关于如何计算幂的(正常)方法(但是如果没有 loops/recursion,将其转换为展开代码将非常困难):
如果您想摆脱递归和函数调用,您可以使用模板而不是宏,但这仅限于C++ .
template<class T> T my_pow(T a,T b)
{
if (b==0) return 1;
if (b==1) return a;
return a*my_pow(a,b-1);
}
void main()
{
int a=2,b=3,c;
c=my_pow(a,b);
}
如您所见,模板具有 return 值,因此即使使用更复杂的代码(不止一个表达式)也没有问题。
要避免循环,您可以使用LUT 表格
int my_pow[4][4]=
{
{1,0,0,0}, // 0^
{1,1,1,1}, // 1^
{1,2,4,8}, // 2^
{1,3,9,27}, // 3^
};
void main()
{
int a=2,b=3,c;
c=my_pow[a][b];
}
如果您可以访问 FPU 或高级数学汇编,您可以使用它,因为 asm 指令不是函数调用。 FPU 本身通常具有 log,exp,pow
功能。然而,这将代码限制为特定指令集!!!
这里有一些例子:
- How to: pow(real, real) in x86
所以当我考虑到你的局限性时,我认为最好的方法是:
#define my_pow(a,b) (b==0)?1:(b==1)?a:(b==2)?a*a:(b==3)?a*a*a:0
void main()
{
int a=2,b=3,c;
c=my_pow(a,b); // c = a^b
}
这将适用于 int
指数 b
最多 3(如果你想要更多,只需添加 (b==4)?a*a*a*a: ... :0
)以及 int
和 float
基数a
。如果您需要更大的指数,请使用带有局部临时变量的复杂版本以获得 returning 结果。
[Edit1] 最终的单表达式宏,通过平方 a^15
#define my_pow(a,b) (1* (int(b&1))?a:1* (int(b&2))?a*a:1* (int(b&4))?a*a*a*a:1* (int(b&8))?a*a*a*a*a*a*a*a:1)
void main()
{
int a=2,b=3,c;
c=my_pow(a,b); // c = a^b
}
如果您想要超过 a^15
,只需为每一位指数添加子项 (int(b&16))?a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a:1
依此类推。
这是一个系列。根据之前的迭代替换 pow()
。
代码不需要调用pow()
。它可以形成 pow(x, 5 * i - 1)
和 pow(-1, i - 1)
,因为两者都有一个基于迭代器 i
的 int
指数,来自先前的循环迭代。
示例:
让f(x, i) = pow(x, 5 * i - 1)
那么f(x, 1) = x*x*x*x
和 f(x, i > 1) = f(x, i-1) * x*x*x*x*x
double power_n1 = 1.0;
double power_x5 = x*x*x*x;
for (int i = 1; i < j + 1; i++)
// sum += (pow(-1, i - 1)) / (5 * i - 1) * (pow(x, 5 * i - 1));
sum += power_n1 / (5 * i - 1) * power_x5;
power_n1 = -power_n1;
power_x5 *= x*x*x*x*x;
}
我使用的是 C++ 编译器,但用 C 编写代码(如果有帮助的话)
有一串数字
(-1^(a-1)/2a-1)B^(2a-1)
A 和 X 是用户定义的...A 必须为正数,但 X 可以是任何值 (+,-)...
解码这个序列...我需要使用exponents/powers,但有一些限制...我不能创建另一个函数,使用递归,或pow()
(以及其他高级cmath 或 math.h).
有很多类似的问题,但是很多答案都使用了与这个问题没有直接关系的函数和递归。
这是与 pow()
完美配合的代码,我花了很多时间试图修改它以用我自己的代码替换 pow()
,但似乎没有任何效果......主要是得到错误的结果。 X 和 J 是用户输入的变量
for (int i = 1; i < j; i++)
sum += (pow(-1, i - 1)) / (5 * i - 1) * (pow(x, 5 * i - 1));
}
您可以使用 宏 来避开 无函数调用 限制,因为宏将生成内联代码,这在技术上不是函数调用
然而,在更复杂的操作的情况下,宏不能有 return 值,因此您需要为结果使用一些局部变量(在不止一个表达式的情况下),例如:
int ret;
#define my_pow_notemp(a,b) (b==0)?1:(b==1)?a:(b==2)?a*a:(b==3)?a*a*a:0
#define my_pow(a,b)\
{\
ret=1;\
if (int(b& 1)) ret*=a;\
if (int(b& 2)) ret*=a*a;\
if (int(b& 4)) ret*=a*a*a*a;\
if (int(b& 8)) ret*=a*a*a*a*a*a*a*a;\
if (int(b&16)) ret*=a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a;\
if (int(b&32)) ret*=a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a;\
}
void main()
{
int a=2,b=3,c;
c=my_pow_notemp(a,b); // c = a^b
my_pow(a,b); c = ret; // c = a^b
}
如您所见,您可以直接使用 my_pow_notemp
,但代码是硬编码的,因此最多只能使用 a^3
,如果您需要更多,则必须将其添加到代码中。 my_pow
接受最大为 a^63 的指数,它也是一个关于如何在宏中有更复杂代码的情况下 return 值的示例。如果您需要非整数或负指数,这里有一些关于如何计算幂的(正常)方法(但是如果没有 loops/recursion,将其转换为展开代码将非常困难):
如果您想摆脱递归和函数调用,您可以使用模板而不是宏,但这仅限于C++ .
template<class T> T my_pow(T a,T b)
{
if (b==0) return 1;
if (b==1) return a;
return a*my_pow(a,b-1);
}
void main()
{
int a=2,b=3,c;
c=my_pow(a,b);
}
如您所见,模板具有 return 值,因此即使使用更复杂的代码(不止一个表达式)也没有问题。
要避免循环,您可以使用LUT 表格
int my_pow[4][4]=
{
{1,0,0,0}, // 0^
{1,1,1,1}, // 1^
{1,2,4,8}, // 2^
{1,3,9,27}, // 3^
};
void main()
{
int a=2,b=3,c;
c=my_pow[a][b];
}
如果您可以访问 FPU 或高级数学汇编,您可以使用它,因为 asm 指令不是函数调用。 FPU 本身通常具有 log,exp,pow
功能。然而,这将代码限制为特定指令集!!!
这里有一些例子:
- How to: pow(real, real) in x86
所以当我考虑到你的局限性时,我认为最好的方法是:
#define my_pow(a,b) (b==0)?1:(b==1)?a:(b==2)?a*a:(b==3)?a*a*a:0
void main()
{
int a=2,b=3,c;
c=my_pow(a,b); // c = a^b
}
这将适用于 int
指数 b
最多 3(如果你想要更多,只需添加 (b==4)?a*a*a*a: ... :0
)以及 int
和 float
基数a
。如果您需要更大的指数,请使用带有局部临时变量的复杂版本以获得 returning 结果。
[Edit1] 最终的单表达式宏,通过平方 a^15
#define my_pow(a,b) (1* (int(b&1))?a:1* (int(b&2))?a*a:1* (int(b&4))?a*a*a*a:1* (int(b&8))?a*a*a*a*a*a*a*a:1)
void main()
{
int a=2,b=3,c;
c=my_pow(a,b); // c = a^b
}
如果您想要超过 a^15
,只需为每一位指数添加子项 (int(b&16))?a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a:1
依此类推。
这是一个系列。根据之前的迭代替换 pow()
。
代码不需要调用pow()
。它可以形成 pow(x, 5 * i - 1)
和 pow(-1, i - 1)
,因为两者都有一个基于迭代器 i
的 int
指数,来自先前的循环迭代。
示例:
让f(x, i) = pow(x, 5 * i - 1)
那么f(x, 1) = x*x*x*x
和 f(x, i > 1) = f(x, i-1) * x*x*x*x*x
double power_n1 = 1.0;
double power_x5 = x*x*x*x;
for (int i = 1; i < j + 1; i++)
// sum += (pow(-1, i - 1)) / (5 * i - 1) * (pow(x, 5 * i - 1));
sum += power_n1 / (5 * i - 1) * power_x5;
power_n1 = -power_n1;
power_x5 *= x*x*x*x*x;
}