【问题标题】:sin & cos funcs without math.h [closed]没有 math.h 的 sin 和 cos 函数 [关闭]
【发布时间】:2016-08-12 12:12:37
【问题描述】:

由于 PS3 3.40 SDK 引起的某些编译器问题,我无法使用 c++ 函数 sin()cos()sin() & cos() 的计算是什么,所以我可以在不需要 math.h 的情况下使用函数?

到目前为止,我已经想出了这些,但它们似乎无法正常工作?

float sin(float deg) {
    bool neg = false;
    while (deg >= 360) deg = deg - 360;
    while (deg < 0) deg = deg + 360;
    if (deg > 180) {
        deg = deg - 180;
        neg = true;
    }
    float ret = (float)(4*deg*(180-deg))/(40500-(deg*(180-deg)));
    if (neg)return ret*-1;
    return ret;
}

float cos(float AnglesDeg)
{
 float AnglesRad = DegreesToRadians(AnglesDeg);
 float Rad = (float)(PI/2.0f)-AnglesRad;
 float ang = RadiansToDegrees(Rad);
    return sin(ang);
}

【问题讨论】:

  • 由于某些编译器问题,我无法使用 c++ 函数 sin() 和 cos()。 那些“编译器问题”是什么?
  • 可以加入cmath吗?
  • sin()cos()stdlib 的一部分,因此您应该可以使用它们,请尝试修复编译错误,如果不能,然后将它们添加到您的问题中在这方面寻求帮助。
  • 也许你应该自己实现一些泰勒级数函数。
  • @Jaa-c 标准的cossin 函数当然不是微不足道的,你不能简单地从头文件中复制它们。

标签: c++ math trigonometry


【解决方案1】:

您可以使用泰勒级数自行实现。代码很简单:

float sine(int deg) {
    deg %= 360; // make it less than 360
    float rad = deg * PI / 180;
    float sin = 0;

    int i;
    for(i = 0; i < TERMS; i++) { // That's Taylor series!!
        sin += power(-1, i) * power(rad, 2 * i + 1) / fact(2 * i + 1);
    }
    return sin;
}

float cosine(int deg) {
    deg %= 360; // make it less than 360
    float rad = deg * PI / 180;
    float cos = 0;

    int i;
    for(i = 0; i < TERMS; i++) { // That's also Taylor series!!
        cos += power(-1, i) * power(rad, 2 * i) / fact(2 * i);
    }
    return cos;
}

正如你所说,你没有 math.h,我为这个算法做了一个简单的幂函数。您还需要一个函数来计算阶乘数。他们在这里:

float power(float base, int exp) {
    if(exp < 0) {
        if(base == 0)
            return -0; // Error!!
        return 1 / (base * power(base, (-exp) - 1));
    }
    if(exp == 0)
        return 1;
    if(exp == 1)
        return base;
    return base * power(base, exp - 1);
}

int fact(int n) {
    return n <= 0 ? 1 : n * fact(n-1);
}

PI 和 TERMS 只是我使用的预处理器指令 (#define's),即 PI 3.14159(在我的情况下,我使用了 50 位精度的 pi,这完全没有必要),TERMS 为 7。

【讨论】:

    【解决方案2】:

    如果你真的需要自己实现 sin 和 cos 函数,你应该使用泰勒级数 sin x = x - x^3/3! + x^5/5! -x^7/7! ..cos x = 1 -x^2/2!+x^4/4!-x^6/6! ..,其中 n!是 n n!=1*2*3*..*(n-1)*n 的阶乘。下面是一个相当健壮的实现。它使用度数作为输入,因为我认为原始海报不希望像标准函数那样的弧度。

    #include <iostream>
    
    const double PI=3.1415926535897932384650288;
    
    double sin(double x){
      double sign=1;
      if (x<0){
        sign=-1.0;
        x=-x;
      }
      if (x>360) x -= int(x/360)*360;
      x*=PI/180.0;
      double res=0;
      double term=x;
      int k=1;
      while (res+term!=res){
        res+=term;
        k+=2;
        term*=-x*x/k/(k-1);
      }
    
      return sign*res;
    }
    
    double cos(double x){
      if (x<0) x=-x;
      if (x>360) x -= int(x/360)*360;
      x*=PI/180.0;
      double res=0;
      double term=1;
      int k=0;
      while (res+term!=res){
        res+=term;
        k+=2;
        term*=-x*x/k/(k-1);
      }  
      return res;
    }
    
    int main(){
      double c = cos(1231);
      double s = sin(1231);
      std::cout << "cos(1231) = " << c << ", sin(1231) =  " << s << " sin^2+cos^2=" << c*c+s*s << " (should be 1)" << std::endl;
    }
    

    【讨论】:

      【解决方案3】:

      我很确定您的协处理器具有 sincos 操作,您可以使用汇编程序调用它们,例如:

      double mycos(double)
      {
        __asm
        {
          fld qword ptr[ebp + 8]
          fcos
        }
      }
      
      double mysin(double)
      {
        __asm
        {
          fld qword ptr[ebp + 8]
          fsin
        }
      }
      

      但请注意,此方法不安全且不可移植,因此最好使用stdlib 解决您的问题。

      【讨论】:

      • 这几乎行不通。 (我的意思是,由于所使用的语法,唯一真正起作用的地方是 MSVC 编译 32 位时。)
      • @Griwes 你说得对。这就是为什么 ts 不应该使用这个代码,而是在他的平台上使用类似的东西。而且我提到这个解决方案应该被认为是最后的边界。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多