2016-10-13 254 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; 
}