Chapter 7

Numbers and Types

In This Chapter

arrow Processing whole numbers

arrow Making new values from old values

arrow Understanding Java’s more exotic types

Not so long ago, people thought computers did nothing but big, number-crunching calculations. Computers solved arithmetic problems, and that was the end of the story.

In the 1980s, with the widespread use of word-processing programs, the myth of the big metal math brain went by the wayside. But even then, computers made great calculators. After all, computers are very fast and very accurate. Computers never need to count on their fingers. Best of all, computers don’t feel burdened when they do arithmetic. I hate ending a meal in a good restaurant by worrying about the tax and tip, but computers don’t mind that stuff at all. (Even so, computers seldom go out to eat.)

Using Whole Numbers

Let me tell you, it’s no fun being an adult. Right now I have four little kids in my living room. They’re all staring at me because I have a bag full of gumballs in my hand. With 30 gumballs in the bag, the kids are all thinking “Who’s the best? Who gets more gumballs than the others? And who’s going to be treated unfairly?” They insist on a complete, official gumball count, with each kid getting exactly the same number of tasty little treats. I must be careful. If I’m not, then I’ll never hear the end of it.

With 30 gumballs and 4 kids, there’s no way to divide the gumballs evenly. Of course, if I get rid of a kid, then I can give 10 gumballs to each kid. The trouble is, gumballs are disposable; kids are not. So my only alternative is to divvy up what gumballs I can and dispose of the rest. “Okay, think quickly,” I say to myself. “With 30 gumballs and 4 kids, how many gumballs can I promise to each kid?”

I waste no time in programming my computer to figure out this problem for me. When I’m finished, I have the code in Listing 7-1.

Listing 7-1: How to Keep Four Kids from Throwing Tantrums

class KeepingKidsQuiet {

    public static void main(String args[]) {

        int gumballs;

        int kids;

        int gumballsPerKid;

      

        gumballs = 30;      

        kids = 4;

        gumballsPerKid = gumballs / kids;

      

        System.out.print(“Each kid gets “);

        System.out.print(gumballsPerKid);

        System.out.println(“ gumballs.”);

    }

}

A run of the KeepingKidsQuiet program is shown in Figure 7-1. If each kid gets seven gumballs, then the kids can’t complain that I’m playing favorites. They’ll have to find something else to squabble about.

Figure 7-1: Fair and square.

9780470371749-fg0701.tif

At the core of the gumball problem, I’ve got whole numbers — numbers with no digits beyond the decimal point. When I divide 30 by 4, I get 71⁄2, but I can’t take the 1⁄2 seriously. No matter how hard I try, I can’t divide a gumball in half, at least not without hearing “my half is bigger than his half.” This fact is reflected nicely in Java. In Listing 7-1, all three variables (gumballs, kids, and gumballsPerKid) are of type int. An int value is a whole number. When you divide one int value by another (as you do with the slash in Listing 7-1), you get another int. When you divide 30 by 4, you get 7 — not 71⁄2. You see this in Figure 7-1. Taken together, the statements

gumballsPerKid = gumballs/kids;

System.out.print(gumballsPerKid);

put the number 7 on the computer screen.

Reading whole numbers from the keyboard

What a life! Yesterday there were 4 kids in my living room, and I had 30 gumballs. Today there are 6 kids in my house, and I have 80 gumballs. How can I cope with all this change? I know! I’ll write a program that reads the numbers of gumballs and kids from the keyboard. The program is in Listing 7-2, and a run of the program is shown in Figure 7-2.

Listing 7-2: A More Versatile Program for Kids and Gumballs

import java.util.Scanner;

class KeepingMoreKidsQuiet {

    public static void main(String args[]) {

        Scanner myScanner = new Scanner(System.in);

        int gumballs;

        int kids;

        int gumballsPerKid;

      

        System.out.print

            (“How many gumballs? How many kids? “);

         

        gumballs = myScanner.nextInt();      

        kids = myScanner.nextInt();

      

        gumballsPerKid = gumballs / kids;

      

        System.out.print(“Each kid gets “);

        System.out.print(gumballsPerKid);

        System.out.println(“ gumballs.”);

    }

}

Figure 7-2: Next thing you know, I’ll have 70 kids and 1,000 gumballs.

9780470371749-fg0702.tif

You should notice a couple of things about Listing 7-2. First, you can read an int value with the nextInt method. Second, you can issue successive calls to Scanner methods. In Listing 7-2, I call nextInt twice. All I have to do is separate the numbers I type by blank spaces. In Figure 7-2, I put one blank space between my 80 and my 6, but more blank spaces would work as well.

This blank space rule applies to many of the Scanner methods. For example, here’s some code that reads three numeric values:

gumballs = myScanner.nextInt();

costOfGumballs = myScanner.nextDouble();

kids = myScanner.nextInt();

Figure 7-3 shows valid input for these three method calls.

Figure 7-3: Three numbers for three Scanner method calls.

9780470371749-fg0703.tif

What you read is what you get

When you’re writing your own code, you should never take anything for granted. Suppose that you accidentally reverse the order of the gumballs and kids assignment statements in Listing 7-2:

//This code is misleading:

System.out.print(“How many gumballs? How many kids? “);

kids = myScanner.nextInt();      

gumballs = myScanner.nextInt();

Then, the line How many gumballs? How many kids? is very misleading. Because the kids assignment statement comes before the gumballs assignment statement, the first number you type becomes the value of kids, and the second number you type becomes the value of gumballs. It doesn’t matter that your program displays the message How many gumballs? How many kids?. What matters is the order of the assignment statements in the program.

If the kids assignment statement accidentally comes first, you can get a strange answer, like the zero answer in Figure 7-4. That’s how int division works. It just cuts off any remainder. Divide a small number (like 6) by a big number (like 80), and you get 0.

Figure 7-4: How to make six kids very unhappy.

9780470371749-fg0704.tif

Creating New Values by Applying Operators

What could be more comforting than your old friend, the plus sign? It was the first thing you learned about in elementary school math. Almost everybody knows how to add two and two. In fact, in English usage, adding two and two is a metaphor for something that’s easy to do. Whenever you see a plus sign, one of your brain cells says, “Thank goodness, it could be something much more complicated.”

So Java has a plus sign. You can use the plus sign to add two numbers:

int apples, oranges, fruit;

apples = 5;

oranges = 16;

fruit = apples + oranges;

Of course, the old minus sign is available, too:

apples = fruit - oranges;

Use an asterisk for multiplication and a forward slash for division:

double rate, pay, withholding;

int hours;

rate = 6.25;

hours = 35;

pay = rate * hours;

withholding = pay / 3.0;

tip.eps When you divide an int value by another int value, you get an int value. The computer doesn’t round. Instead, the computer chops off any remainder. If you put System.out.println(11 / 4) in your program, the computer prints 2, not 2.75. If you need a decimal answer, make either (or both) of the numbers you’re dividing double values. For example, if you put System.out.println(11.0 / 4) in your program, the computer divides a double value, 11.0, by an int value, 4. Because at least one of the two values is double, the computer prints 2.75.

Finding a remainder

There’s a useful arithmetic operator called the remainder operator. The symbol for the remainder operator is the percent sign (%). When you put System.out.println(11 % 4) in your program, the computer prints 3. It does this because 4 goes into 11 who-cares-how-many times, with a remainder of 3.

technicalstuff.eps Another name for the remainder operator is the modulus operator.

The remainder operator turns out to be fairly useful. After all, a remainder is the amount you have left over after you divide two numbers. What if you’re making change for $1.38? After dividing 138 by 25, you have 13 cents left over, as shown in Figure 7-5.

The code in Listing 7-3 makes use of this remainder idea.

Figure 7-5: Hey, bud! Got change for 138 sticks?

9780470371749-fg0705.eps

Listing 7-3: Making Change

import java.util.Scanner;

class MakeChange {

   public static void main(String args[]) {

      Scanner myScanner = new Scanner(System.in);

      int quarters, dimes, nickels, cents;

      int whatsLeft, total;

      System.out.print(“How many cents do you have? “);

      total = myScanner.nextInt();

      quarters = total / 25;

      whatsLeft = total % 25;

      dimes = whatsLeft / 10;

      whatsLeft = whatsLeft % 10;

      nickels = whatsLeft / 5;

      whatsLeft = whatsLeft % 5;

      cents = whatsLeft;

      System.out.println();

      System.out.println

            (“From “ + total + “ cents you get”);

      System.out.println(quarters + “ quarters”);

      System.out.println(dimes + “ dimes”);

      System.out.println(nickels + “ nickels”);

      System.out.println(cents + “ cents”);

   }

}

A run of the code in Listing 7-3 is shown in Figure 7-6. You start with a total of 138 cents. The statement

quarters = total / 25;

divides 138 by 25, giving 5. That means you can make 5 quarters from 138 cents. Next, the statement

whatsLeft = total % 25;

divides 138 by 25 again, and puts only the remainder, 13, into whatsLeft. Now you’re ready for the next step, which is to take as many dimes as you can out of 13 cents.

You keep going like this until you’ve divided away all the nickels. At that point, the value of whatsLeft is just 3 (meaning 3 cents).

Figure 7-6: Change for $1.38.

9780470371749-fg0706.tif

warning_bomb.eps When two or more variables have similar types, you can create the variables with combined declarations. For example, Listing 7-3 has two combined declarations — one for the variables quarters, dimes, nickels, and cents (all of type int); another for the variables whatsLeft and total (both of type int). But to create variables of different types, you need separate declarations. For example, to create an int variable named total and a double variable named amount, you need one declaration int total; and another declaration double amount;.

tip.eps Listing 7-3 has a call to System.out.println() with nothing in the parentheses. When the computer executes this statement, the cursor jumps to a new line on the screen. (I often use this statement to put a blank line in a program’s output.)

The increment and decrement operators

Java has some neat little operators that make life easier (for the computer’s processor, for your brain, and for your fingers). Altogether, there are four such operators — two increment operators and two decrement operators. The increment operators add one, and the decrement operators subtract one. To see how they work, you need some examples.

Using preincrement

The first example is in Figure 7-7.

A run of the program in Figure 7-7 is shown in Figure 7-8. In this horribly uneventful run, the count of gumballs gets displayed three times.

The double plus sign goes under two different names, depending on where you put it. When you put the ++ before a variable, the ++ is called the preincrement operator. In the word preincrement, the pre stands for before. In this setting, the word before has two different meanings:

check.png You’re putting ++ before the variable.

check.png The computer adds 1 to the variable’s value before the variable gets used in any other part of the statement.

Figure 7-9 has a slow-motion, instant replay of the preincrement operator’s action. In Figure 7-9, the computer encounters the System.out.print ln(++gumballs) statement. First, the computer adds 1 to gumballs (raising the value of gumballs to 29). Then the computer executes System.out.println, using the new value of gumballs (29).

Figure 7-7: Using preincrement.

9780470371749-fg0707.tif

Figure 7-8: A run of the preincrement code (the code in Figure 7-7).

9780470371749-fg0708.tif

Figure 7-9: The preincrement operator in action.

9780470371749-fg0709.eps

remember.eps With System.out.println(++gumballs), the computer adds 1 to gum balls before printing the new value of gumballs on the screen.

Using postincrement

An alternative to preincrement is postincrement. With postincrement, the post stands for after. The word after has two different meanings:

check.png You put ++ after the variable.

check.png The computer adds 1 to the variable’s value after the variable gets used in any other part of the statement.

Figure 7-10 has a close-up view of the postincrement operator’s action. In Figure 7-10, the computer encounters the System.out.println(gum balls++) statement. First, the computer executes System.out.println, using the old value of gumballs (28). Then the computer adds 1 to gum balls (raising the value of gumballs to 29).

Look at the bold line of code in Figure 7-11. The computer prints the old value of gumballs (28) on the screen. Only after printing this old value does the computer add 1 to gumballs (raising the gumballs value from 28 to 29).

remember.eps With System.out.println(gumballs++), the computer adds 1 to gum balls after printing the old value that gumballs already had.

A run of the code in Figure 7-11 is shown in Figure 7-12. Compare Figure 7-12 with the run in Figure 7-8.

Figure 7-10: The post-increment operator in action.

9780470371749-fg0710.eps

Figure 7-11: Using post-increment.

9780470371749-fg0711.tif

Figure 7-12: A run of the postincrement code (the code in Figure 7-11).

9780470371749-fg0712.tif

check.png With preincrement in Figure 7-8, the second number that gets displayed is 29.

check.png With postincrement in Figure 7-12, the second number that gets displayed is 28.

In Figure 7-12, the number 29 doesn’t show up on the screen until the end of the run, when the computer executes one last System.out.println(gumballs).

tip.eps Are you trying to decide between using preincrement or postincrement? Ponder no longer. Most programmers use postincrement. In a typical Java program, you often see things like gumballs++. You seldom see things like ++gumballs.

In addition to preincrement and postincrement, Java has two operators that use --. These operators are called predecrement and postdecrement:

check.png With predecrement (--gumballs), the computer subtracts 1 from the variable’s value before the variable gets used in the rest of the statement.

check.png With postdecrement (gumballs--), the computer subtracts 1 from the variable’s value after the variable gets used in the rest of the statement.

Assignment operators

If you read the previous section — the section about operators that add 1 — you may be wondering if you can manipulate these operators to add 2, or add 5, or add 1000000. Can you write gumballs++++ and still call yourself a Java programmer? Well, you can’t. If you try it, then Eclipse will give you an error message:

Invalid argument to operation ++/--

If you don’t use Eclipse, you may see a different error message:

unexpected type

required: variable

found   : value

      gumballs++++;

              ^

Eclipse or no Eclipse, the bottom line is the same: Namely, your code contains an error, and you have to fix it.

So how can you add values other than 1? As luck would have it, Java has plenty of assignment operators you can use. With an assignment operator, you can add, subtract, multiply, or divide by anything you want. You can do other cool operations, too.

For example, you can add 1 to the kids variable by writing

kids += 1;

Is this better than kids++ or kids = kids + 1? No, it’s not better. It’s just an alternative. But you can add 5 to the kids variable by writing

kids += 5;

You can’t easily add 5 with pre- or postincrement. And what if the kids get stuck in an evil scientist’s cloning machine? The statement

kids *= 2;

multiplies the number of kids by 2.

With the assignment operators, you can add, subtract, multiply, or divide a variable by any number. The number doesn’t have to be a literal. You can use a number-valued expression on the right side of the equal sign:

double amount = 5.95;

double shippingAndHandling = 25.00, discount = 0.15;

amount += shippingAndHandling;

amount -= discount * 2;

The preceding code adds 25.00 (shippingAndHandling) to the value of amount. Then, the code subtracts 0.30 (discount * 2) from the value of amount. How generous!

Size Matters

Here are today’s new vocabulary words:

foregift (fore-gift) n. A premium that a lessee pays to the lessor upon the taking of a lease.

hereinbefore (here-in-be-fore) adv. In a previous part of this document.

Now imagine yourself scanning some compressed text. In this text, all blanks have been removed to conserve storage space. You come upon the following sequence of letters:

hereinbeforegiftedit

The question is, what do these letters mean? If you knew each word’s length, you could answer the question.

here in be foregift edit

hereinbefore gifted it

herein before gift Ed it

A computer faces the same kind of problem. When a computer stores several numbers in memory or on a disk, the computer doesn’t put blank spaces between the numbers. So imagine that a small chunk of the computer’s memory looks like the stuff in Figure 7-13. (The computer works exclusively with zeros and ones, but Figure 7-13 uses ordinary digits. With ordinary digits, it’s easier to see what’s going on.)

What number or numbers are stored in Figure 7-13? Is it two numbers, 42 and 21? Or is it one number, 4,221? And what about storing four numbers, 4, 2, 2, and 1? It all depends on the amount of space each number consumes.

Figure 7-13: Storing the digits 4221.

9780470371749-fg0713.eps

Imagine a variable that stores the number of paydays in a month. This number never gets bigger than 31. You can represent this small number with just eight zeros and ones. But what about a variable that counts stars in the universe? That number could easily be more than a trillion, and to represent one trillion accurately, you need 64 zeros and ones.

At this point, Java comes to the rescue. Java has four types of whole numbers. Just as in Listing 7-1, I declare

int gumballsPerKid;

I can also declare

byte paydaysInAMonth;

short sickDaysDuringYourEmployment;

long numberOfStars;

Each of these types (byte, short, int, and long) has its own range of possible values (see Table 7-1).

Java has two types of decimal numbers (numbers with digits to the right of the decimal point). Just as in Listing 6-1, I declare

double amount;

I can also declare

float monthlySalary;

Given the choice between double and float, I always choose double. A variable of type double has a greater possible range of values and much greater accuracy (see Table 7-1).

/Table 7-1

Table 7-1 lists six of Java’s primitive types (also known as simple types). Java has only eight primitive types, so only two of Java’s primitive types are missing from Table 7-1.

Chapter 8 describes the two remaining primitive types. Chapter 17 introduces types that aren’t primitive.

As a beginning programmer, you don’t have to choose among the types in Table 7-1. Just use int for whole numbers and double for decimal numbers. If, in your travels, you see something like short or float in someone else’s program, just remember the following:

check.png The types byte, short, int, and long represent whole numbers.

check.png The types float and double represent decimal numbers.

Most of the time, that’s all you need to know.