在我的具体案例中,我首先开发了一个在德州仪器微控制器(TMS320F28335(中运行的程序。它是一个实时同步发电机模拟器,因此需要执行大量浮点运算。我没有为浮点常量指定任何后缀,所以它们被视为双精度(我想这是C标准所说的(,但德州仪器公司提供的编译器将这些双精度实现为32位浮点数,因此以一种有效的方式使用了微控制器的FPU(见编译器用户指南中的表6-1(。然后,我不得不将该程序移植到带有嵌入式linux的BeagleBone Black(针对实时需求进行了修补(。当然,编译器(GCC(再次将所有常量视为双精度,但在这种情况下,这并不意味着32位浮点数,而是64位浮点数。我不完全理解ARM Cortex A8的FPU是如何工作的,但据我所知(由于它是一个32位处理器(,如果将这些浮点常量视为32位浮点数,性能会有所提高。所以,所有这些都让我想到了一个问题:有没有一种方法可以制作更可移植的"最佳类型"浮点常量?在这种情况下,我可以通过在每个常量中添加"f"后缀来解决这个问题,因为这两个处理器都更有效(我想(处理浮点运算,但如果我在amd64 PC中开发一些东西,并且我想将其移植到32位微控制器,有没有办法添加一些后缀,对于32位的微控制器,可以改为"f",对于amd64电脑,可以更改为"l"?我想到了这样的东西(当然,它不起作用(:
32位微控制器的体系结构相关头文件:
#define BEST_TYPE f
.
.
.
amd64 PC的体系结构相关头文件:
#define BEST_TYPE l
.
.
.
独立于体系结构的源文件:
.
.
.
a = b * 0.1BEST_TYPE;
.
.
.
为了澄清,我所说的"最佳类型"是指微处理器的FPU支持的更精确的数字数据类型。
这个问题要求类似于C 2018 7.20.4中的宏,"用于整数常量的宏"。这些宏,如UINT64_C(value)
,扩展到适合初始化具有相应类型的对象的整数常量。
如果我们查看macOS 10.14的Xcode 11提供的<stdint.h>
,我们会看到实现只是添加一个后缀来指示类型(或者什么都不做,如果默认情况下值具有所需类型(:
#define UINT8_C(v) (v)
#define UINT16_C(v) (v)
#define UINT32_C(v) (v ## U)
#define UINT64_C(v) (v ## ULL)
我们可以将其用作浮点类型的类似宏的指导,使用以下之一:
#define MyFloatType_C(v) (v ## f)
#define MyFloatType_C(v) (v)
#define MyFloatType_C(v) (v ## l)
可以通过各种编译时方法来选择要使用的宏的定义,例如测试预处理器宏(它们要么内置在编译器中以描述目标,要么在命令行上明确传递(。