是否有可能在编译时计算pow(10,x)?
我有一个没有浮点支持和慢整数除法的处理器.我正在尝试在编译时执行尽可能多的计算.如果我传递两个x
并C/pow(10,x)
作为参数(x和C总是常量整数,但它们是每个调用的不同常量),我可以大大加速一个特定的函数.我想知道我是否可以通过引入一个1/pow(10,x)
自动执行的宏来使这些函数调用不易出错,而不是强迫程序员计算它?
有预处理器技巧吗?我可以强制编译器优化库调用吗?
在溢出int(甚至很长)之前,可能的值很少.为了清楚起见,把它变成一张桌子!
编辑:如果你正在使用浮点数(看起来像你),那么不可能在编译时调用pow()函数而不实际编写在make进程中运行的代码并将值输出到文件(例如头文件)然后编译.
GCC将以足够高的优化级别执行此操作(-O1为我做).例如:
#includeint test() { double x = pow(10, 4); return (int)x; }
在-O1 -m32编译为:
.file "test.c" .text .globl test .type test, @function test: pushl %ebp movl %esp, %ebp movl $10000, %eax popl %ebp ret .size test, .-test .ident "GCC: (Ubuntu 4.3.3-5ubuntu4) 4.3.3" .section .note.GNU-stack,"",@progbits
这也可以在没有强制转换的情况下工作 - 当然,你会在那里获得一个浮点加载指令,因为Linux ABI在FPU寄存器中传递浮点返回值.
你可以使用Boost.Preprocessor来做到这一点:
http://www.boost.org/doc/libs/1_39_0/libs/preprocessor/doc/index.html
码:
#include#define _TIMES_10(z, n, data) * 10 #define POW_10(n) (1 BOOST_PP_REPEAT(n, _TIMES_10, _)) int test[4] = {POW_10(0), POW_10(1), POW_10(2), POW_10(3)};
您可以将科学计数法用于浮点值,这是C语言的一部分.它看起来像这样:
e = 1.602E-19 // == 1.602 * pow(10, -19)
E
(E
可能是大写或小1.602e-19
)之前的数字是小数部分,其中作为E
指数部分之后的(带符号)数字序列.默认情况下,编号是该类型的double
,但你可以将一个浮点后缀(f
,F
,l
或者L
如果你需要一个)float
或long double
.
我不建议将此语义打包到宏中:
它不适用于变量,浮点值等.
科学记数法更具可读性.
实际上,通过利用C预处理器,您可以使用它来计算C pow(10, x)
任何实数C
和积分x
.请注意,正如@quinmars所说,C允许您使用科学语法来表达数值常量:
#define myexp 1.602E-19 // == 1.602 * pow(10, -19)
用于常量.考虑到这一点,有点小聪明的,我们可以构造一个预处理器宏以管理C
和x
与它们合并成一个幂令牌:
#define EXP2(a, b) a ## b
#define EXP(a, b) EXP2(a ## e,b)
#define CONSTPOW(C,x) EXP(C, x)
现在可以将其用作常量数值:
const int myint = CONSTPOW(3, 4); // == 30000
const double myfloat = CONSTPOW(M_PI, -2); // == 0.03141592653