Help with logic on quadratic formula (hw)

Maybe I don't understand complex numbers well enough to explain them to a computer...

I'm writing this program that should be able to figure out both real and complex answers to the quadratic formula, given a, b and c. I figured out how to the real numbers without trouble, but I'm having trouble thinking up a way to code complex answers in.

Sample code looks like this:

Quadratic equation solver:
Enter a: 1
Enter b: 2
Enter c: 10
There are two complex solutions: -1+3i and –1-3i

What I've got below is this (just trying to cout the answers for now, until the logic is good). It's messy with a lot of superfluous variable right now, but only really looking for a logic solution. Any pointers much appreciated!

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
49
50
51
52
53
54
55
56
57
#include <iostream>
using namespace std;
#include <iostream>
#include <cmath>
using namespace std;

void findX(double, double, double);
void findCompX (double, double, double);

int main()
{
	double a, b, c, x;
	float answer;
	
	cout<<"Enter a value for a: ";
	cin>>a;
		while (a==0.0){
			cout<<"'a' cannot equal zero, the equation will be undefined. Enter a non-zero value.";
			cin>>a;
			}
	cout<<"Enter a value for b: ";
	cin>>b;
	cout<<"Enter a value for c: ";
	cin>>c;
	
	if ((sqrt ((b*b) -4*a*c)) > 0) {
		findX (a,b,c);	
	}
	
	else if ((sqrt ((b*b) -4*a*c)) < 0){
		findCompX(a, b, c);
	}

	return 0;
}

void findX (double a, double b, double c){
	
	float x1, x2;
	
	x1 = (-b + (sqrt ((b*b) -4*a*c))) /2*a;
	x2 = (-b - (sqrt ((b*b) -4*a*c))) /2*a;
	
	cout << x1 << "." << x2;
}

void findCompX (double a, double b, double c){
	
	double posVal;
	
	posVal = sqrt (-1*((b*b) -4*a*c));
	
	cout << posVal;
}


1. Discriminant logic
The solution to a quadratic equation becomes complex once the discriminant is less than zero.
The discriminant is b*b - 4*a*c, not sqrt(b*b - 4*a*c). The discriminant is what needs to be checked to see if it's below zero, not the square root of the discriminant; the point is preventing the operation of sqrt on a negative number in the first place.

2. Order of operations
x1 = (-b + (sqrt ((b*b) -4*a*c))) /2*a;
This is slightly wrong. When you do something/2*a, you are dividing something by 2, and then multiplying the result by a. Use parentheses:
x1 = (-b + (sqrt ((b*b) -4*a*c))) /(2*a);

3. If-else logic with comparisons
Doing if ( A > 0) { ... } else if (A < 0) { ... } is not only redundant, but does not account for when A == 0.

Simplify and correct your logic to:
1
2
3
4
5
6
if (b*b -4*a*c >= 0) {
	findX (a,b,c);	
}	
else {
	findCompX(a, b, c);
}


4. Complex arithmetic
Once you know you're in the complex plane, you need to divide up the logic into its real and imaginary parts. Multiplying the discriminant by -1 if the discriminant less than zero is okay, but you need to follow that up with a modified form of the full formula.

for n < 0, sqrt(n) = i * sqrt(-n).
You still need to apply the full formula, BUT you now need to split it into its real and imaginary components.

The real part will be -b / (2a) for both roots, because sqrt(negative) is purely imaginary.
The imaginary part will be (plus or minus) sqrt(-discriminant) / (2a).

print it like this
1
2
3
4
5
double x_real = // ...
double x_imaginary = // ...
cout << "There are two complex solutions: " << 
  x_real << " + " << x_imaginary << "i and " <<
  x_real << " - " << x_imaginary << "i" << endl;


5. You're mixing floats with doubles (last and least)
Either one is fine for your purposes (you're not doing high-precision scientific computing), but stick with one. I would suggest double simply because that is the default type when you write 0.0 in C++. Use floats if you need to interact with another library/API (such as OpenGL) that needs input as floats.
Last edited on
c++ has a built in complex type. If you were not told to explicitly avoid it, just use that and save a lot of trouble trying to code around it. Besides, you can show off to your professor... they love to get 'one of those' students :P

I find it best to think of complex numbers as a 2-d vector. Its the same as on paper, though. You just need to store 2 values, a real and imaginary part, and basic functions to add/sub/mul/div etc them depending on the program.
Last edited on
Thank you!

This is early in the semester, and I have not yet learned vectors. Ganado's explanation is super helpful. This is what I'm turning in:

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
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <iostream>
#include <cmath>
using namespace std;

void findX (float, float, float);
void findCompX (float, float, float);

int main()
{
	float a, b, c, x;
	
	cout<<"Enter a value for a: ";
	cin>>a;
		while (a==0.0){
			cout<<"'a' cannot equal zero, the equation will be undefined. Enter a non-zero value.";
			cin>>a;
			}
	cout<<"Enter a value for b: ";
	cin>>b;
	cout<<"Enter a value for c: ";
	cin>>c;
	
	if (b*b -4*a*c >= 0){
		findX (a,b,c);
	}
	
	else {
		findCompX (a, b, c);
	}
	
	return 0;
}

void findX (float a, float b, float c){
	
	float x1, x2;
	
	x1 = (-b + (sqrt ((b*b) -4*a*c))) / (2*a);
	x2 = (-b - (sqrt ((b*b) -4*a*c))) / (2*a);
	
	if (x2 == x1){
		cout << "There is one real solution: " << x1 << endl;
	}
	
	else{
		cout << "There are two real solutions: " << x1 << " and " << x2 << endl;
	}
	
}

void findCompX (float a, float b, float c){
	
	float realX, compX, posVal;
	
	posVal = (-1*((b*b) -4*a*c));
	
	realX = -b / (2*a);
	compX = sqrt (posVal)/2*a;
	
	cout << "There are two complex solutions: " << realX << " + " << compX << "i" << " and " <<realX << " - " << compX << "i" << endl;
}
Topic archived. No new replies allowed.