【问题标题】:Floating point arithmetic at compile-time编译时的浮点运算
【发布时间】:2010-12-11 14:21:41
【问题描述】:

使用编译时常量整数的浮点计算是在编译时还是在运行时执行的?比如什么时候计算除法运算:

template <int A, int B>
inline float fraction()
{
    return static_cast<float>(A) / B;
}

【问题讨论】:

  • AFAIK 标准没有定义这一点,它取决于编译器和优化标志。
  • 顺便说一句,不要忘记您可以检查编译器的汇编器输出。你问的是编译器特定的,而不是语言特定的东西。我敢打赌,一个好的编译器(尤其是优化过的)会在编译时计算它所能做的一切。

标签: c++ floating-point math compile-time


【解决方案1】:

对于这么简单的事情,编译器会可能在编译时完成。事实上,编译器可能会在编译时执行此操作,即使没有模板,只要在编译时知道所有值:即如果我们有inline float fraction(int A, int B),它可能会在如果我们调用fraction(1,2),则编译时间。

如果你想强制编译器在编译时做一些事情,你将不得不使用一些模板元编程技巧,我不确定你是否可以让它与浮动一起工作-点算术。但这里是该技术的一个基本示例:

// Something similarly simple that doesn't use floating-point ;)
template <int A, int B>
struct Product {
    enum { value = A * B };
};

// Later:
... Product<3, 4>::value ...

【讨论】:

    【解决方案2】:

    我相信它是实现定义的,但大多数编译器会在编译时评估常量表达式。但是,即使您没有进行以下修改:

    template <int A, int B>
    inline float fraction()
    {
        static const float f = static_cast<float>(A) / B;
        return f ;
    }
    

    如果在运行时计算表达式,至少会确保表达式只计算一次。

    【讨论】:

      【解决方案3】:

      您应该等待带有 C++0x constexpr 关键字实现的 gcc 4.6。

      【讨论】:

      • 在我们等待的时候,所有其他编译器都会忽略 C++0x,并且如果它曾经获得批准,我们如何完成工作? ;)
      【解决方案4】:

      最好的办法是查看生成的代码 - 无法保证浮点运算会在编译时执行,但在更高的优化级别上它们可能会执行,尤其是对于像这样简单的事情。

      (一些编译器可能会避免这样做,因为对于某些体系结构,浮点行为是在运行时可配置的。在编译时执行的操作的结果可能与在运行时执行的相同操作的结果可能不同。)

      【讨论】:

        【解决方案5】:

        C 或 C++ 标准均要求在编译时计算任何条带的常量表达式,但它们确实允许它。过去 20 年发布的大多数编译器都会评估算术表达式,因此如果不引发函数调用或内联代码很重要,请尽可能保持简单。

        如果这些表达式的范围仅限于单个文件,您可以随时利用预处理器和#define FRACTION(a,b) (float(a)/float(b)) 来方便。我不建议在标题中执行此操作,除非您有一个好的方案来防止污染#includes 的任何文件。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-05-15
          • 2018-08-19
          • 2011-01-23
          • 1970-01-01
          • 2012-03-04
          • 1970-01-01
          相关资源
          最近更新 更多