Home > OS >  Bus error when programming Taylor series in C
Bus error when programming Taylor series in C

Time:04-18

I am working on a program in C that graphs a rose curve as ASCII art. The program uses custom trig functions (Taylor series to be exact):

int factorial(int n) {
    int p = 1;
    if (n == 0) return 1;
    for (int i = 1; i < n; i   ){
        p *= i;
    }
    return p;
}

float sine(float x, int t) {
    float s = 0;
    for (int i = 0; i < t; i   ) {
        float n = (i%2==0 ? 1 : -1);
        int d = factorial(i*2);
        float m = pow(x, i*2);
        s  = (n/d)*m;
    }
}

float cosine(float x, int t) {
    float s = 0;
    for (int i = 0; i < t; i   ) {
        float n = (i%2==0 ? 1 : -1);
        int d = factorial(i*2 1);
        float m = pow(x, i*2 1);
        s  = (n/d)*m;
    }

The t parameter denotes the number of terms, which is always 10.

And to graph the rose I use:

void point(float r, float theta) {
    float fx = r*cosine(theta, TM);
    float fy = r*sine(theta, TM);
    int x = (int) round(fx) 50;
    int y = (int) round(fy) 50;
    grid[x][y] = 1;
}
...other code...
for (float theta = 0; theta < PI; theta  = 0.5) {
    float r = SCALE*cosine(theta*CT, TM);
    point(r, theta);

The SCALE variable is the size of the rose and is defined at the top of the program. The TM variable is the number of terms in the Taylor series, and the CT variable is another parameter. It works fine using default C trig functions, but when I switch to mine it gives me a bus error, which says

make: *** [run] Bus error: 10

. This is on Mac OS X 10 by the way. The functions I wrote give me the correct values for a few numbers but just don't work here.

The Taylor series I'm using are here, and my implementation works in radians:

enter image description here

If you're wondering why I didn't just use the default trig functions, I'm doing this for fun and custom trig functions are part of what I want to do for this project. I'm also not the most experienced C programmer so keep that in mind.

CodePudding user response:

Okay, so when I see a "bus error: 10" on MacOS, my first thought is that your program tried to access a memory address wrongly.

(Another common error that tells me roughly the same general gist is "segmentation fault/violation". There is nuance to which one means what on which system that you can look up in other questions.)

Now that we know that, we can significantly narrow down possible causes! It must be a place in the code where your memory accesses could be targeting the wrong memory.

Looking over the code you initially posted, the only place I can see where that might happen is the assignment to grid[x][y].

So my next thought is: how could x or y end up outside of your allocated grid space? I'm assuming grid has known fixed dimensions, and trusting your claim that the only thing you change to trigger the problem is swapping which trig functions you used.

Based on that, I would think maybe your trig functions are returning values which end up (due to rounding or approximation or whatever) causing x or y to be outside of the grid.

The simplest thing you could do to debug this further is to add a printf("x=%d y=%d\n", x, y); line just before the line where you have grid[x][y].

(You may want to also take the time to get familiar with how to run running your program live under a debugger, so that you can see variable values changing as the code steps through each instruction, but that's a separate detour onto another learning curve.)

Also, based on this related question that StackOverflow recommended, it sounds like maybe Taylor series is just inherently be too inaccurate when you get too far from zero? Might be relevant here.

CodePudding user response:

  1. your goniometrics computation is wasting too much CPU power

    see C function to approximate sine using taylor series expansion

    You are computing the same stuff again and again, You mix int and float causing slow conversions ...

  2. how big is TM ?

    you know factorial overflows pretty quick and on floats you can not get better precision than 5 decimals no matter what TM is anyway so I would not dare to go above 15 ...

  3. you are not returning float value in sine and cosine

    That is most likely corrupting STACK and causing your error as the rest of the code is expecting it but I do not code on your platform so I might be wrong ... Better compilers throw a warning on this ...

    And of coarse without return your sin and cos simply does not work as even if you compute it it will not propagate the result to rest of your code. Instead you most likely got gibberish from STACK causing seemingly random numbers or even INF or NAN ...

So simply repair your functions like this (hope I port it to C from the link above correctly):

float sine(float x,int n=15)
    {
    int i;
    float y=0;      // result
    float x2=x*x;   // x^2
    float xi=x;     // x^i
    float ii=1;     // i!
    if (n>0) for(i=1;;)
        {
        y =xi/ii; xi*=x2; i  ; ii*=i; i  ; ii*=i; n--; if (!n) break;
        y-=xi/ii; xi*=x2; i  ; ii*=i; i  ; ii*=i; n--; if (!n) break;
        }
    return y;
    }

As you can see no need for expensive operations like modulo and no calls to sub-functions nor repetitive computing of the same stuff in each iterations like you do ... Do not forget to repair your cosine too

  • Related