my first program. works perfectly but i dont understand why. few newbie questions.

This is a discussion on my first program. works perfectly but i dont understand why. few newbie questions. within the C Programming forums, part of the General Programming Boards category; hey there guys. i wrote a program to calculate the roots of a cubic equation using Cardanos formula , it ...

  1. #1
    jdi
    jdi is offline
    Registered User
    Join Date
    Aug 2009
    Posts
    4

    my first program. works perfectly but i dont understand why. few newbie questions.

    hey there guys.

    i wrote a program to calculate the roots of a cubic equation using Cardanos formula, it works great so far

    i posted a thread asking for help on using the pow() function and i was having trouble getting a function prototype to work, but that sorted out now, i think.

    im really happy i got this working. im so pleased i did it myself!! i only needed a tiny bit of help and i figured the rest out

    now the issues im having.

    questions:

    1. is there a pi function in C or do i have to define PI like that each time?


    2. i dont understand how my sign function works(i have no idea how i actually managed to write it with almost no problems)

    this is what i understand of it

    i declare at the beginning of my program

    float sign(float S); /* sign function prototype */

    this tells the compiler that i've declared a function to be used in the main(), so when it reaches this function it knows that it exists.

    then at the end of my function i wrote the function itself as

    Code:
    float sign(float S)
    {
    	if (S > 0)
    		return 1;
    	else if (S < 0)
    		return -1;
    	else
    		return 0;
    }
    okay what i understand of this is that the float sign(float S) means, sign(float S) is expecting to be a floating point result. im more of a mathematician so ill speak in terms more familiar to me.

    sign(float S) means f(x) where the input x will be a decimal/floating point number, this is correct

    the output of this function will always be 1, -1 or 0, so can i define this function as

    int sign(float S)?

    does this save space or make it "better" or something?

    furthermore - is S a global variable as i have defined it outside my main body? this is to say that, could i write sign function as...

    int sign(float n), then when i call the function, use it as sign(S) later in the main body?

    3.

    when i wrote this part of the code

    Code:
    Q = (b*b - 3.*c)/(9.0);
    S = (2.*b*b*b - 9.*b*c + 27.*d)/(54.0);
    my professor explained that the . after the numbers was important, i dont remember why.. infact i have no idea why. as practice in our lab class we wrote a quadratic program and the numbers used in calculating the discriminant were of the same for, eg: 2.*d*d/3.0

    how come i need the .'s there?

    4. is this program clean and easy to understand?

    is my constant use of if statements poor programming form? is there anything i can clean up?




    this is the code

    Code:
    #include <stdio.h>
    #include <math.h>
    #define PI (3.141592653589793238462643)
    
    float Q, S, a, b, c, d, A1, x1, x2, x3, theta;
    
    float sign(float S); /* sign function prototype */
    
    int main()
    {
    
    
    	/* Get coefficients from user */
    
    	printf("Cubic coefficient a? ");
    	scanf("%f", &a);
    
    	printf("Cubic coefficient b? ");
    	scanf("%f", &b);
    
    	printf("Cubic coefficient c? ");
    	scanf("%f", &c);
    
    	printf("Cubic coefficient d? ");
    	scanf("%f", &d);
    
    	/* Make sure a = 1, if it doesn't, recalculate the rest of the coefficents */
    
    	if (a != 1)
    	{
    		b = b/a; /* values of b, c, d must be calculated before a is set to 1 */
    		c = c/a;
    		d = d/a;
    		a = 1;
    	}
    
    	/* Now to do some calculations to be used later in the program */
    
    	Q = (b*b - 3.*c)/(9.0);
    	S = (2.*b*b*b - 9.*b*c + 27.*d)/(54.0);
    
    
    
    
    
    	/* temporary printf function to make sure results are being calculated correctly */
    
    	printf("%f = Q, %f = S, %f = a, %f = b, %f = c %f = d\n", Q, S, a, b, c, d);
            printf("%f = sign(S) %f = A1\n", sign(S), A1);
    	printf("%f = Q*Q*Q - S*S\n", Q*Q*Q - S*S);
    
    
    	if (Q*Q*Q - S*S > 0)
    	{
    		theta = acos(S/sqrt(Q*Q*Q));
    		x1 = -2*sqrt(Q)*cos(theta/3.) - b/3.;
    		x2 = -2*sqrt(Q)*cos((theta + 2*PI)/3.) - b/3.;
    		x3 = -2*sqrt(Q)*cos((theta + 4*PI)/3.) - b/3.;
    
    		printf("The cubic has three real roots, %f = x1, %f = x2, %f = x3\n", x1, x2, x3);
    	}
    
    
    	if (Q*Q*Q - S*S <= 0)
    	{
    		A1 = -sign(S)*pow((sqrt(S*S - Q*Q*Q) + fabs(S)),1/3.);
    
    		if (A1 = 0)
    		{
    			x1 = A1 - b/3.;
    			printf("The cubic has only one real root, %f = x1\n", x1);
    		}
    		else
    		{
    			x1 = A1 + Q/A1 - b/3.;
    			printf("The cubic has only one real root, %f = x1\n", x1);
    		}
    	}
    
    	return 0;
    
    }
    
    
    
    float sign(float S)
    {
    	if (S > 0)
    		return 1;
    	else if (S < 0)
    		return -1;
    	else
    		return 0;
    }
    Last edited by jdi; 08-18-2009 at 07:04 AM.

  2. #2
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    1) You can use the constant M_PI (defined in math.h) or, if you like, calculated it "on the fly" as the result of 4.0 * atan(1.0).

    2)
    a) It really doesn't matter much. Either way works fine (though I've usually seen it as an int).
    b) The name of a function parameter has no binding outside of the function. If you have a global variable by the same name it won't be visible within the scope of that function though, obviously.

    3) The '.' simply tell the compiler that it's a floating-point constant (as opposed to an integer).

    4) It looks fine, although you could probably optimize things a bit by not doing repetitious calculations (eg: Q*Q*Q is used in several parts of the program whereas it could be calculated just once), and personally I'd be sure to leave space between operators and operands (eg: Q * Q * Q).

  3. #3
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    1. No, but just define a constant. You may find non-standard M_PI in math.h

    2. I'd declare it as int sign(const float s), as it makes more sense. Since floating points are approximations, and why approximate on -1, 0 and 1? (Even though at least 0 can be exactly represented as a float)

    3. They are, since it makes them double constants, without them they would be integer constants and the resulting arithmetic would be different. i.e. x = (5 / 2), x is 2 since it's integer division, but x = (5. / 2), results in 2.5 since it's "floating point division".

    4. It's mostly fine, but:
    • Use more comments
    • Why calculate the same thing twice? i.e. Q*Q*Q*Q, why not store the result in say, q4? Since you use it more than once.
    • The variable names are pretty poor and nondescript.

  4. #4
    Maz
    Maz is offline
    Registered User Maz's Avatar
    Join Date
    Nov 2005
    Location
    Finland
    Posts
    194
    About the return type of sign()

    Whether it should be int or float depends on how you use it.
    Remember, that comparing floating point numbers (especially using ==) is tricky, since the decimal representation is not what is internally used by computer. Hence it may be that the value looking exact, is not exact in the computer's point of view.

    On the other hand, if sign() returns an int, then be carefull when you use it in calculations. Mixing floats and integers may get your result floored to nearest integer.

  5. #5
    sjb
    sjb is offline
    Registered User
    Join Date
    Aug 2009
    Posts
    1
    Why return 0 if and only if 's' equals 0? Doesn't that obfuscate the concept of signs?

    Code:
    int sign(const float s) {
    
        if( s >= 0)
           return 1; // s is not negative
    
        // s must be negative 
        return -1;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Memory handling functions (newbie questions)
    By PaulBlay in forum C Programming
    Replies: 6
    Last Post: 03-10-2009, 07:37 AM
  2. Writing a Unix Search Program, some questions
    By Acolyte in forum C Programming
    Replies: 3
    Last Post: 09-23-2008, 01:53 AM
  3. A program that kills itself...and questions
    By Shadow in forum C Programming
    Replies: 5
    Last Post: 07-25-2002, 08:08 PM
  4. Replies: 6
    Last Post: 01-07-2002, 02:46 AM
  5. Pls explain how this program works...
    By Unregistered in forum C Programming
    Replies: 9
    Last Post: 01-05-2002, 09:53 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21