我有以下C程序:
#include <stdio.h>
#include <math.h>
#define LOG2(x) ((int)( log((double)(x)) / log(2) ))
int main() {
int num = 64;
int val1 = LOG2(num);
int val2 = LOG2(64);
printf("val1: %d, val2 %d\n", val1, val2);
return 0;
}
哪个输出:
val1: 5, val2: 6
为什么当我将它与变量一起使用时,这个宏会产生一个不同的(和错误的)答案,但是当我直接输入64时它会正常工作?
无论这是否真的是获取日志库2的好方法,导致此行为的原因是什么?有什么办法可以让这个宏与变量一起正常工作吗? (我的所有输入都是2的精确权力)
答案 0 :(得分:2)
从数学上讲,这是计算base-2日志的一种很好的方法,但由于log(val)和log(2)都是长的,混乱的分数,所以结果不太可能除法将最终为5.999,这将截断为5.我建议舍入,特别是如果你知道输入总是2的幂。
(但为什么你得到不同与变量的不同答案?这是一个很好的问题,我不确定答案。通常答案是,当涉及常数时,编译器是能够在编译时执行部分/全部计算,但通常编译器最终使用与运行时环境相比微妙或显着不同的浮点算法。但我不会认为编译器会解释函数像log()
一样进行编译时常量折叠。)
此外,一些C库具有log2()
功能,可以为您提供完美的答案,但我不知道该功能的标准。