2016-10-13 342 views
0

我是C++的新手,已經編寫了一個小程序來查找角度的正弦和餘弦值。我的示例代碼如下:在C++中找到角度的正弦和餘弦值

#include <math.h> 
#include <iostream> 
#include <iomanip> 
using namespace std; 
#define PI 3.14159265 

int main() 
{ 
    double rate, result; 
    rate = 90.0; 
    result = cos (rate*PI/180); 
    cout<<"The cosine of " << rate << " degrees is " << result <<endl; 
    return 0; 
} 

我得到1.7949e-009作爲cos(90)的結果。有沒有辦法得到0作爲結果(在結果變量),而不是這種格式?同樣的問題是180度的罪惡。我希望的情況下,一般的解決方案,其中得到的值將是0

+1

溝#define PI',使用數學頭中的M_PI。 –

+3

@ n.m。它不是一個標準化的定義 – krzaq

+0

[相關問題](http://stackoverflow.com/questions/6566512/value-of-sine-180-is-coming-out-as-1-22465e-16) – njuffa

回答

0
#include <stdio.h>  
#include <math.h>  

#define PI 3.14159265 

int main(){ 

    double param, result; 
    param = 30.0; 
    result = sin (param*PI/180); 
    printf ("The sine of %f degrees is %f.\n", param, result); 
    return 0; 
} 
+0

但實際上並不存儲結果變量0。對? @rishabhgupta – user76289

+0

'printf'和'ostream'可能使用不同的精度進行打印,但這只是一個症狀。 – StoryTeller

0

結果是1.7949e-009,這是科學的方法,你可以用固定的方式,即使指定點的精度。

實際上1.7949e-009約爲0.0000000017949。

用戶krzaq指定輸出格式是固定的方式,並設置精度2,它將打印:

the cosine of 90.0 degree is 0.00 

除了你的PI是不夠準確的。

要獲得高精度,唯一需要做的事情就是下載glm。 glm是一款出色的數學派對,它在OpenGL數學功能中表現出色。 這裏是代碼使用GLM:

#include <iostream> 
#include <glm.hpp> 

int main() 
{ 
    double Angle, Result; 
    Angle = 90.0; 
    Result = glm::cos(glm::radians(Angle)); 
    std::cout << "The cosine of " << Angle << " degrees is " << std::fixed << Result << std::endl; 
    return 0; 
} 
+0

是否有任何方法將結果變量中的精確值存儲以供將來使用? @FrancisHoo – user76289

+0

結果值仍然是1.7949e-009,它並未被關鍵字fixed和setprecision(2)所改變。關鍵字fixed和setprecision(2)僅限制輸出格式。 –

+0

是的,我正在說這個。但我需要做些什麼才能存儲準確的使用價值? @FrancisHoo – user76289

0

我有嘗試M_PI,3.141592653589793238L或ACOS(-1L)。在你的程序中,所有這些PI的近似值都不會產生0。 但是,至少你可以使用std :: setprecision和std :: fixed(在iomanip中)來顯示0. 或者你可以使用自定義epsilon來舍入結果。

3

既然你標記後C++而不是C,讓我給你一些C++提示:

  1. 的數學標準的頭是<cmath>而不是<math.h>
  2. 在C++中有更好的方式來聲明常量那#define
  3. 浮點數不是實數的精確表示(沒有計算精確表示可以存在),所以你總是以舍入誤差結束。

更習慣的方法來結果凸輪是這樣的:

#include <cmath> 
#include <iostream> 
#include <iomanip> 

int main() 
{ 
    const auto PI = std::acos(-1); //let the computer to find out what PI is 

    double rate{}, result{}; //don't let uninitialized values 
    rate = 90.0; 
    result = std::cos (rate*PI/180); 
    std::cout<<"The cosine of " << // set outoput precison for floating point 
     std::setprecision(4) << rate << " degrees is " << 
     std::setprecision(4) << result <<endl; 
    return 0; 
} 

注意我如何讓std::明確:C++ <cmath>有比C數學函數更多超載

參見:

還要注意的是,雖然更準確PI使得result更加精確,總有一種可能性,即結果並不完美,所以當顯示浮點值時,將精度設置到足以補償的水平e對於您的問題有意義的級別的換位錯誤。

實數的表示精度可以從std::numeric_limits<double>::digits10(來自<limits>表頭)獲得:切出2-3位數字總是很好。

另外,還要考慮舍入誤差,做減法或比較的時候:看到的例子在std::numeric_limits::epsilon參考文檔:

#include <cmath> 
#include <limits> 
#include <iomanip> 
#include <iostream> 
#include <type_traits> 
#include <algorithm> 

template<class T> 
typename std::enable_if<!std::numeric_limits<T>::is_integer, bool>::type 
    almost_equal(T x, T y, int ulp) 
{ 
    // the machine epsilon has to be scaled to the magnitude of the values used 
    // and multiplied by the desired precision in ULPs (units in the last place) 
    return std::abs(x-y) < std::numeric_limits<T>::epsilon() * std::abs(x+y) * ulp 
    // unless the result is subnormal 
      || std::abs(x-y) < std::numeric_limits<T>::min(); 
} 
int main() 
{ 
    double d1 = 0.2; 
    double d2 = 1/std::sqrt(5)/std::sqrt(5); 

    if(d1 == d2) 
      std::cout << "d1 == d2\n"; 
    else 
      std::cout << "d1 != d2\n"; 

    if(almost_equal(d1, d2, 2)) 
      std::cout << "d1 almost equals d2\n"; 
    else 
      std::cout << "d1 does not almost equal d2\n"; 
} 

,顯示的sqrt(5)如何平方是不是... ... 5,即使你管理看上去這麼:

(劇透:在outpu是

d1 != d2 
d1 almost equals d2 

);-)

0

有沒有辦法得到0作爲結果[餘弦(90°)]?

步驟1中,用一個更準確的機PI

步驟2:而不是轉換爲弧度,然後調用cos(),降低的範圍內,然後轉換爲弧度,然後調用cos()

範圍縮減可以通過exactlyfmod(x,360.0)並且進一步與各種trigonometric identifies來完成。

This answer提供有關一般方法和詳細的sind(double degrees)的信息。以下是結果值爲0的情況的一般解決方案。This post討論-0.0的問題。

// cos() of 90.0 degrees is 6.1232339957367660e-17 
// cosd() of 90.0 degrees is 0.0000000000000000e+00 

#include <cmath> 


static double d2r(double d) { 
    static const auto PI = std::acos(-1); 
    return (d/180.0) * PI; 
} 

double cosd(double x /* degrees */) { 
    if (!isfinite(x)) { 
    return std::cos(x); 
    } 
    int quo; 
    double x90 = std::remquo(std::fabs(x), 90.0, &quo); 
    double xr = d2r(x90); 
    switch (quo % 4) { 
    case 0: 
     return std::cos(xr); 
    case 1: 
     // Use + 0.0 to avoid -0.0 
     return std::sin(-xr + 0.0); 
    case 2: 
     return -std::cos(xr); 
    case 3: 
     return std::sin(xr + 0.0); 
    } 
    return 0.0; 
}