当前位置:  开发笔记 > 编程语言 > 正文

泰勒系列扩展为constexpr

如何解决《泰勒系列扩展为constexpr》经验,为你挑选了1个好方法。

我正在尝试sine使用泰勒系列扩展构建一个简单的函数,可以在编译时使用C++ 14进行评估constexpr.我的代码正在编译,但编译器不会生成常量.

sine 定义如下:

template  constexpr T sine(T x) {
    T result = x;

    for (int i = 1; i < P; ++i)
        result += power(-1, i) * power(x, 1 + 2 * i) / factorial(1 + 2 * i);

    return result;
}

我可以提供代码power,factorial如果需要的话.它们是微不足道的constexpr.

sine在这样的循环中调用:

template  void test(double *out) {
    for (int i = 0; i < N; ++i) {
        out[i] = sine<20, double>(i * M_PI / N);
    }
}

我期待编译器可以生成一组结果sine并将其放入,out而不需要实际计算泰勒系列.相反,生成的代码sine就像执行任何其他非constexpr函数一样执行.

我的编译器是从Xcode 7.2编译而来的-O3.



1> 101010..:

我期待编译器可以为正弦生成一组结果并将它们放入,而不需要实际计算泰勒系列.相反,生成的代码执行正弦,就像它是任何其他非constexpr函数一样.

constexpr在编译时评估函数,必须满足以下条件:

它的所有输入参数都必须是常量表达式.

其结果必须用于常量表达式.

test'for循环中的赋值不是常量表达式.因此,sine无法在编译时进行评估.

你真正想要的是使用静态初始化数组的元素sine().使用一个std::array和一些辅助机械可以这样做,如下所示:

#define r 0.01745329251

constexpr double factorial(int n) {
  double res = 1.0;

  for(int i(2); i <= n; ++i) res *= i;

  return res;
}

template
constexpr T power(T &&base, int const n) {

  if(!n) return 0.0;

  T res = base;

  for(int i(1); i < n; ++i) res *= base;

  return res;
}

template  
constexpr T sine(T &&x) {
  T res = x * r;

  for (int i(3), sgn(-1); i <= N; i += 2, sgn = -sgn) {
    res += power(x * r, i) / factorial(i);
  }

  return res;
}

template 
constexpr std::array sine_array_impl(std::index_sequence) {
  return {{sine(T{Is})...}}; 
}

template 
constexpr std::array sine_array() {
  return sine_array_impl(std::make_index_sequence{});
}

现场演示

推荐阅读
135369一生真爱_890
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有