next up previous
Next: Shortcomings of the Code Up: The Code Previous: C++ code

Explanation of the Program

Here we explain some new features in the code

#include <cmath>

The header <cmath> is needed to define the identifier sqrt used later in the code. You will probably need this line in most of your code in this class.

// Compute roots of quadratic equation
// Physics 6720 example

Comments are ignored by the compiler. They start with //. You can also use the C-style comment /* comment */ as in

/* Compute roots of quadratic equation */
/* Physics 6720 example */
/* Compute roots of quadratic equation
   Physics 6720 example */
The liberal use of comments is good programming practice. It helps you and others understand what your code is doing.

  d = b*b - 4*a*c;
  signb = 1;

These are assignment statements and not simply equations. In an assignment statement a single variable name appears on the left and an expression appears on the right. The statement instructs the computer to evaluate the expression on the right and assign the result to the variable on the left. So the equal sign implies movement to the left.

Note: All variables in an expression must have been given previously assigned values. Here the variables a, b, and c are assigned values in the previous cin statement. It is a common mistake to forget to assign values to variables before using them. If you make this mistake, you might get very strange results.

Notice that C++ doesn't have a ``power of'' notation, so to square b we multiplied it out: b*b. For more complicated powers, one can use the C math library function pow(x,y) for $x^y$, but for low integer powers, explicit multiplication is more efficient.

In addition to simple assignments, C++ has compound assignment statements. For example

  x += y;
is an abbreviation for
  x = x + y;
Other compound assignments are -=, *=, and /=.

  if(b < 0)signb = -1;

This is a simple if statement. We are using it to make signb be $+1$ if b is positive and $-1$ if negative. The logic of this code is first to assign $+1$ and then correct it if b is negative.

The formal syntax for a simple if statement is

A logical expression is one that evaluates to true or false. A nonzero numeric value is considered to be true, and a zero value, false. If the expression is true, the statement is executed. Otherwise it is skipped. Here we are checking whether $b$ is less than zero. We use the relational "is less than" < operator. Here is a list of relational operators:
$<$ is less than
$>$ is greater than
$<=$ is less than or equal to
$>=$ is greater than or equal to
$==$ is equal to
$!=$ is not equal to
Writing a single equal sign instead of the double equal sign causes a great deal of trouble for beginners. The expression if(a = b) has an entirely different meaning from if(a == b). The former actually assigns the value of b to a and evaluates to true if b is nonzero and false if zero. The latter expression evaluates to true if a and b are equal and false if they are not, which is most likely what is intended.

Logical expressions can be combined with parentheses and logical operators to form more complex logical expressions. So to test whether $a$ and $b$ are both zero we do

  if((a == 0) && (b == 0)){
     cout << "Yes, a and b are both zero.";
The logical operators are
&& AND
|| OR

Returning to the code for solving a quadratic, we could have also determined the sign of $b$ with a simple if else pair:

  if(b < 0)signb = -1;
  else signb = 1;
In this case the statement following else is executed if the logical expression is false.

With braces we can have have several statements controlled by if and else:

  if(b < 0){
    signb = -1;
    cout << "b is negative.\n";
  else {
    signb = 1;
    cout << "b is nonnegative.\n";
In this case we have a block of statements to execute if the expression is true and a block to execute if it is false. We must use braces to enclose a block when it has more than one statement.

 s = -(b + sqrt(d)*signb)/2;

Here we use the math library sqrt function. The notation corresponds to what one expects algebraically: Take the square root of d and multiply the result by signb before adding to b. The outer parentheses force the addition to happen before dividing by 2 and reversing the sign.

There are a couple of subtleties about the order of calculation that often trip up beginners. The following expression gives an incorrect result for the root of the quadratic:

 x1 = -(b + sqrt(d)*signb)/2.*a;  // WRONG!
Here division by 2 happens first and the result is then multiplied by a, effectively putting a in the numerator. To divide by the product $2a$, it is necessary to use parentheses:
 x1 = -(b + sqrt(d)*signb)/(2.*a);  // correct

Another subtlety has to do with integer division. Suppose you had written

 x1 = -(1/2)*(b + sqrt(d)*signb)/a;  // WRONG!
This is mathematically correct, but computationally incorrect. Because of the parentheses, the integer division takes place before multiplication. A convention steeped in tradition requires that when division involves only integers the result must be given as an integer quotient with the remainder discarded. So (1/2) evaluates to zero, making the whole result mysteriously zero. Inserting a single decimal point is enough to cure the problem:
 x1 = -(1./2)*(b + sqrt(d)*signb)/a;  // correct
But it is best to be in the habit of always putting decimal points after integers in expressions that evaluate to a floating point result.
 x1 = -(1./2.)*(b + sqrt(d)*signb)/a;  // better

  x1 = s/a;
  x2 = c/s;

  cout << "Roots are \n" << x1 << " " << x2 << "\n";

Notice that one root is computed with one solution formula and the other with the other, as promised.

next up previous
Next: Shortcomings of the Code Up: The Code Previous: C++ code
Carleton DeTar 2007-08-17