在c ++中查找角度的正弦和余弦值

时间:2016-10-13 05:52:21

标签: c++ math cos

我是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的情况的一般解决方案。

5 个答案:

答案 0 :(得分:3)

由于你标记了后期C ++而不是C,让我给你一些C ++提示:

  1. 数学的标准标题是<cmath>而不是<math.h>
  2. 在c ++中有更好的方法来声明#define
  3. 的常量
  4. 浮点数不是实数的精确表示(不存在计算精确表示),因此总是会出现舍入误差。
  5. 更为惯用的方法来得出结果:

    #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更准确,但总有可能结果不完美,因此 - 当显示浮点值时 - 将精度设置为足以在对您的问题有意义的水平上补偿换向误差。

    实数的表示精度可以从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
    

    ); - )

答案 1 :(得分: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;
}

答案 2 :(得分: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;
}

答案 3 :(得分:0)

我试过M_PI,3.141592653589793238L或acos(-1l)。所有这些PI的近似值都不会在您的程序中完全生成0。 但是,至少你可以使用std :: setprecision和std :: fixed(在iomanip中)来显示0。 或者也许您可以使用自定义epsilon来舍入结果。

答案 4 :(得分:0)

  

有没有办法得到0作为结果[对于余弦(90°)]?

第1步,使用更准确的机器PI

第2步:不是转换为弧度然后调用cos(),而是缩小范围,然后然后转换为弧度,然后调用cos()

范围减少可以使用fmod(x,360.0)进行exactly,也可以使用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;
}