C++ program to find sin of x

Discussion in 'Mac Programming' started by Mugambo, Aug 16, 2012.

  1. Mugambo macrumors 6502

    Mugambo

    Joined:
    Jul 4, 2009
    #1
    I have compiled the program and it executes.
    But soon after I give a value say 30 (i.e. to find sin 30) cursor keeps blinking with no response.
    Along with C, I'm learning C++ from books.

    Code:
    #include <iostream>
    #include <math.h>
    #include <stdlib.h>
    #include <stdio.h>
    using namespace std;
    
    class value {
        float n, x, fct, count;
        public:
        void getx() {
            cout<<"Enter a number"<<endl; cin>>x; fflush(stdin);
        }
        float fact(float j) {
            fct=1;
            while(1) {
                fct=fct*j; j++;
            }
            return fct;
        }
        void sinx(){
            float sinxx;
            count=-1;
            float i;
            i=1;
            sinxx=0;
            while(i<=10){
            count*=count;
            sinxx=sinxx+count*((pow(x,i))/fact(i));
            i+=2;
            }
            printf("sin of %d is %f", x, sinxx);
        }
    };
    
    int main()
    {
        value sed;
        sed.getx();
        sed.sinx();
        return 0;
    }
    
     
  2. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #2
    This:

    Code:
     float fact(float j) {
            fct=1;
            while(1) {
                fct=fct*j; j++;
            }
            return fct;
        }
    
    looks very wrong to me. I'm not C++ expert but how does the while loop ever terminate?
     
  3. Mugambo thread starter macrumors 6502

    Mugambo

    Joined:
    Jul 4, 2009
    #3
    Code:
    
        float fact(float j) {
            fct=1;
            while(j>=1) {
                fct=fct*j; j--;
            }
            return fct;
        }
    
    
    Thank you for the help.
    Not able to get accurate results yet.
    Help please.
     
  4. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #4
    Then work through the code on paper and work out why. Debugging is a core part of programming. Simply saying "it's not working" and getting someone else to study, analyse and fix is not.
     
  5. gnasher729 macrumors P6

    gnasher729

    Joined:
    Nov 25, 2005
    #5
    For small x, let's say less than 1, sin (x) is close to x. Do you get that? If yes, that's a start.

    The sine function has arguments in radians, not in degrees. What is sin (0), sin (pi/2), sin (pi), sin (3pi/2), sin (2 pi) and how does it go on after that? You know what the sine curve looks like, don't you?

    For large x, like the 30 which you mention, which is close to 9.5 pi, the Taylor formula isn't very accurate. What about printing out the values that you are adding up?

    And then of course you should check the value of "count". Which is badly named, because it doesn't count anything. Probably meant to be called "sign".
     
  6. Mugambo thread starter macrumors 6502

    Mugambo

    Joined:
    Jul 4, 2009
    #6
    Robbieduncan, that's a piece of advice which I'm sure no book can offer. I truly thank you for that. Debugging on paper got me there!

    Got it finally!
    I'm getting accurate results for values entered between sin(-11) and sin(11). Beyond that results are inaccurate. This is due to reduced iterations.
    Simply increasing iterations/(no. Of passes) seems to have a limit after which junk values are displayed.
    In my case anything over 250 iterations is causing junk values.

    Any best practices to follow in order to avoid above scenario will be helpful.
     
  7. Mugambo thread starter macrumors 6502

    Mugambo

    Joined:
    Jul 4, 2009
    #7
    Gnasher, great heads up on the sine wave! Now I got a clear picture. Very helpful, thanks. This answers my above post. Please ignore above post btw.
     
  8. chown33, Aug 16, 2012
    Last edited: Aug 16, 2012

    chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #8
    The best practice is to learn how to use the debugger. Then use it.

    With a debugger, you can set breakpoints on functions and lines in functions, then step through a line at a time. You can also examine variables while stopped at a breakpoint, or stepping through.

    If your book doesn't teach you how to use the debugger, find one that does.
     
  9. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #9
    I suspect that you should be looking at the fact the function is periodic.
     
  10. gnasher729 macrumors P6

    gnasher729

    Joined:
    Nov 25, 2005
    #10
    Again, print out the values that are added up. If x >= 3, then these values will first grow and then become smaller. Your initial code failed because the number of iterations was too low, and you dropped values that were still quite large. But if x > 20, you will see that these values can become _very_ large, and adding them will just produce huge rounding errors. Since -1 <= sin x <= 1, as soon as the rounding error is > 1, your results will be nonsense.

    Try first what happens if you replace "float" with "double" and "long double". It will improve things, but not solve the problem. However, in many cases just using "double" will make a solution good enough, so you should _never_ use float (until you reached the point where you don't need to follow anyone's advice).

    The second thing which solves this particular problem: There is a formula for the sine function

    sin (x + 2pi) = sin (x).

    Obviously sin (x + k * 2pi) = sin (x) for every integer k.

    So you take x / (2pi), rounded to the nearest integer, call the result k, and subtract k * 2pi from x before you start calculating.
     
  11. ghellquist macrumors regular

    Joined:
    Aug 21, 2011
    Location:
    Stockholm Sweden
    #11
    It is a rather typical result in evaluating mathematical functions on a computer. Too many iterations often leads to wrong results as errors accumulate. The main reason for this is that calculations are done with a finite precision, ie a maximum number of decimals in the number. A series that in "pure" mathematics converges on a value might very well start swinging between very different values or slowly move away from the correct value.

    There is a whole branch of science known as numerical methods that deals with this kind of techniques. It is taken as courses on advanced level in universities, but if you are interested there is a lot of interesting material freely available on the net. Using methods in that area allows you to calculate the optimum number of iterations for this kind of algorithms, depending on what precision the numbers use (float, double float or even longer floats).

    A quick fix for your algorithm would be to scale the input before running the algorithm. This works as the sin function is periodic and the input can be scaled to between 0 and 2*pi. You could actually scale to between 0 and 1/2*pi and do some mirroring as a last step.

    Have fun // Gunnar
     
  12. softwareguy256, Aug 19, 2012
    Last edited by a moderator: Aug 19, 2012

    softwareguy256 macrumors regular

    Joined:
    Jun 5, 2010

Share This Page