1)我的C算法中有很多常数。 2)我的代码在浮点和定点都有效。
现在,这些常量由函数float2fixed初始化,因此在浮点中它什么都不做,而在定点中,它找到它们的定点表示。例如,如果在浮点工作,0.5f保持0.5f,而使用pow()例程,如果在定点工作,则变为32768,定点表示为Qx.16。
这很容易维护,但实际上在定点计算这些常量需要花费很多时间(pow是一个浮点函数)。在C ++中,我使用了一些元编程,因此编译器在编译时计算这些值,因此在运行时没有命中。但在C中,那是不可能的。或者是吗?有人知道这样的伎俩吗?任何编译器都足够聪明吗?
期待任何答案。
A
答案 0 :(得分:4)
不是使用(unsigned)(x*pow(2,16))
进行定点转换,而是将其写为(unsigned)(0.5f * (1 << 16))
这应该是一个可接受的编译时常量表达式,因为它只涉及内置运算符。
答案 1 :(得分:2)
使用定点时,您是否可以编写一个程序来获取浮点值并将它们转换为固定点类型的正确,常量初始值设定项,因此您可以有效地向生成固定点值的编译添加步骤。
这样做的一个优点是,您可以使用const
定义和声明常量,以便它们不会在运行时更改 - 而使用初始化函数时,值必须是可修改,因为它们只计算一次。
我的意思是写一个简单的程序,可以扫描可能读取的公式行:
const double somename = 3.14159;
它会读取并生成:
const fixedpoint_t somename = { ...whatever is needed... };
您设计的操作使两种符号都易于管理 - 因此,您的转换器可能始终读取文件,有时会重写它。
datafile.c: datafile.constants converter
converter datafile.constants > datafile.c
答案 2 :(得分:1)
GCC的最新版本(大约4.3)通过评估更复杂的常量函数,增加了使用GMP和MPFR进行编译时优化的能力。这种方法使您的代码简单易用,并且信任编译器来完成繁重的工作。
当然,它可以做什么是有限的,并且很难知道它是否在没有去看组件的情况下优化给定的实例。但值得一试。 Here's a link to the description in the changelog
答案 3 :(得分:0)
在简单的C中,你无能为力。您需要在某个时刻进行转换,并且编译器不会在编译时为您提供任何调用有趣的用户提供的函数的权限。从理论上讲,你可以试着哄骗预处理器来为你做这件事,但这是完全疯狂的快速之路(即你必须在宏中实现pow(),这是非常可怕的)。
我能想到的一些选择:
在磁盘上维护持久缓存。至少那时它只会缓慢一次,尽管你仍然需要加载它,确保它没有腐败等等。
如另一条评论所述,无论如何都要使用模板元编程,并使用C ++编译器进行编译。大多数C使用C ++编译器工作得很好(可以说更好)。