2009-06-10 104 views
3

1)我的C语言中有很多常量。 2)我的代码可以在浮点和定点中工作。静态初始化一个变量(在编译时)

现在,这些常量由一个函数float2fixed初始化,因此在浮点时它不做任何事情,而在定点时,它找到它们的定点表示。例如,如果工作在浮点,0.5f保留0.5f,而使用pow()子程序,如果工作在定点并且定点表示为Qx.16,则变为32768。

这很容易维护,但实际上需要花费很多时间来计算定点中的这些常量(pow是一个浮点函数)。在C++中,我会使用一些元编程,因此编译器会在编译时计算这些值,所以在运行时没有任何问题。但在C中,这是不可能的。或者是?任何人都知道这样的伎俩?任何编译器都足够聪明来做到这一点吗?

期待任何答案。

A

+0

为什么你不能只使用C++? – Zifre 2009-06-10 23:01:57

+0

C不支持预处理器宏? – CookieOfFortune 2009-06-10 23:02:58

+0

@CookieOfFortune:宏几乎不像C++模板那么强大(它们甚至不是图灵完整版),但它可能是可能的。 – Zifre 2009-06-10 23:06:53

回答

0

在普通的C中,你可以做的事情不多。您需要在某个时间点进行转换,编译器在编译时不会给您任何访问权限来调用感兴趣的用户提供的函数。从理论上讲,你可以试着哄预处理器为你做,但这是通向疯狂的快速通道(即你必须在宏中实现pow(),这非常可怕)。

我能想到的一些选项:

  1. 在磁盘上维护持久性高速缓存。至少它只会缓慢一次,虽然你仍然需要加载它,确保它没有损坏,等等。

  2. 正如另一条评论所提到的,无论如何都要使用模板元编程并用C++编译器进行编译。大多数C在C++编译器中工作得很好(可以说更好)。

嗯,我想这就是我所能想到的。祝你好运。

2

使用定点时,您可以编写一个程序来获取您的浮点值并将它们转换为固定点类型的正确,常量初始值设定项,因此您可以在生成定点值的编译中实际添加一个步骤。

这样做的一个优点是您可以使用const定义并声明常量,以便它们在运行时不会更改 - 但是对于初始化函数,当然值必须是可修改的,因为它们计算一次。


我的意思是写一个简单的程序,它可以扫描公式化线可能阅读:

const double somename = 3.14159; 

它会读取以及生成:

const fixedpoint_t somename = { ...whatever is needed... }; 

你设计的操作,使它很容易管理这两个符号 - 所以也许你的转换器总是读取文件,有时会重写它。

datafile.c: datafile.constants converter 
     converter datafile.constants > datafile.c 
+0

太麻烦了。我已经开发了6个平台,而这只是一个开始。 – vectorizor 2009-06-11 17:27:05

4

比使用(unsigned)(x*pow(2,16))做你的固定点的转换,把它写成(unsigned)(0.5f * (1 << 16))

相反这应该是可接受的作为一个编译时间常数表达,因为它只涉及内置操作符。

1

最近的GCC版本(约4.3版)增加了使用GMP和MPFR进行一些编译时优化的能力,通过评估更复杂的函数是不变的。这种方法使你的代码变得简单和便携,并且相信编译器能够完成繁重的工作。

当然,它可以做什么是有限的,很难知道它是否优化给定的实例而不去查看程序集。但它可能值得检查。 Here's a link to the description in the changelog