我的公式很长,如下所示:
float a = sin(b)*cos(c)+sin(c+d)*sin(d)....
是否可以在C语言中使用s
代替sin
来缩短公式,不影响运行时间?
答案 0 :(得分:17)
将s
用于sin
至少有三个选项:
使用预处理程序宏:
#define s(x) (sin(x))
#define c(x) (cos(x))
float a = s(b)*c(c)+s(c+d)*c(d)....
#undef c
#undef s
请注意,宏定义立即用#undef
删除,以防止它们影响后续代码。另外,您应该了解预处理器宏替换的基础,注意以下事实:c
中的第一个c(c)
将被扩展,而第二个c
将不会扩展,因为类似函数的宏c(x)
仅在c
后跟(
的情况下展开。
此解决方案对运行时间没有影响。
使用内联函数:
static inline double s(double x) { return sin(x); }
static inline double c(double x) { return cos(x); }
对于一个好的编译器,这不会对运行时间造成影响,因为编译器应将对s
或c
的调用替换为对sin
或{{1 }},其结果与原始代码相同。不幸的是,在这种情况下,cos
函数将与示例代码中显示的c
对象发生冲突。您将需要更改名称之一。
使用函数指针:
c
使用一个好的编译器,这对运行时间也没有影响,尽管我怀疑比起以前的解决方案,有更多的编译器可能无法使用此解决方案优化代码。同样,您将与static double (* const s)(double) = sin;
static double (* const c)(double) = cos;
发生名称冲突。请注意,使用函数指针会创建对c
和sin
函数的直接调用,绕过C实现可能已为它们定义的任何宏。 (允许C实现使用宏以及函数来实现库函数,并且它们可以这样做以支持优化或某些功能。对于高质量的编译器,这通常是一个小问题;直接调用的优化仍然应该是不错的选择。 )
答案 1 :(得分:16)
如果我使用define,是否会影响运行时间?
define
通过在编译时进行基于文本的替换来工作。如果您#define s(x) sin(x)
,则C预处理程序将在编译器有机会查看之前将所有s(x)
重写为sin(x)
。
顺便说一句,这种低级的文本修饰正好是为什么对于更复杂的表达式使用define可能很危险。例如,一个经典的陷阱是,如果您执行类似#define times(x, y) x*y
的操作,则times(1+1,2)
将重写为1+1*2
,其结果为3
而不是预期的4
。对于更复杂的表达式,通常最好改用inlineable functions。
答案 2 :(得分:9)
不要这样做。
数学家一直在将三角函数缩写为 sin , cos , tan , sinh , cosh 和 tanh 已有很多年了。即使数学家(像我一样)喜欢使用他们最喜欢的并且经常是特质的表示法,因此将每篇论文的页数都增加了很多,但这些已经成为相当标准的了。甚至LaTeX都具有\sin
,\cos
和\tan
之类的命令。
日语在1970年代发布科学计算器时使缩写永生化(缩写可以很容易地放在按钮上),C标准库采用了缩写。
如果您偏离此规定,则您的代码将立即变得难以阅读。这对于数学代码尤其有害,因为您无法立即看到不良实现的效果。
但是如果您必须,那么简单
static double(*const s)(double) = sin;
就足够了。