c ++ libstd同时计算sin和cos

gal*_*tte 12 c++ math trigonometry libstdc++

在C库中math.h,有一个sincos非常有效的函数,因为它在更接近单个调用sin()或者cos()调用两者的总时间的时间内计算正弦和余弦.

C++标准库中有这样的功能吗?

Ali*_*Ali 8

c ++标准库中没有这样的功能吗?

不,不幸的是没有.

在C库math.h中,有一个sincos函数

在Linux上,它可以作为GNU Extension使用.它也不是C的标准.


Eva*_*ark 6

只需分别使用 sin 和 cos 并打开优化。C 编译器非常擅长优化,他们可能会意识到您正在计算同一变量的正弦和余弦。如果您想确保,您可以始终检查生成的程序集(对于 gcc 使用 -S 选项)并查看它生成了什么。

编译器可能会优化掉任何调用sincos支持简单地使用 SSE 指令来计算它。我不确定 SSE 是否有sincos操作码,但即使单独计算它们也比调用sincos编译器不会优化的任何函数更快。

  • SSE 不支持 sin/cos 或除除法和平方根之外的任何“花哨”函数。但是某些编译器(例如英特尔编译器)将具有使用 SSE 的矢量化实现。 (3认同)
  • 使用 godbolt 我确认在高优化级别的较新 GCC 版本确实设法将 sin + cos 合并到 sincos,但是 clang 和 VS2017 没有这样的优化。 (3认同)
  • @DanOlson,在这里确认 https://godbolt.org/z/wuS26Z 对于 GCC 和 intel 来说处于相当低的优化水平。clang 仅在“-Ofast”(快速数学)中进行优化。这暗示我“sincos”可能无法保证与单独调用“sin”和“cos”的结果“完全相同”。 (2认同)

ɲeu*_*urɳ 5

虽然没有标准的 C++ 库函数,但您可以非常快速地定义模板函数:

template <class S>
std::pair<S,S> sincos(S arg) { return { std::sin(arg), std::cos(arg) }; }
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用以下命令在一行(使用 C++ 17)中获取结果:

auto [s, c] = sincos(arg);
Run Code Online (Sandbox Code Playgroud)

如果您经常这样做,它会非常方便,节省空间,并且是自记录的,所以我强烈推荐它。如果您担心性能,请不要担心。当使用优化进行编译时,它应该生成与分别调用 sin 和 cos 完全相同的代码。clang++ -std=c++17 -S -o - -c -O3 sincos.cpp您可以通过以下测试代码确认情况是否如此:

#include <cmath>
#include <utility>
#include <iostream>

template <class S>
std::pair<S,S> sincos(S arg) { return { std::sin(arg), std::cos(arg) }; }

void testPair(double a) {
    auto [s,c] = sincos(a);
    std::cout << s << ", " << c << '\n';
}

void testSeparate(double a) {
    double s = std::sin(a);
    double c = std::cos(a);
    std::cout << s << ", " << c << '\n';
}
Run Code Online (Sandbox Code Playgroud)

在使用 clang 的 MacOS 上,两个测试函数都编译为完全相同的程序集(减去名称更改),调用该程序集___sincos_stret来执行组合计算(请参阅/sf/answers/1331210051/)。

  • godbolt 显示在 -O3 处我们得到了所需的程序集:https://godbolt.org/z/KdT9fjEEr (2认同)