我正在寻找一个使用宏计算阶乘的例子。我没有找到任何有效的东西。有什么具体的原因吗?是因为C的实现吗?我知道你不能在宏中使用递归,但是有一种方法可以使用迭代阶乘函数,为什么在C中不能使用阶乘宏呢?下面是我找到的阶乘函数迭代实现的一个例子,以供参考:
int factorial(int N) { int product = 1; for (int j = 1; j <= N; j++) product *= j; return product; }
ijxebb2r1#
我想不出在一般情况下将其作为宏的方法,但只有很少的int值可以定义阶乘函数:如果int具有32位,则其调用N > 12的未定义行为。下面是利用这一点的许多方法:
int
N > 12
static int const factorials[13] = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600 }; #define FACT(n) ((n) < 0 ? 1 : (n) > 12 ? INT_MAX : factorials[n])
或者:
#define FACT(n) ((n) <= 1 ? 1 : \ (n) == 2 ? 2 : \ (n) == 3 ? 6 : \ (n) == 4 ? 24 : \ (n) == 5 ? 120 : \ (n) == 6 ? 720 : \ (n) == 7 ? 5040 : \ (n) == 8 ? 40320 : \ (n) == 9 ? 362880 : \ (n) == 10 ? 3628800 : \ (n) == 11 ? 39916800 : \ (n) == 12 ? 479001600 : INT_MAX)
请注意,这两个函数都会多次计算n。内联函数是一种更好的方法。在现代优化编译器上,您的factorial()可以编译为常量参数的常量:一个使用Matt Godbolt's online compiler和clang 3.9 -O2的简短示例非常有启发性:factorial函数可编译成235行英特尔SIMD代码,而int test(void) { return factorial(12); }仅生成2条指令:
n
factorial()
factorial
int test(void) { return factorial(12); }
test(): # @test() mov eax, 479001600 ret
即使使用-Os优化大小,也会产生49行汇编代码,这太大了,因为-O1只有10行。
-Os
-O1
1条答案
按热度按时间ijxebb2r1#
我想不出在一般情况下将其作为宏的方法,但只有很少的
int
值可以定义阶乘函数:如果int
具有32位,则其调用N > 12
的未定义行为。下面是利用这一点的许多方法:
或者:
请注意,这两个函数都会多次计算
n
。内联函数是一种更好的方法。在现代优化编译器上,您的
factorial()
可以编译为常量参数的常量:一个使用Matt Godbolt's online compiler和clang 3.9 -O2的简短示例非常有启发性:
factorial
函数可编译成235行英特尔SIMD代码,而int test(void) { return factorial(12); }
仅生成2条指令:即使使用
-Os
优化大小,也会产生49行汇编代码,这太大了,因为-O1
只有10行。