编译时与运行时常量

时间:2014-05-21 21:18:43

标签: c++

我目前正在开发自己的数学库来提高我的c ++技能。我偶然发现了boost's constants header file,我问自己在运行时声明的常量上使用编译时常量有什么意义?

const float root_two = 1.414213562373095048801688724209698078e+00;
const float root_two = std::sqrt( 2.0f );

在使用固定的编译时常量但在运行带有函数的应用程序时进行计算时,是否存在错误? 如果使用运行时常量,那么错误是否会被忽略?

2 个答案:

答案 0 :(得分:2)

  1. 正如HansPassant所说,可以为你节省微瓦。但是,请注意,编译器有时会通过在编译期间评估表达式并在文字值中替换来优化它。请参阅我之前关于此问题的this answer

  2. 使用固定编译时常量时是否存在错误? 如果您正在使用任意精度数据类型。但是使用像double这样的普通数据类型效率更高,而且这些数据仅限于大约16位十进制数字。

  3. 基于(2),您的第二次初始化不会比第一次初始化更准确。实际上,如果使用任意精度计算器预先计算平方根的值,则文字甚至可能更多精确。

答案 1 :(得分:0)

像Boost这样的库必须在大量的环境中工作。使用该库的应用程序可以设置FPU可以处于从零到零模式,为非正规化(微小)结果提供0.0。

或者应用程序可以使用-fast-math标志编译,给出 不准确的结果。

此外,(a + b + c)的运行时计算取决于编译器生成的代码将如何存储中间结果。它可能选择从FPU弹出(a + b)为64位双精度,或者它可以将它作为80位留在FPU堆栈上。这取决于大量的事物,也取决于相关性的代数重写。

总而言之,如果您混合使用不同的处理器,操作系统,编译器以及库内部使用的不同应用程序,您将获得上述每种排列的不同结果。

在一些(罕见的)情境中,这不是必需的;你可能需要一个确切的恒定值。