CoSTARS Note #4:
More "int" Variables


1.  Practice

By now, you should be comfortable supplying all of the "green code" for a program.  To practice this, save and compile the following program:

public class SampleCode {
   public static java.util.Scanner scanner = new java.util.Scanner(System.in);
   public static void main(String[] args) {
                                    
       // this program does nothing!
                                    
   }
}
First, notice that this program does compile and does run.  Of course, it does nothing, but that's what we told it to do!  Now for the practice:

2.  String concatenation

Here we will learn a useful shortcut called string concatenation.  Say we have a variable "f" which represents the number of frogs on a log.  We may wish to display this information as such (if, say, f equals 10):
     There are 10 frogs on the log.
Here is the Java code to do this:
      System.out.print("There are ");
      System.out.print(f);
      System.out.println(" frogs on the log.");
We do this print/print/println pattern so often, it would be nice if there was a shorthand way to do this on one line.  Well, there is!  We can use the "+" operator to "add" strings together.  When we do this, the result is a new string that is just the first string followed by the second string.  For example, "abc" + "def" equals "abcdef".

This also works for a string and a number, so "abc" + 5 equals "abc5".  Java converted the number 5 into the string "5" for us, and then proceeded with adding two strings as above.  So?  Well, now we can use this to print our frog information with one statement:
      System.out.println("There are " + f + " frogs on the log.");

See how this works?  Java will convert whatever value f is assigned (say, 15) into a string (like "15"), then add that string to "There are " to get "There are 15", and then add that string to " frogs on a log." to get "There are 15 frogs on the log."  How convenient!

Now it's your turn.

3 Integer Division

Recall that an integer is a number with no decimal part.  So, 3, 4, and 5 are integers, but 3.14 is not an integer.  When Java divides one integer by another integer, the result is always an integer.  This can be confusing at first, but you will get used to it.

So, 4/2 equals 2, just as you would expect.  But what about 5/2?  In math, you learned that this equals 2.5 (that is, 2 and one-half).  But 5 and 2 are both integers, so the answer must be an integer, too.  So we would expect the answer to be either 2 or 3.  But which one?  You might expect Java to round the answer to the nearest integer, but this is not what it does!  Instead, it truncates the answer -- simply ignoring the decimal portion of the answer.  So 2.5 becomes 2, and so in Java 5/2 becomes 2.  See?

Now for some practice:

4.  The Remainder Operator (%)

So far, we have learned how to add, subtract, multiply, and divide integers.  Java also provides a remainder operator (%), where x%y returns the remainder when x is divided by y.  For example, when we divide 13 by 5 we get a remainder of 3.  So, 13%5 equals 3.  Similarly, 15%5 equals 0 and 201%5 equals 1.

Now for some practice:

So you know:  The remainder operator (%) is also called the modulus operator, or for short, just the mod operator.  Some programmers even read it this way:  so they would read "7%3" as "seven mod three".

5.  Overflow

As we have discussed, computers store all information as 1's and 0's.  For this reason, integers are usually stored using the binary or base 2 number system (with one small change to make it work better with negative numbers).  Also, for the past 20 years or so, most computers have used a "32-bit architecture", which means that integers are usually stored using 32 bits.  Java works this way -- it uses 32 bits to store its integers.

So?  Well, because of this, Java has a largest integer that it can store!  The largest integer is precisely 2,147,483,647, which is just over 2 billion.  Using "int" variables, Java cannot store numbers larger than this.

But what happens if your program includes math with an answer that is larger than 2 billion?  It turns out that Java simply computes the wrong answer and your program just keeps running.  This is known as overflow.  Here is an example:

      int x = 2000000000;    // x equals 2 billion
      System.out.println(x); // works fine
      int y = x + x;         // y should equal 4 billion
      System.out.println(y); // OVERFLOW!!!

Compile and run this code.  See what it does?  Two billion works fine, but 4 billion is larger than the largest integer, and so Java cannot store this value.  Instead, Java comes up with the value -294,967,296.  Never mind the details, the point is:  Java added 2 billion plus 2 billion and came up with a negative answer!  This is the result of overflow.

We can show that 2,147,483,647 is in fact the largest possible number with this simple program:

      int x = 2147483646;    // one less than the largest possible 32-bit integer
      x = x + 1;
      System.out.println(x); // works fine
      x = x + 1;
      System.out.println(x); // OVERFLOW

When you run this program, you can see that when you add 1 to 2,147,483,646, you get the expected answer of 2,147,483,647.   But when you add 1 to 2,147,483,647, you get a negative answer.  See?

6.  Operator Precedence

What happens when you enter "2+3*4" on most calculators?  Well, there are two possibilities.  Either the addition comes first, so the calculator would find that 2+3 equals 5, and then 5*4 equals 20, so the answer would be 20.  Or the multiplication comes first, so it would first find that 3*4 equals 12, and then 2+12 equals 14, so the answer would be 14.  Which is it?

On most calculators, the answer is 14.  Java works this way, too.  In Java, multiplication is performed before addition.

Now for some practice:

We can use parentheses to force Java to add two numbers before multiplying.  Java computes values in parentheses before other values.  So, while 2+3*4 equals 14, (2+3)*4 forces Java to add first, so we get 5*4, which is 20.

More practice:

We say that operators like addition (a+b) and multiplication (a*b) have precedence.  Multiplication has higher precedence than addition, so it comes first.  In general, Java computes operators with higher precedence before other operators.

There are more operators to consider.  Subtraction (a-b) has the same precedence as addition.  Division (a/b) has the same precedence as multiplication.   Here is some more practice:

What about the remainder (or modulus, or mod) operator?  It has the same precedence as multiplication and division.  Let's practice that:

7.  Operator Associativity

Java uses operator precedence to choose which operator to compute first.  What happens when two operators have the same precedence?  In the simplest case, what happens when the operators are the same?  In this case, for the operators we are considering, Java computes from left-to-right.  We call this the operator's associativity.  So, most Java operators have left-to-right associativity.

For example:  to compute "20/5/3", Java would first divide 20 by 5 to get 4, then divide 4 by 3 to get 1 (remember, this is integer division).  So the answer is 1.  If Java worked the other way, it would first divide 5 by 3 to get 1 (again, this is integer division), and then divide 20 by 1 to get 20.  Of course, we can force Java to do this with parentheses, but otherwise Java will work left-to-right and get 1 for the answer.  Let's confirm this as follows:

      System.out.println(20/5/3);
      System.out.println(20/(5/3));

Compile this code and run it.  See how it clearly shows that Java has left-to-right association (at least for division)?

Now for some practice:

8.  Increment and Decrement Statements

Adding one to a variable (or incrementing it) is such a common operation that Java provides a shortcut for it:  you can replace the statement "x = x + 1;" with "x++;".  Consider the following:

      int x = 1;
      System.out.println(x);  // prints 1
      x = x + 1;              // add one to x (increment it)
      System.out.println(x);  // prints 2
      x++;                    // increment x
      System.out.println(x);  // prints 3

Compile this code and run it.  See how it shows that "x++" adds one to x?

Note that you can use "++x;" as well as "x++;".  As statements, these have the same effect of adding one to x.  Let's verify this:

      int x = 1;
      System.out.println(x);  // prints 1
      x = x + 1;              // add one to x (increment it)
      System.out.println(x);  // prints 2
      x++;                    // increment x
      System.out.println(x);  // prints 3

      ++x;                    // also increment x
      System.out.println(x);  // prints 4


Compile this code and run it.  See how it shows that "++x" also adds one to x?

Subtracting one from a variable (or decrementing it) is also common, and so "x = x - 1;" can be replaced by either "--x;" or "x--;".  Again, let's confirm this:

      int x = 4;
      System.out.println(x);  // prints 4
      x = x - 1;              // subtract one from x (decrement it)
      System.out.println(x);  // prints 3
      x--;                    // decrement x
      System.out.println(x);  // prints 2

      --x;                    // also decrement x
      System.out.println(x);  // prints 1


Compile this code and run it.  See how it shows that "--x" and "x--" both subtract one from x?

9.  Increment and Decrement Expressions

Besides being used as statements, the increment (++) and decrement (--) operators can be used within expressions.  This is complicated, however, and should generally be avoided.  However, it is common enough that you should know how it works so you can understand Java code that uses this technique.

We start with this example:

      int x = 4;
      int y = ++x;
      System.out.println(x + "," + y); // prints 5,5 (and not 4,5)

The first line is clear -- it sets x equal to 4.  But what does the second line do?  It first increments x, to get 5, and then sets y equal to this value.  This is not the same as setting y equal to (x + 1).  The difference is that here x is actually changed, too.  So x and y both equal 5.  Compile and run the code to confirm this.

To further stress this point, let's add the line "y = x + 1;", as such:

      int x = 4;
      int y = ++x;
      System.out.println(x + "," + y); // prints 5,5
      y = x + 1;
      System.out.println(x + "," + y); // prints 5,6

Compile this code and run it.  See how it shows that "y = ++x" and "y = x + 1" are not the same?  Both set y equal to x plus one, but the first statement also increments x, whereas the second statement has no effect on x.

We see that "++x" adds one to value of x and then uses that value.  We call this pre-incrementing.  The other form of the increment operator is written as "x++".  Notice that the "++" is written after the variable x.  The "x++" form is called post-incrementing.  It still adds one to x, but it uses the old value of x.  For example:

      int x = 4;
      int y = x++;                     // post-increment!
      System.out.println(x + "," + y); // prints 5,4 (not 5,5)

Compile this code and run it.  See how it shows that "y = x++" still adds one to x (which ends up with 5 and not 4), but it uses the old value of x (4) and not the new value (5), so y equals 4 and not 5?  To review, this example contrasts x++ and ++x:

      int x,y;
      x = 4;
      y = ++x;                         // pre-increment!
      System.out.println(x + "," + y); // prints 5,5
      x = 4;
      y = x++;                         // post-increment!
      System.out.println(x + "," + y); // prints 5,4

Compile this code and run it.  See how it shows that ++x pre-increments x and x++ post-increments x?  See how these differ?

Note that when we use "x++" or "++x" in statements (on lines by themselves), they are the same.  They only differ when used in expressions.  For example:

      int x = 4;
      System.out.println(x);  // prints 4
      x++;                    // increment statement using x++
      System.out.println(x);  // prints 5
      ++x;                    // increment statement using ++x
      System.out.println(x);  // prints 6

We can use the increment operator in arithmetic expressions, too.  For example:

      int x = 4;
      int y = ++x * 3;
      System.out.println(x + "," + y);  // prints 5,15

Compile this code and run it.  Be sure you understand what is happening here.  On the second line, the value of x is first incremented, so x equals 5, and then this value (5) is multiplied by 3.  So y equals 15 (5*3) and not 12 (4*3).

By contrast, here is the same example, only here we use "x++" instead of "++x":

      int x = 4;
      int y = x++ * 3;
      System.out.println(x + "," + y);  // prints 5,12

Compile this code and run it.  What is happening?  On the second line, the value of x is first obtained (4), and then it is incremented, so x equals 5, and but the old value (4) is multiplied by 3.  So y equals 12 (4*3) and not 15 (5*3).

Note that "--x" (pre-decrement) and "x--" (post-decrement) work in the same way:

      int x, y;
      x = 4;
      y = --x * 3;                      // pre-decrement
      System.out.println(x + "," + y);  // prints 3,9
      x = 4;
      y = x-- * 3;                      // post-decrement
      System.out.println(x + "," + y);  // prints 3,12

Compile this code and run it.  Be sure you understand why pre-decrementing and post-decrementing produce different results, even though both expressions decrement x by one.

Using the ++ and -- operators as statements is straightforward, and is a common practice.  However, using the ++ and -- operators in expressions (like y = ++x * 3) can be confusing!  For this reason, you generally should not do it.  You can generally avoid this practice and simply add another line to perform the increment or decrement.  That is, you can replace:
      y = --x * 3;
with:
      --x;
      y = x * 3;

And you can replace:
      y = x-- * 3;
with:
      y = x * 3;
      --x;
Now there is no confusion!  So you should take this approach in your code.  However, you still must be able to understand other programmers' code that uses pre/post increment/decrement operators in confusing ways.

10.  Assignment Operators

We just saw how the ++ and -- operators can be used to add or subtract one to a variable, either as a standalone statement or within an expression.  What if we want to add or subtract some value besides one?  Say, two?

As you may have guessed, Java provides a shortcut for this as well using the += and -= operators.  Consider this line:
      x = x + 2;
This is exactly the same as:
      x += 2;

So we see that "+=" can be used to add a value to a variable.  Similarly, "-=" can subtract a value.  For example:

      int x = 4;
      System.out.println(x); // prints 4
      x += 2;
      System.out.println(x); // prints 6
      x -= 4;
      System.out.println(x); // prints 2

Compile this code and run it.  See how it shows how += and -= work?

As with ++ and --, you can use the += and -= operators both as statements (which is a good idea) and in expressions (which is not).  For example, here we use the += and -= operators in expressions:

      int x, y;
      x = 4;
      y = (x += 2) * 2;                 // add 2 to x, then use that value
      System.out.println(x + "," + y);  // prints 6,12
      x = 4;
      y = (x -= 2) * 2;                 // subtract 2 from x, then use that value
      System.out.println(x + "," + y);  // prints 2,4

Besides += and -=, Java provides several other assignment operators:

      x += 2    is the same as    x = x + 2
      x -= 2   
is the same as    x = x - 2
      x *= 2   
is the same as    x = x * 2
      x /= 2   
is the same as    x = x / 2
      x %= 2   
is the same as    x = x % 2

Now for some practice:

11.  More Practice