Lecture 7

  1. Announcements
  2. The "real" syntax of the if statement
  3. More on boolean expressions
  4. Base types other than int and boolean


Announcements

Please don't forget lab 3 is due Thursday (September 19).

Remember that the TAs are in the lab much of the day!!! See them for help, but not too much.


The "real" syntax of the if-statement

Last time we saw several examples of the if-statement and other forms (such as the if-else). You've also used these (very successfully) in lab. Let's take a moment now to look at the "real" syntax of the if-statement. The real syntax of the if-statement is:

   if (boolean expression)
      statement-to-execute-if-boolean-expression-true
   else
      statement-to-execute-if-boolean-expression-false

As we've already seen, the boolean expression must appear in parentheses. We've also seen that the else part is optional. The indenting I've given here is a style suggestion. It is unnecessary from Java's perspective, but is very important for readability, because it helps to indicate that this is not simply a straight line of code in which everything is necessarily executed.

Now let's examine

      statement-to-execute-if-boolean-expression-true

      statement-to-execute-if-boolean-expression-false

Each of these can be:

Last time we said that the form was:

   if (boolean expression)
   {
      statement-to-execute-if-boolean-expression-true
   }
   else
   {
      statement-to-execute-if-boolean-expression-false
   }

If it's the case that

      statement-to-execute-if-boolean-expression-true

is just a primitive instruction, you can drop the curly braces. The same is true for the else part. We recommend keeping the braces, however. One good reason is that if you decide to make your statements more complex later, you'll already be set with the braces in the right places. A common mistake is to add lines and forget to add the braces!

There's one exception to our "use the braces" rule. That's the case where the else part is another if-statement. Consider the final version of the Pong program that we discussed last time. In that version we determined how to move the paddle as follows:

    if (point.getX() < COURT_LEFT)
    {
       // move paddle to left edge ..
    }
    else if (point.getX() > COURT_LEFT + COURT_WIDTH - PADDLE_WIDTH)
    {
       // move paddle to right edge ..
    }
    else
    {
       // move paddle to mouse ..
    }

We didn't say:

    if (point.getX() < COURT_LEFT)
    {
       // move paddle to left edge ..
    }
    else
    {
       if (point.getX() > COURT_LEFT + COURT_WIDTH - PADDLE_WIDTH)
       {
          // move paddle to right edge ..
       }
       else
       {
          // move paddle to mouse ..
       }
   }

This second way would be completely legal, and it follows our rule for always using braces. But in this second case:

  1. The extra braces are distracting; and
  2. The fact that we're considering a three-way alternative isn't immediately clear.

We prefer the first way (dropping the extra braces and indenting all the options at the same level) because it makes it more clear to the reader that a three-way split is happening.


More on boolean expressions

In the final version of the Pong game, we first checked if the paddle was off of the left edge, then if it was off the right edge, and if neither of those was true then it must have been between the edges.

Suppose the first thing that we wanted to do was to check if it was between the edges? Because we need it to be inside the left edge and inside the right edge, we need to write an expression to determine if both of these are true. In Java we use && betwen two boolean expressions to indicate that both must be true.

In order to ensure that point is between the left and right edges of the court we would need to write a statement as below:

    if (point.getX() > COURT_LEFT && 
        point.getX() < COURT_LEFT + COURT_WIDTH - PADDLE_WIDTH)
    {...}

For the code in the if statement to be executed, it is necessary for the boolean expression to the left of the && (checking to see if point is to the right of COURT_LEFT) to be true as well as the expression on the right.

Unfortunately computer programming languages do not usually allow one to combine two inequalities as one, as in the expression 1 < x < 10. Instead one must write this out the long way as 1 < x && x < 10.

Why can't we combine inequalities into one expression in Java? Why can't we say

   1 < x < 10

The answer is that < is an operator which produces a value. When Java process a line like this one, it evaluates

   1 < x

first, getting the result true (if x has a value like 9, for example). Then it compares the result (which is true) to 10. This makes no sense! So while it may seem inconvenient to write complex conditionals in the way that we have to write them, it really makes perfect sense.

Just as Java uses && to represent the logical and operation, it uses || to represent the logical or. The operation || is used in Java to determine whether at least one of two expressions is true. Thus x < 5 || x > 20 will be true if x is less than 5 or if x is greater than 20. An expression of the form bexp1 || bexp2 will be true if either or both of bexp1 and bexp2 are true.

Note that not every expression is evaluated strictly left to right. There is a set of precedence rules that specify the order in which sub-parts of an expression should be evaluated:


Base types other than int and boolean

Java includes four commonly used numeric types:

(There are others, but we won't discuss them here.)

The types int and long both represent integers. Type int represents numbers between about -2 * 109 and 2 * 109, while long represents integers up to about 1019.

Numbers written with decimal points are represented by the types float and double. The type float only retains about 7 digits of precision, so we usually use double instead. Type double has about 15 digits of precision and can represent numbers up to about 10308 and as small as 10-308. These numbers can be written either simply with a decimal point, e.g., 4.735, or in scientific notation, e.g., 5.146E+47, representing 5.146*1047.

Because of the way many of the Java libraries are written we will tend to use type int for integers and double for numbers with decimal points. Occasionally we will use long when we need to represent more digits with integers, but we will find no need to use float in this course.

Like int, the type double supports operations +, -, *, and /, but does not have an operation corresponding to %. The results of applying these operators to doubles is an answer which is also a double. Thus 3.0 / 2.0 = 1.5.

If an arithmetic operator has one operand with type int and the other with type double, the result will be a double. Basically what happens is that Java recognizes that the two operands are of different types (which it is not happy about), and thus attempts to make them be of the same type. The simplest thing, from Java's point of view is to convert int's to double's, as no loss of precision results. As we saw earlier, if both operands are of type int, the result will also be of type int.

One must be careful in performing divisions to be aware of the types of the operands, as the results may differ depending on their types. Thus 3 / 2 = 1, while 3.0 / 2.0 = 3.0 / 2 = 3 / 2.0 = 1.5.