我在 C 中有一个函数,它接受并返回一个双精度值(并在内部使用多个双精度值)。有没有一种好方法来制作该函数的第二个版本,就像它一样,除了float代替double?还DBL_EPSILON应该更新常量之类的。
我想我可以用预处理器来做这件事,但这看起来很尴尬(如果有编译错误,可能很难调试)。最佳实践推荐什么?我无法想象我是唯一一个不得不处理这件事的人。
编辑:我忘了,这是stackoverflow,所以我不能只问一个问题,我必须证明自己是正确的。在这种情况下,我有对精度非常敏感的代码;使用 doubles 而不是 floats 的成本是 200% 到 300%。到目前为止,我只需要一个双版本——当我需要它时,我想要尽可能高的精度,而不管所需的时间(在那个应用程序中它是一个很小的百分比)。但是现在我发现了一种对速度敏感且不会从额外精度中受益的用途。我对我的第一个想法感到畏缩,那就是复制整个函数并替换类型。然后我认为 SO 的专家会知道更好的方法,所以我在这里发布。
不知道“最佳实践”,但预处理器绝对是我首先想到的。它类似于 C++ 中的模板。
[编辑:Jesus Ramos 的回答提到了库中不同类型的函数的不同字母,实际上您可能会想要这样做]
您使用函数创建一个单独的源文件,在任何地方都将其双重更改为 FLOATING_POINT_TYPE (仅作为示例),然后从另一个文件包含两次源文件。(或者您选择的任何方法,您只需要能够最终处理文件两次,一次使用您定义的每种数据类型。)[还要确定附加的字符以区分函数的不同版本,请定义 FLOATING_POINT_TYPE_CHAR]
#define FLOATING_POINT_TYPE double
#define FLOATING_POINT_TYPE_CHAR d
#include "my_fp_file.c"
#undef FLOATING_POINT_TYPE_CHAR
#undef FLOATING_POINT_TYPE
#define FLOATING_POINT_TYPE float
#define FLOATING_POINT_TYPE_CHAR f
#include "my_fp_file.c"
#undef FLOATING_POINT_TYPE
#undef FLOATING_POINT_TYPE_CHAR
那么您也可以在标题中对原型使用类似的策略。
但是,所以在你的头文件中你需要类似的东西:
#define MY_FP_FUNC(funcname, typechar) \
   funcname##typechar
对于您的函数定义/原型:
FLOATING_POINT_TYPE
  MY_FP_FUNC(DoTheMath, FLOATING_POINT_TYPE_CHAR) 
  (
    FLOATING_POINT_TYPE Value1,
    FLOATING_POINT_TYPE Value2
  );
等等。
我肯定会把它留给其他人来讨论最佳实践:)
顺便说一句,对于成熟软件中这种策略的示例,您可以查看 FFTW (fftw.org),尽管它比示例更复杂一些,我认为它使用基本相同的策略。