毕达哥拉斯身份:我如何计算适当的cos符号?

时间:2015-04-07 10:42:03

标签: c++ math sin cos

有公式

  

cos(x)= sqrt(1-sin(x)^ 2)

我试图在我的简单程序中测试它,但我不知道我的错在哪里。 结果最终不正确。

#include <iostream>
#include <vector>
#include <cmath>

int main() {
    std::vector<float> data;

    constexpr float angleAdd = 360.0/10.0;
    constexpr float M_PI_DIVIDED_BY_180 = M_PI/180.0;

    for (auto angle = 0.0; angle < 360.0; angle += angleAdd) {
        data.push_back(angle);
    }

    //
    float res1 = 0;
    for (int i = 0; i < data.size(); ++i) {
        res1 += sin(data[i]*M_PI_DIVIDED_BY_180);
        res1 += cos(data[i]*M_PI_DIVIDED_BY_180);
    }

    std::cout << "\n\n";

    float res2 = 0;
    for (int i = 0; i < data.size(); ++i) {
        float angle = data[i];      
        float sinVal = sin(angle*M_PI_DIVIDED_BY_180);

        bool isPositiveSign = (angle >= 0 && angle <= 90) || (angle >= 270 && angle <= 360);
        float cosVal = sqrt(1 -sinVal*sinVal);
        if (isPositiveSign) {
            cosVal = fabs(cosVal);
        } else {
            cosVal = -1.0*fabs(cosVal);
        }

        res2 += sinVal;
        res2 += cosVal;
    }

    std::cout << "res1: " << res1 << " res2: " << res2 << std::endl;
    return 0;
}

它给了我:

  

res1:-6.89606e-07 res2:-3.57628e-07

显然,res2是错误的。 我确信在我对cos符号的计算中有些事情搞砸了,但我无法弄清楚 - 什么。 社区可以给我一些提示吗?

1 个答案:

答案 0 :(得分:1)

如果您可以无误地进行计算,那么您计算为res1res2的数字将为零。但是,浮点算法总是会产生错误。因此,您获得的两个不同结果只是浮点零的两种不同表示形式的计算精度 - 以双精度执行它们,您会发现幅度较小的结果。

另请注意,std::cos()std::sin() <\ n> <\ n>因此,

square(sin)+square(cos)=1

对于assert(square(std::cos(x)) != 1 - square(std::sin(x))); 的大多数值(例外情况可能只有0而且可能是pi)。

由于xres1都是零的近似值,因此它们的符号是任意的(虽然是确定性的)。如果将res2更改为angleAdd的另一个除数,您将得到不同的结果(但仍然与零的近似值一致)。

当然,所有这些都意味着您的程序不会测试360res1的任何值,这些值在零res2之内(std::numeric_limits<X>::epsilon()X使用的浮点类型是有效的。没有正确的答案。