Chapter 7
IN THIS CHAPTER
Processing whole numbers
Making new values from old values
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.)
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, I’ll never hear the end of it.
With 30 gumballs and four kids, there’s no way to divide the gumballs evenly. Of course, if I get rid of a kid, 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.");
}
}
Figure 7-1 shows a run of the KeepingKidsQuiet
program. 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.
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 7½, but I can’t take the ½ 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 7½. 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.
What a life! Yesterday there were four kids in my living room, and I had 30 gumballs. Today there are six 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 keyboard = new Scanner(System.in);
int gumballs;
int kids;
int gumballsPerKid;
System.out.print("How many gumballs? How many kids? ");
gumballs = keyboard.nextInt();
kids = keyboard.nextInt();
gumballsPerKid = gumballs / kids;
System.out.print("Each kid gets ");
System.out.print(gumballsPerKid);
System.out.println(" gumballs.");
keyboard.close();
}
}
You should notice a couple of things about Listing 7-2. First, you can read an int
value with the nextInt
method. (Refer to the table in Chapter 5.) 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 = keyboard.nextInt();
costOfGumballs = keyboard.nextDouble();
kids = keyboard.nextInt();
Figure 7-3 shows valid input for these three method calls.
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 = keyboard.nextInt();
gumballs = keyboard.nextInt();
Here, the line How many gumballs? How many kids?
is 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.
Run the program in Listing 7-2. When the program asks How many gumballs? How many kids?
, type 80.5 6. (Actually, if you live in a country where 80,5 represents eighty-and-a-half, type 80,5 instead of 80.5.)
What unpleasant message do you see during this run of the program? Why do you see this message?
Run the program in Listing 7-2. When the program asks How many gumballs? How many kids?
, type "80" "6" (quotation marks and all).
What unpleasant message do you see during this run of the program? Why do you see this message?
Write a program that gets two numbers from the keyboard and displays the sum of the two numbers.
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;
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 so because 4 goes into 11 who-cares-how-many times, with a remainder of 3.
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.
LISTING 7-3 Making Change
import java.util.Scanner;
class MakeChange {
public static void main(String args[]) {
Scanner keyboard = new Scanner(System.in);
int quarters, dimes, nickels, cents;
int whatsLeft, total;
System.out.print("How many cents do you have? ");
total = keyboard.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");
keyboard.close();
}
}
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).
10 / 3
10 % 3
3 / 10
3 % 10
8 * 3 + 4
4 + 8 * 3
8 * (3 + 4)
34 % 5 - 2 * 2 + 21 / 5
What’s the value of each of the following variables (a
, b
, c
, and so on)? Type each statement on a separate line in JShell to find out whether your answers are correct:
int a = 8
int b = 3
int c = b / a
int d = a / b
int e = a % b
int f = 5 + e * d - 2
A local plumber charges $75 to come to my house. In addition, for every hour the plumber works at my house, the plumber charges an additional $125. Write a program that inputs the number of hours that a plumber works at my house, and outputs the total amount that the plumber charges.
Modify the code in Listing 7-3 so that it starts by getting a number of dollars and a number of cents from the keyboard. For example, instead of typing 138 (meaning 138 cents), the user types 1 38 (1 dollar and 38 cents).
Where I come from, we don’t use metric measurements. Instead, we measure each person’s height in feet and inches. A foot is 12 inches, and I’m five-and-a-half feet tall. (My height in feet is the double
value 5.5.) Write a program to find my height in inches. (That is, from 5.5 feet, calculate 66 inches.)
Modify the program so that it asks for the user’s height in feet and then reports the person’s height in inches.
Modify the program so that it asks for the user’s height in feet and inches. For example, a person who’s five-and-a-half feet tall types the number 5 (for five feet) followed by the number 6 (for six more inches). The program reports the person’s height in inches.
My wife and I were married on February 29, so we have one anniversary every four years. Write a program with a variable named years
. Based on the value of the years
variable, the program displays the number of anniversaries we’ve had. For example, if the value of years
is 4
, the program displays the sentence Number of anniversaries: 1
. If the value of years
is 7
, the program still displays Number of anniversaries: 1
. But if the value of years
is 8
, the program displays Number of anniversaries: 2
.
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.
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 is 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:
++
before the variable.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.println(++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
).
An alternative to preincrement is postincrement. With postincrement, the post stands for after. The word after has two different meanings:
++
after the variable.Figure 7-10 shows a close-up view of the postincrement operator’s action. In Figure 7-10, the computer encounters the System.out.println(gumballs++)
statement. First, the computer executes System.out.println
, using the old value of gumballs
(28
). Then the computer adds 1 to gumballs
(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
).
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.
29
.With postincrement in Figure 7-12, the second number that’s 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)
.
In addition to preincrement and postincrement, Java has two operators that use --
. These operators are called predecrement and postdecrement:
--gumballs
), the computer subtracts 1 from the variable’s value before the variable is used in the rest of the statement.gumballs--
), the computer subtracts 1 from the variable’s value after the variable is used in the rest of the statement.jshell> int i = 8
jshell> i++
jshell> i
jshell> i
jshell> i++
jshell> i
jshell> ++i
jshell> i
Before you run the following code, try to predict what the code’s output will be. Then run the code to find out whether your prediction is correct:
public class Main {
public static void main(String[] args) {
int i = 10;
System.out.println(i++);
System.out.println(--i);
--i;
i--;
System.out.println(i);
System.out.println(++i);
System.out.println(i--);
System.out.println(i);
}
}
If you’ve read the previous section — the section about operators that add 1 — you may be wondering whether 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, 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.
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 preincrement 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!
public class Main {
public static void main(String[] args) {
int i = 10;
i += 2;
i -= 5;
i *= 6;
System.out.println(i);
System.out.println(i += 3);
System.out.println(i /= 2);
}
}
In addition to the assignment operators that I describe in this section, Java also has a %=
operator. The %=
operator does for remainders what the +=
operator does for addition. Modify the code in Listing 7-3 so that it uses the %=
assignment operator wherever possible.
Here are today’s new vocabulary words:
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:
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.
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 1 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.)
TABLE 7-1 Java’s Primitive Numeric Types
Type Name | Range of Values |
Whole Number Types | |
| –128 to 127 |
| –32768 to 32767 |
| –2147483648 to 2147483647 |
| –9223372036854775808 to 9223372036854775807 |
Decimal Number Types | |
| –3.4×1038 to 3.4×1038 |
| –1.8×10308 to 1.8×10308 |
Java has two types of decimal numbers (numbers with digits to the right of the decimal point). Just as in Listing 6-1 (over in Chapter 6), 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 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:
byte
, short
, int
, and long
represent whole numbers.float
and double
represent decimal numbers.Most of the time, that’s all you need to know.
3.15.14.98