3

I cannot use the c++ functions sin() and cos() due to certain compiler issues caused by PS3 3.40 SDK. What are the calculations of sin() & cos() so i can use functions without needing math.h?

I have so far came up with these, but they seem to not be functioning correctly?

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);
}
JeffCoderr
  • 283
  • 1
  • 4
  • 16
  • 10
    *So i cannot use the c++ functions sin() and cos() due to certain compiler issues.* What "compiler issues" are those? – Borgleader Aug 12 '16 at 12:14
  • 5
    Can you include `cmath` ? – Nishant Aug 12 '16 at 12:15
  • `sin()` and `cos()` are part of the [stdlib](https://en.wikipedia.org/wiki/C_mathematical_functions) so you should be able to use them, please try to fix the compile errors, if you cannot, then add them to your question to seek help in this regard. – A4L Aug 12 '16 at 12:19
  • Those compiler issues are in these functions? Why not just copy-paste them from the standard header? – Jaa-c Aug 12 '16 at 12:19
  • 3
    Maybe you should implement some Taylor Series function by yourself. –  Aug 12 '16 at 12:19
  • 3
    @Jaa-c The standard `cos` and `sin` functions are certainly not trivial and you cannot simply copy them from header files. – Holt Aug 12 '16 at 12:20
  • You can easily test the formulas you implemented using an [online plotter](http://fooplot.com/?lang=en#W3sidHlwZSI6MCwiZXEiOiJzaW4ocGkqeC8xODApIiwiY29sb3IiOiIjMDBGRjAwIn0seyJ0eXBlIjowLCJlcSI6Iig0KngqKDE4MC14KSkvKDQwNTAwLSh4KigxODAteCkpKSIsImNvbG9yIjoiIzAwMDBGRiJ9LHsidHlwZSI6MCwiZXEiOiItKDQqKHgtMTgwKSooMzYwLXgpKS8oNDA1MDAtKCh4LTE4MCkqKDM2MC14KSkpIiwiY29sb3IiOiIjRkYwMDAwIn0seyJ0eXBlIjoxMDAwLCJ3aW5kb3ciOlsiLTYwIiwiNDIwIiwiLTEuMiIsIjEuMiJdfV0-), you can see that you got the right formulas, so your problem is somewhere else in the code. – BeyelerStudios Aug 12 '16 at 12:36
  • Possible duplicate of [How does C compute sin() and other math functions?](http://stackoverflow.com/questions/2284860/how-does-c-compute-sin-and-other-math-functions) – Victor Sergienko Aug 12 '16 at 13:24
  • Taylor series are some sort of "de facto standard", but it's not necessarily what you must choose, I offer this alternative: http://forum.devmaster.net/t/fast-and-accurate-sine-cosine/9648 – harold Aug 12 '16 at 16:07
  • @Borgleader i am writing software on PS3 3.40 SDK, it cannot compile when certain libs / lib functrions are used... – JeffCoderr Aug 13 '16 at 00:48

3 Answers3

6

You can use Taylor Series to implement this by yourself. The code is straight forward:

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;
}

As you said you don't have math.h, I made a simple power function for this algorithm. Also you need a function to calculate factorial nubmers. Here they are:

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 and TERMS were just preprocessor directives (#define's) I used, being PI 3.14159 (in my case I used a 50 digits precision pi, what is completely unnecessary) and TERMS being 7.

Carlos Afonso
  • 1,927
  • 1
  • 12
  • 22
3

If you really need to implement the sin and cos functions yourself you should use the taylor series sin x = x - x^3/3! + x^5/5! -x^7/7! .. and cos x = 1 -x^2/2!+x^4/4!-x^6/6! .., where n! is the factorial of n n!=1*2*3*..*(n-1)*n. A fairly robust implementation is below. It uses degrees as input as I think original poster wanted not radians like the standard functions.

#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;
}
Ari Hietanen
  • 1,749
  • 13
  • 15
2

I'm pretty sure your coprocessor has sin and cos operations, and you can call them using Assembler, something like:

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

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

But please notice that this method is unsafe and unportable and so it's much better to solve your issues with stdlib.

alexeykuzmin0
  • 6,344
  • 2
  • 28
  • 51
  • This hardly works. (I mean, the only place this actually works due to the syntax used is MSVC *when compiling for 32-bit*.) – Griwes Aug 12 '16 at 12:45
  • @Griwes You right. That's why ts should use not this code, but something similar on his platform. And I mentioned that this solution should be considered as being the last frontier only. – alexeykuzmin0 Aug 12 '16 at 12:49