Assignment, Increment and Decrement Operators

In reality almost nobody writes for loops like we did in the previous sections. They would almost certainly use the increment or decrement operators instead. There are two of these, ++ and -- and they work like this.

//Count to ten

class CountToTen  {

  public static void main (String args[]) {
    int i;
    for (i=1; i <=10; i++) {
      System.out.println(i);
    }
    System.out.println("All done!");

}

}
//Count to ten??

class BuggyCountToTen  {

  public static void main (String args[]) {
    int i;
    for (i=1; i <=10; i--) {
      System.out.println(i);
    }
    System.out.println("All done!");

  }

}

When we write i++ we’re using shorthand for i = i + 1. When we say i-- we’re using shorthand for i = i - 1. Adding and subtracting one from a number are such common operations that these special increment and decrement operators have been added to the language. They also allow the compiler to be smarter about certain optimizations on some CPU architectures, but mainly they make code easier to write and read.

However what do you do when you want to increment not by one but by two? or three? or fifteen? We could of course write i = i + 15 but this happens frequently enough that there’s another short hand for the general add and assign operation, +=. We would normally write this as i += 15. Thus if we wanted to count from 0 to 20 by two’s we’d write:

class CountToTwentyByTwos  {

  public static void main (String args[]) {
    int i;
    for (i=0; i <=20; i += 2) {
      System.out.println(i);
    }
    System.out.println("All done!");

 } //main ends here

}

As you might guess there is a corresponding -= operator. If we wanted to count down from twenty to zero by twos we could write:

class CountToZeroByTwos  {

  public static void main (String args[]) {
    int i;
    for (i=20; i >= 0; i -= 2) {
      System.out.println(i);
    }
    System.out.println("All done!");

  }

}

You should note that we also had to change the initialization and test components of the for loop to count down instead of up.

There are also *= and /= operators that multiply and divide by their right hand sides before assigning. In practice you almost never see these because of the speed at which variables making use of them go to either zero or Inf. If you don’t believe me consider the following cautionary tale.

Many centuries ago in India a very smart man is said to have invented the game of chess. This game greatly amused the king, and he became so enthralled with it that he offered to reward the inventor with anything he wished, up to half his kingdom and his daughter’s hand in marriage.

Now the inventor of the game of chess was quite intelligent and not a little greedy. Not being satisfied with merely half the kingdom, he asked the king for the following gift:

“Mighty King,” he said, “I am but a humble man and would not know what to do with half of your kingdom. Let us merely calculate my prize as follows. Put onto the first square of the chessboard a single grain of wheat. Then onto the second square of the chessboard two grains, and onto the third square of the chessboard twice two grains, and so on until we have covered the board with wheat.”

Upon hearing this the king was greatly pleased for he felt he had gotten off rather cheaply. He rapidly agreed to the inventor’s prize. He called for a bag of wheat to be brought to him, and when it arrived he began counting out wheat. However he soon used up the first bag and was not yet halfway across the board. He called for a second, and a third, and more and more, until finally he was forced to admit defeat and hand over his entire kingdom for lack of sufficient wheat with which to pay the inventor.

How much wheat did the king need? Let’s try to calculate it. Although we won’t use physical wheat, we will soon find ourselves in the same dire straits as the king. Remember that a chessboard has 64 squares.

class CountWheat  {

  public static void main (String args[]) {

    int i, j, k;

    j = 1;
    k = 0;

    for (i=1; i <= 64; i++) {
      k += j;
      System.out.println(k);
      j *= 2;
    }
    System.out.println("All done!");

  }

}

We can improve our results slightly (but only slightly) by changing our ints to longs like so:

class CountWheat {

  public static void main (String args[]) {

    long i, j, k;

    j = 1;
    k = 0;

    for (i=1; i <= 64; i++) {
      k += j;
      System.out.println(k);
      j *= 2;
    }
    System.out.println("All done!");

  }

}

A long is an integer type variable that can hold up to 9,223,372,036,854,775,807. However even that isn’t enough to count how much wheat the king owed. Let’s try using a double instead, the largest type of all.

class CountWheat {

  public static void main (String args[]) {

  int i;
  double j, k;

  j = 1.0;
  k = 0.0;

  for (i=1; i <= 64; i++) {
      k += j;
      System.out.println(k);
      j *= 2;
  }
  System.out.println("All done!");

}

}

A double can hold a number as large as 1.79769313486231570e+308. That turns out to be large enough to count the king’s debt which comes to 1.84467e+019 grains of wheat, give or take a few billion grains. That’s a lot of wheat.

Exercises
  1. Would a float be big enough to count how many grains of wheat the king owes?
  2. Why isn’t there a ** or a // operator?

Comments are closed.