2015-04-07 71 views
0

具有式畢達哥拉斯身份:我如何計算正確的cos符號?

COS(X)=開方(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

「顯然,res2是錯誤的」。爲什麼?你期望什麼價值? – interjay

+1

這不是一個有效的測試,因爲舍入錯誤也有所貢獻。總和應該是零,所以你看到的是兩個不同的舍入誤差。兩者都具有預期的幅度,即接近'std :: numeric_limits :: epsilon()'。 – Walter

+0

'res1'和'res2'應該*近乎相等,不是嗎? – fres

回答

1

如果您可以在沒有錯誤的情況下進行計算,那麼您計算的數字爲res1res2將爲零。但是,浮點運算總是會產生錯誤。因此,您獲得的兩個不同結果僅僅是浮點零點到計算精度的兩種不同表示 - 以雙精度執行,並且您可以找到更小幅度的結果。

還要注意的是std::cos()std::sin()不準確滿足身份square(sin)+square(cos)=1。因此,

assert(square(std::cos(x)) != 1 - square(std::sin(x))); 

用於x大多數值(例外是大概只有0和或許PI)。

由於res1res2都近似爲零,它們的符號是任意的(儘管是確定性的)。如果將angleAdd更改爲360的另一個除數,則會得到不同的結果(但仍與零點的近似值一致)。

所有這一切都意味着,當然,你的程序測試什麼和res1res2是內從零幾std::numeric_limits<X>::epsilon()(其中X是使用了浮點型)是有效的,任何價值。沒有正確答案。

+0

謝謝。我不明白的一點是,如果我有'angleAdd = 360.0/2.0','res1'和'res2'可能會有不同的符號。 – fres

+0

在這種情況下,我得到'res1:3.33067e-16 res2:-8.74228e-08'。這仍然是正確的嗎? – fres

+0

沒有正確的答案。請參閱編輯我的答案。 – Walter

相關問題