quadratic equation help

I'm learning about pass by reference and I'm trying to write a code to solve a quadratic equation roots. It's giving me errors saying I cannot use 4.0*a inside a function but I'm not sure why.

I have a code(second one) below (that I got off the internet for reference) that's suppose to be what it looks like, but it's printing the wrong values for me. I tried getting the roots of x^2+5+6, which should be -3 and -2, but it prints a massively small number.
1
2
3
4
5
6
7
8
9
10
11
void qRoot(double a, double b, double c,
                       double& bigRoot, double& smallRoot){
                           double hold;
                           hold=((-b)+sqrt((b*b)-(4.0*a)(c)))/2*a;
                           smallRoot=((-b)-sqrt((b*b)-(4.0*a)(c)))/2*a;
                           if (smallRoot>hold){
                                bigRoot=smallRoot;
                                smallRoot=hold;}
                                else bigRoot=hold;
                       }
                           

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <string>
#include <cmath>
double quadraticRoots(double a, double b, double c, double& bigRoot, double& smallRoot);
bool pathological(double a, double b, double c, double& root);
double radical(double a, double b, double c);

int main()
{
   double x=0;
    double y=0;
std::cout<<quadraticRoots(1,5,6,x,y);
return 0;
}
double quadraticRoots(double a, double b, double c, double& bigRoot, double& smallRoot){

    if (pathological(a,b,c,bigRoot))
        smallRoot = bigRoot;
    else {
        double rad = radical(a,b,c);
        if (rad >= 0){
            if (a > 0){
                bigRoot = (-b + rad) / (2*a);
                smallRoot = (-b - rad) /(2*a);
             } else {
                bigRoot = (-b - rad) / (2*a);
                smallRoot = (-b + rad) /(2*a);
                return smallRoot;
             }
        }
    }
}
                           
bool pathological(double a, double b, double c, double& root){
    bool isPath = false; // not pathological is default
    if (a == 0.0) {
        isPath = true; // not actually a quadratic
        if (b!=0.0)
            root = -c/b;
    }
    return isPath;
}

double radical(double a, double b, double c){
    double rad = b*b - 4 * a * c;
    if (rad >= 0.0) return sqrt(rad);
    return -1.0;
}
Last edited on
(4.0*a)(c)
The problem isn't 4.0*a, it's the fact that you're trying to do implicit multiplication by c. In C++, you always have to use * to multiply:
4.0*a*c

Note also that your code will fail if there are no real roots to the equation.
Also, there are a large number of unnecessary parentheses (as well as missing parentheses where they are needed).
I updated my code. I fixed the implicit multiplication and removed any parentheses I didn't think I needed. It works now for equations with roots.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Example program
#include <iostream>
#include <string>
#include <cmath>
double qRoot(double a, double b, double c, double& bigRoot, double& smallRoot);
int main()
{
double x=0;
double y=0;
std::cout<< qRoot(1, 5, 6, x, y);
                       return 0;
}
double qRoot(double a, double b, double c, double& bigRoot, double& smallRoot){
                           double hold;
                           hold=(-b+sqrt((b*b)-4.0*a*c))/2*a;
                           smallRoot=(-b-sqrt((b*b)-4.0*a*c))/2*a;
                           if (smallRoot>hold){
                                bigRoot=smallRoot;
                                smallRoot=hold;}
                                else{ bigRoot=hold;}
                                return smallRoot;
                                
                       }
Last edited on
But does it give the correct results?
This line:
 
    hold=(-b+sqrt((b*b)-4.0*a*c))/2*a;

still has one set of unnecessary parentheses (which are harmless) and also one set of parentheses missing (which is not harmless, as it changes the meaning of the expression).
Okay I updated the code again and removed a set of parentheses, I don't see the ones which are missing though.

The equation x^2+5x+6 is returning -2 and -3, which are the correct roots for just that equation, I'm not sure if it would work for all

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Example program
#include <iostream>
#include <string>
#include <cmath>
double qRoot(double a, double b, double c, double& bigRoot, double& smallRoot);
int main()
{
double x=0;
double y=0;
std::cout<< qRoot(1, 5, 6, x, y);
                       return 0;
}
double qRoot(double a, double b, double c, double& bigRoot, double& smallRoot){
                           double hold;
                           hold=(-b+sqrt(b*b-4.0*a*c))/2*a;
                           smallRoot=(-b-sqrt(b*b-4.0*a*c))/2*a;
                           if (smallRoot>hold){
                                bigRoot=smallRoot;
                                smallRoot=hold;}
                                else{ bigRoot=hold;}
                                return smallRoot;
                                
                       }
Try testing your program with a value for a which is not 1.
e.g.
a = 10
b = 1
c = -21

roots are 1.4 and -1.5
according to http://www.math.com/students/calculators/source/quadratic.htm

however your code gives
140 and -150

Okay I updated it again with parentheses around 2*a

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Example program
#include <iostream>
#include <string>
#include <cmath>
double qRoot(double a, double b, double c, double& bigRoot, double& smallRoot);
int main()
{
double x=0;
double y=0;
std::cout<< qRoot(10, 2, -21, x, y);
                       return 0;
}
double qRoot(double a, double b, double c, double& bigRoot, double& smallRoot){
                           double hold;
                           hold=(-b+sqrt(b*b-4.0*a*c))/(2*a);
                           smallRoot=(-b-sqrt(b*b-4.0*a*c))/(2*a);
                           if (smallRoot>hold){
                                bigRoot=smallRoot;
                                smallRoot=hold;}
                                else{ bigRoot=hold;}
                                return smallRoot;
                                
                       }
I think that's ok now, though the cout at line 10 only outputs one of the roots, not both.
Is this better? It shows both now, I removed the cout from the main and put it inside the function.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Example program
#include <iostream>
#include <string>
#include <cmath>
double qRoot(double a, double b, double c, double& bigRoot, double& smallRoot);
int main()
{
double x=0;
double y=0;
 qRoot(10, 2, -21, x, y);
                       return 0;
}
double qRoot(double a, double b, double c, double& bigRoot, double& smallRoot){
                           double hold;
                           hold=(-b+sqrt(b*b-4.0*a*c))/(2*a);
                           smallRoot=(-b-sqrt(b*b-4.0*a*c))/(2*a);
                           if (smallRoot>hold){
                                bigRoot=smallRoot;
                                smallRoot=hold;}
                                else{ bigRoot=hold;
                              std::cout<<bigRoot<<smallRoot;

}
    return smallRoot;
                       }
That looks like it works. However it's the wrong approach. In your opening post it says, "I'm learning about pass by reference".

Your code should make use of the two parameters passed by reference, and output their values in main() after calling the function.
How do I call the pass by reference functions in main? I tried it a bunch of different ways, but since it's not defined in main it's not working, and I'd assuming typing double& bigRoot; in main wouldn't work at all.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Example program
#include <iostream>
#include <string>
#include <cmath>
double qRoot(double a, double b, double c, double& bigRoot, double& smallRoot);
int main()
{
double x=0;
double& bigRoot;
double& smallRoot;
double y=0;
 std::cout<<qRoot(10, 2, -21, x, y);<<bigRoot<<smallRoot;
                       return 0;
}
double qRoot(double a, double b, double c, double& bigRoot, double& smallRoot){
                           double hold;
                           hold=(-b+sqrt(b*b-4.0*a*c))/(2*a);
                           smallRoot=(-b-sqrt(b*b-4.0*a*c))/(2*a);
                           if (smallRoot>hold){
                                bigRoot=smallRoot;
                                smallRoot=hold;}
                                else{ bigRoot=hold;

}
                       }
Last edited on
The previous version of the code was almost right. Passing by reference is actually pretty simple once you get the hang of it. Something like this:
1
2
3
4
5
6
7
8
int main()
{
    double x = 0;
    double y = 0;
    qRoot(10, 2, -21, x, y);
    std::cout << "x: " << x << "   y: " << y << std::endl;
    return 0;
}



Take a look at the tutorial page for a fuller explanation, and examples.

http://www.cplusplus.com/doc/tutorial/functions/
Last edited on
Let me suggest that you have qroot() return a bool that indicates whether the roots exist. Then, borrowing from Chervil's example, your main program can look something like this:
1
2
3
4
5
6
7
8
9
10
11
int main()
{
    double x = 0;
    double y = 0;
    if (qRoot(10, 2, -21, x, y)) {
        std::cout << "x: " << x << "   y: " << y << std::endl;
    } else {
        std::cout << "No real roots exist." << endl;
    }
    return 0;
}
Topic archived. No new replies allowed.