2

正如我在其他问题中所展示的那样,我目前正在实现一个 C++ 元编程库,其中包括一组用于编译时算术的类型和元函数。

我现在的目标是实现三角函数sincos我的定点类型。
我的问题是,我发现的每一篇关于三角算法的论文都谈到了CORDIC或某种泰勒级数。CORDIC 的问题在于它需要通过查找表来提供大量预先计算的值,而我无法通过 tmp 轻松提供它。此外,CORDIC 的重点是在没有乘法器的硬件中计算三角函数,而且我完全有能力用我的库进行乘法运算。

所以我的问题是:除了 CORDIC 和泰勒级数还有其他简单的替代方法来计算三角函数吗?

4

2 回答 2

3

最后我sin通过泰勒级数实现了元函数,默认使用 10 个术语的系列(可以配置)。我的实现基于这篇有趣的文章

我的库包括使用迭代器的 tmp for 循环的实现,以及允许以“清晰”方式编写复杂表达式的表达式模板(与常见的模板元编程语法相比清晰add<mul<sub<1,2>>>......)。这允许我从字面上复制粘贴文章提供的 C 实现:

template<typename T , typename TERMS_COUNT = mpl::uinteger<4>>
struct sin_t;

template<typename T , typename TERMS_COUNT = mpl::uinteger<4>>
using sin = typename sin_t<T,TERMS_COUNT>::result;

/*
 * sin() function implementation through Taylor series (Check http://www10.informatik.uni-erlangen.de/~pflaum/pflaum/ProSeminar/meta-art.html)
 * 
 * The C equivalent code is:
 * 
 * // Calculate sin(x) using j terms
 * float sine(float x, int j)
 * {
 *     float val = 1;
 *
 *     for (int k = j - 1; k >= 0; --k)
 *         val = 1 - x*x/(2*k+2)/(2*k+3)*val;
 *
 *     return x * val;
 * }
 */

template<mpl::fpbits BITS , mpl::fbcount PRECISION , unsigned int TERMS_COUNT>
struct sin_t<mpl::fixed_point<BITS,PRECISION>,mpl::uinteger<TERMS_COUNT>>
{
private:
    using x = mpl::fixed_point<BITS,PRECISION>;

    using begin = mpl::make_integer_backward_iterator<TERMS_COUNT-1>;
    using end   = mpl::make_integer_backward_iterator<-1>;

    using one   = mpl::decimal<1,0,PRECISION>;
    using two   = mpl::decimal<2,0,PRECISION>;
    using three = mpl::decimal<3,0,PRECISION>;

    template<typename K , typename VAL>
    struct kernel : public mpl::function<decltype( one() - ( x() * x() )/(two() * K() + two())/(two()*K()+three())*VAL() )> {};

public:
    using result = decltype( x() * mpl::for_loop<begin , end , one , kernel>() );
};

是项目 repo 中实现的标头。

于 2013-09-14T14:25:08.123 回答
2

通过查找表的大量预先计算的值

“巨大”有多少?听起来像是一次性的努力,一旦你完成了就会很快。我的建议?拿一把铁锹填满那张桌子。当你在这里得到另一个答案时,你已经完成了。

于 2013-09-12T01:14:42.623 回答