Week 5: if, else, and Quadratic Roots
Odd or even with and without else, positive, negative, or zero with a nested if, and the roots of a quadratic equation in all three discriminant cases: why else exists, why the remainder test is == 0, and why a double is never compared with == 0.
Decisions as Statements
Week 3 made decisions inside expressions. Week 5 makes them with if, else, and nesting, the chapter 5 statements, and then puts the whole toolkit to work on the one program every C lab in the country includes: the roots of a quadratic equation. The first two programs are deliberately small so that the shape of the statement is the whole lesson. The third is where the shape earns its keep.
Program 1: Odd or Even, With and Without else
Print NUMBER IS EVEN or NUMBER IS ODD. The lab asks for it twice: once with else, once without, and the comparison is the point.
Algorithm:
- Start.
- Read the integer n.
- If n leaves no remainder on division by 2, print NUMBER IS EVEN.
- Otherwise print NUMBER IS ODD.
- Stop.
Now the same decision without else. Two independent if statements each test the condition, one for each outcome:
Both print the same thing for every input, and the second one is worse. It evaluates n % 2 twice, and more importantly the two conditions are only exhaustive because you wrote them to be: change the second test to n % 2 == 1 and a negative odd number, whose remainder is -1, matches neither if and prints nothing. else guarantees exactly one branch runs, with no second condition to keep in step with the first. That sentence is the answer to "why use else" in the viva.
Note the test in the with-else version is n % 2 == 0, never n % 2 == 1 for the odd case. Week 1 established that the remainder of a negative number is negative, so -3 % 2 is -1; testing for zero remainder is the only version that is right for every integer.
Program 2: Positive, Negative, or Zero with Nested if
Algorithm:
- Start.
- Read the integer n.
- If n is greater than 0, print NUMBER IS POSITIVE.
- Otherwise, if n is less than 0, print NUMBER IS NEGATIVE.
- Otherwise, print NUMBER IS ZERO.
- Stop.
The inner if sits inside the outer else, so it only runs once positive has been ruled out, which is why its own else can say "zero" without testing for it. This is the nesting the syllabus names, and chapter 5's else if ladder is the same structure with the inner braces removed and the if pulled up onto the else line. Write it nested in the record, since that is what was asked, and know that the ladder is the same program.
Program 3: The Roots of a Quadratic Equation
For ax² + bx + c = 0, the discriminant d = b² − 4ac decides everything: two distinct real roots when d > 0, one repeated root when d = 0, and a pair of complex roots when d < 0. The program has to handle all three, and refuse a = 0, which is not a quadratic at all.
Algorithm:
- Start.
- Read a, b, and c.
- If a is 0, print that this is not a quadratic equation and stop.
- Compute d = b × b − 4 × a × c.
- If d is greater than 0, the roots are (−b ± √d) / 2a; print both.
- Otherwise, if d is 0, the single root is −b / 2a; print it.
- Otherwise, the roots are −b / 2a ± (√−d / 2a) i; print the real and imaginary parts.
- Stop.
The three test inputs to keep in the record: 1 -5 6 gives 3.00 and 2.00, 1 2 1 gives the repeated root -1.00, and 1 1 1 gives -0.50 + 0.87i and -0.50 - 0.87i. Then 0 2 1 for the refusal.
Two decisions in this program are the ones the lab manual's version gets wrong. The first is the comparison with zero. d is a double, and chapter 3's rule is that floating-point values are never compared with ==: b * b - 4.0 * a * c for coefficients typed as decimals can land at 0.0000000000000002 when the algebra says 0. So the program tests against a tolerance, EPSILON, on both sides: clearly positive, within the tolerance of zero, and otherwise negative. The same tolerance decides whether a is zero. fabs is the absolute value of a double, from <math.h>.
The second is the ladder itself. Three mutually exclusive cases fit an if, else if, else chain exactly, one test per boundary and the last case free, which is the week's nested-if structure again with a real job. Order matters: the positive test comes first so that the equality test only runs on values already known not to be clearly positive.
In the complex branch, the imaginary part is sqrt(-d), the square root of a positive number, and the two roots differ only in the sign between the parts, so the program computes each part once and prints it twice. Dividing by fabs(2.0 * a) rather than 2.0 * a keeps imag positive when a is negative; the roots are the same pair either way, and it stops the output reading + -0.87i. sqrt needs <math.h>, and on your own compiler -lm at the end of the gcc line; the sandbox links it.
Key Takeaways
ifwithelseruns exactly one of two branches; two separateifstatements only do that if their conditions are kept exhaustive by hand.- Test evenness with
n % 2 == 0, nevern % 2 == 1, because a negative odd number has remainder -1. - Nesting an
ifinside anelsenarrows the cases one step at a time; theelse ifladder is the same structure flattened. - The discriminant b² − 4ac sorts a quadratic into distinct, equal, or complex roots; a = 0 is not a quadratic and is refused first.
- Compare a
doublewith zero through a tolerance usingfabs, never with==. - A chain of mutually exclusive cases is an
if,else if,elseladder, tested in an order that makes each later test simpler.
How did you find this lesson?
Your rating helps us improve the content.
Create an account to track your progress and access interactive exercises. Already have one? Sign in.
Practice Exercises
Odd or Even with if and else
Read an integer and print NUMBER IS EVEN or NUMBER IS ODD on one line, using an if statement with an else branch. Test for evenness with a zero remainder on division by 2, so that negative numbers are classified correctly too. If the integer cannot be read, print invalid input and return 1.
Positive, Negative, or Zero with Nested if
Read an integer and print NUMBER IS POSITIVE, NUMBER IS NEGATIVE, or NUMBER IS ZERO on one line. Use a nested if statement: an outer if tests for positive, and an if inside its else branch separates negative from zero. If the integer cannot be read, print invalid input and return 1.
The Roots of a Quadratic Equation
Read the coefficients a, b, and c of ax^2 + bx + c = 0 as real numbers and print its roots. If a is zero (within a tolerance of 1e-9), print not a quadratic equation and return 1. Otherwise compute the discriminant d = b*b - 4ac and use an if, else if, else ladder with the same tolerance: when d is greater than 1e-9 print roots are real and distinct, then root1 = (-b + sqrt(d)) / 2a and root2 = (-b - sqrt(d)) / 2a on two lines; when d is within 1e-9 of zero print roots are real and equal, then root = -b / 2a; otherwise print roots are complex, then root1 = real + imagi and root2 = real - imagi, where real = -b / 2a and imag = sqrt(-d) / |2a|, so that imag is always positive and the sign printed between the parts is the sign of the root. Every value is printed to two decimal places in the forms root1 = 3.00, root = -1.00, root1 = -0.50 + 0.87i, and root2 = -0.50 - 0.87i. If the three numbers cannot be read, print invalid input and return 1.
Lesson Discussion
Share your thoughts and questions
No comments yet. Be the first to share your thoughts!