当前位置:  开发笔记 > 编程语言 > 正文

我可以在编译时在c中计算pow(10,x)吗?

如何解决《我可以在编译时在c中计算pow(10,x)吗?》经验,为你挑选了5个好方法。

是否有可能在编译时计算pow(10,x)?

我有一个没有浮点支持和慢整数除法的处理器.我正在尝试在编译时执行尽可能多的计算.如果我传递两个xC/pow(10,x)作为参数(x和C总是常量整数,但它们是每个调用的不同常量),我可以大大加速一个特定的函数.我想知道我是否可以通过引入一个1/pow(10,x)自动执行的宏来使这些函数调用不易出错,而不是强迫程序员计算它?

有预处理器技巧吗?我可以强制编译器优化库调用吗?



1> Bill K..:

在溢出int(甚至很长)之前,可能的值很少.为了清楚起见,把它变成一张桌子!

编辑:如果你正在使用浮点数(看起来像你),那么不可能在编译时调用pow()函数而不实际编写在make进程中运行的代码并将值输出到文件(例如头文件)然后编译.



2> bdonlan..:

GCC将以足够高的优化级别执行此操作(-O1为我做).例如:

#include 

int 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寄存器中传递浮点返回值.


尼斯.我想知道他们如何在合理的编译时检查pow是否是纯函数.也许他们有一个已知函数的列表是这样的?

3> e.tadeu..:

你可以使用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(Boost.Preprocessor库)一起使用,它只是预处理器,我检查过它;)只配置您的include目录并包含它!

4> quinmars..:

您可以将科学计数法用于浮点值,这是C语言的一部分.它看起来像这样:

e = 1.602E-19   // == 1.602 * pow(10, -19)

E(E可能是大写或小1.602e-19)之前的数字是小数部分,其中作为E指数部分之后的(带符号)数字序列.默认情况下,编号是该类型的double,但你可以将一个浮点后缀(f,F,l或者L如果你需要一个)floatlong double.

我不建议将此语义打包到宏中:

    它不适用于变量,浮点值等.

    科学记数法更具可读性.


虽然你不推荐它,但这正是我所需要的:`#define P10(X)(1eX)`,结合`#define fixedpt(值,数字)((值)*(1 << 15)/ P10(数字))`给出了我想要的结果,不依赖于优化设置.

5> Jon Gjengset..:

实际上,通过利用C预处理器,您可以使用它来计算C pow(10, x)任何实数C和积分x.请注意,正如@quinmars所说,C允许您使用科学语法来表达数值常量:

#define myexp 1.602E-19   // == 1.602 * pow(10, -19)

用于常量.考虑到这一点,有点小聪明的,我们可以构造一个预处理器宏以管理Cx与它们合并成一个幂令牌:

#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

推荐阅读
保佑欣疼你的芯疼
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有