**77**

**C h a p t e r** 3

### Fundamental Data Types

To recognize the limitations of the int and double types and the overflow and roundoff errors that can result

To write arithmetic expressions in Java

To use the String type to define and manipulate character strings

To learn about the char data type

To learn how to read program input

To understand the copy behavior of primitive types and object references
**C H A P T E R G O A L S**

To understand integer and floating-point numbers

### T his chapter teaches how to manipulate numbers and character strings in

### Java. The goal of this chapter is to gain a firm understanding of the fundamental

### Java data types.

**78** **CHAPTER 3** Fundamental Data Types

**78**

In this chapter, we will use a ^{Purse} class to demonstrate several important concepts. We
won’t yet reveal the implementation of the purse, but here is the public interface:

public class Purse {

/**

Constructs an empty purse.

*/

public Purse() {

// implementation }

/**

Add nickels to the purse.

@param count the number of nickels to add */

public void addNickels(int count) {

// implementation }

/**

Add dimes to the purse.

@param count the number of dimes to add

**3.1** **Number Types**

3.1 Number Types **78**

Quality Tip 3.1: Choose Descriptive Variable
Names **80**

Advanced Topic 3.1: Numeric Ranges and
Precisions **81**

Advanced Topic 3.2: Other Number Types **82**
Random Fact 3.1: The Pentium Floating-Point

Bug **83**

3.2 Assignment **84**

Advanced Topic 3.3: Combining Assignment
and Arithmetic **86**

Productivity Hint 3.1: Avoid Unstable Layout **87**
3.3 Constants **88**

Syntax 3.1: Constant Definition **90**

Quality Tip 3.2: Do Not Use Magic Numbers **92**
3.4 Arithmetic and Mathematical Functions **92**
Common Error 3.1: Integer Division **94**

Common Error 3.2: Unbalanced
Parentheses **96**

Productivity Hint 3.2: On-Line Help **96**

Quality Tip 3.3: White Space **97**

Quality Tip 3.4: Factor Out Common Code **98**
3.5 Calling Static Methods **98**

Syntax 3.2: Static Method Call **99**
3.6 Type Conversion **100**
Syntax 3.3: Cast **101**

HOWTO 3.1: Carrying Out Computations **101**
Common Error 3.3: Roundoff Errors **104**
Advanced Topic 3.4: Binary Numbers **105**
3.7 Strings **107**

Advanced Topic 3.5: Formatting Numbers **109**
3.8 Reading Input **110**

Productivity Hint 3.3: Reading Exception
Reports **112**

Advanced Topic 3.6: Reading Console
Input **113**

3.9 Characters **116**

Random Fact 3.2: International Alphabets **116**
3.10 Comparing Primitive Types and

Objects **119**
**C H A P T E R C O N T E N T S**

**3.1** Number Types **79**
*/

public void addDimes(int count) {

// implementation }

/**

Add quarters to the purse.

@param count the number of quarters to add */

public void addQuarters(int count) {

// implementation }

/**

Get the total value of the coins in the purse.

@return the sum of all coin values */

public double getTotal() {

// implementation }

// private instance variables }

Read through the public interface and ask yourself whether you can figure out how to use ^{Purse}
objects. You should find this straightforward. There is a constructor to make a new, empty purse:

Purse myPurse = new Purse();

You can add nickels, dimes, and quarters. (For simplicity, we don’t bother with pennies, half dollars, or dollar coins.)

myPurse.addNickels(3);

myPurse.addDimes(1);

myPurse.addQuarters(2);

Now you can ask the purse object about the total value of the coins in the purse:

double totalValue = myPurse.getTotal(); // returns 0.75

If you look closely at the methods to add coins, you will see an
unfamiliar data type. The ^{count} parameter has type ^{int}, which
denotes an *integer* type. An integer is a number without a fractional
part. For example, 3 is an integer, but 0.05 is not. The number zero
and negative numbers are integers. Thus, the ^{int} type is more restric-
tive than the ^{double} type that you saw in Chapter 2.

Why have both integer and floating-point number types? Your calculator doesn’t
have a separate integer type. It uses floating-point numbers for all calculations. Why
don’t we just use the ^{double} type for the coin counts?

The int type denotes integers: numbers without fractional parts.

**80** **CHAPTER 3** Fundamental Data Types

**80**

There are two reasons for having a separate integer type: one philosophical and one prag- matic. In terms of philosophy, when we think about real purses and modern American coins, we recognize that there can be only a whole number of nickels, say, in a purse. If we were to saw a nickel in half, the halves would be worthless, and dropping one of them into a purse would not increase the amount of money in the purse. By specifying that the number of nickels is an integer, we make that observation into an explicit assumption in our model. The program would have worked just as well with floating-point numbers to count the coins, but it is generally a good idea to choose programming solutions that document one’s intentions.

Pragmatically speaking, integers are more efficient than floating-point numbers. They take less storage space, are processed faster on some platforms, and don’t cause rounding errors.

Now let’s start implementing the ^{Purse} class. Any ^{Purse} object can be described by
the number of nickels, dimes, and quarters that the purse currently contains. Thus, we
use three instance variables to represent the state of a ^{Purse} object:

public class Purse {

. . .

private int nickels;

private int dimes;

private int quarters;

}

Now we can implement the ^{getTotal} method simply:

public double getTotal() {

return nickels * 0.05 + dimes * 0.1 + quarters * 0.25;

}

In Java, multiplication is denoted by an asterisk ^{*}, not a raised dot · or a cross , because
*there are no keys for these symbols on most keyboards. For example, d · 10 is written as*
d * 10. Do not write commas or spaces in numbers in Java. For example, 10,150.75
must be entered as ^{10150.75}. To write numbers in exponential notation in Java, use ^{E}* n*
instead of “ 10* ^{n}*”. For example, 5.0 10

^{–3}is written as

^{5.0E-3}.

The ^{getTotal} method computes the value of the expression
nickels * 0.05 + dimes * 0.1 + quarters * 0.25

That value is a floating-point number, because multiplying an integer (such as ^{nickels})
by a floating-point number (such as ^{0.05}) yields a floating-point number. The ^{return}
statement returns the computed value as the method result, and the method exits.

**Choose Descriptive Variable Names**

*In algebra, variable names are usually just one letter long, such as p or A, maybe with a*
*subscript such as p*_{1}. You might be tempted to save yourself a lot of typing by using
shorter variable names in your Java programs as well:

**Quality Tip** 3.1

public class Purse {

. . .

private int n;

private int d;

private int q;

}

Compare this with the previous one, though. Which one is easier to read? There is no
comparison. Just reading ^{nickels} is a lot less trouble than reading ^{n}* and then figuring*
*out that it must mean “nickels”. *

In practical programming, descriptive variable names are particularly important when
*programs are written by more than one person. It may be obvious to you that *^{n} must
stand for nickels, but is it obvious to the person who needs to update your code years
later, long after you were promoted (or laid off )? For that matter, will you remember
yourself what ^{n} means when you look at the code six months from now?

Of course, you could use comments:

public class Purse {

. . .

private int n; // nickels private int d; // dimes private int q; // quarters }

That makes the definitions pretty clear. But in the ^{getTotal} method, you’d still have a rather
cryptic computation n * 0.05 + d * 0.1 + q * 0.25. Descriptive variable names are a
better choice, because they make your code easy to read without requiring comments.

**Numeric Ranges and Precisions**

Unfortunately, ^{int} and ^{double} values do suffer from one problem: They cannot represent arbi-
trarily large integer or floating-point numbers. Integers have a range of 2,147,483,648 (about
2 billion) to 2,147,483,647 (about 2 billion). See Advanced Topic 3.4 for an explanation of
these values. If you need to refer to these boundaries in your program, use the constants ^{Integer.}

MIN_VALUE and Integer.MAX_VALUE, which are defined in a class called ^{Integer}. If you
want to represent the world population, you can’t use an ^{int}. Double-precision floating-point
numbers are somewhat less limited; they can go up to more than 10^{300}. However, ^{double}
*floating-point numbers suffer from a different problem: precision. They store only about 15 sig-*
nificant digits. Suppose your customers might find the price of three hundred trillion dollars
($300,000,000,000,000) for your product a bit excessive, so you want to reduce it by five cents to
a more reasonable-looking $299,999,999,999,999.95. Try running the following program:

class AdvancedTopic3_1 {

**Advanced Topic** 3.1

public static void main(String[] args) {

double originalPrice = 3E14;

double discountedPrice = originalPrice - 0.05;

double discount = originalPrice - discountedPrice;

// should be 0.05;

System.out.println(discount);

// prints 0.0625;

} }

The program prints out ^{0.0625}, not ^{0.05}. It is off by more than a penny!

For most of the programming projects in this book, the limited range and precision
of ^{int} and ^{double} are acceptable. Just bear in mind that overflows or loss of precision
can occur.

**Other Number Types**

If ^{int} and ^{double} are not sufficient for your computational needs, there are other
data types to which you can turn. When the range of integers is not sufficient,
the simplest remedy is to use the ^{long}* type. Long integers have a range from*

9,223,372,036,854,775,808 to 9,223,372,036,854,775,807.

To specify a long integer constant, you need to append the letter ^{L} after the number
value. For example,

long price = 300000000000000L;

There is also an integer type ^{short} with shorter-than-normal integers, having a range of
32,768 to 32,767. Finally, there is a type ^{byte} with a range of 128 to 127.

The ^{double} type can represent about 15 decimal digits. There is a second floating-
point type, called ^{float}, whose values take half the storage space. Computations involv-
ing ^{float} execute a bit faster than those involving ^{double}, but the precision of ^{float}
values—about 7 decimal digits—is insufficient for many programs. However, some
graphics routines require you to use ^{float} values.

By the way, the name “floating-point” comes from the fact that the numbers are
represented in the computer as a sequence of the significant digits and an indication of
the position of the decimal point. For example, the numbers 250, 2.5, 0.25, and 0.025
all have the same decimal digits: 25. When a floating-point number is multiplied or
divided by 10, only the position of the decimal point changes; it “floats”. This repre-
sentation corresponds to numbers written in “exponential” or “scientific” notation, such
as 2.5 10^{2}. (Actually, internally the numbers are represented in base 2, as binary
numbers, but the principle is the same. See Advanced Topic 3.4 for more information
on binary numbers.) Sometimes ^{float} values are called “single-precision”, and of
course ^{double} values are “double-precision” floating-point numbers.

**Advanced Topic** 3.2

*If you want to compute with really large numbers, you can use big number objects.*

Big number objects are objects of the ^{BigInteger} and ^{BigDecimal} classes in the
java.math package. Unlike the number types such as ^{int} or ^{double}, big number
objects have essentially no limits on their size and precision. However, computations
with big number objects are much slower than those that involve number types. Per-
haps more importantly, you can’t use the familiar arithmetic operators (^{+ - * /}) with
them. Instead, you have to use methods called ^{add}, ^{subtract}, ^{multiply}, and
divide. Here is an example of how to create two big numbers and how to multiply
them.

BigInteger a = new BigInteger("123456789");

BigInteger b = new BigInteger("987654321");

BigInteger c = a.multiply(b);

System.out.println(c); // prints 121932631112635269

**The Pentium Floating-Point Bug**

In 1994, Intel Corporation released what was then its most powerful processor, the first of the Pentium series. Unlike previous generations of Intel’s processors, the Pentium had a very fast floating-point unit. Intel’s goal was to compete aggressively with the makers of higher- end processors for engineering workstations. The Pentium was an immediate huge success.

In the summer of 1994, Dr. Thomas Nicely of Lynchburg College in Virginia ran an extensive set of computations to analyze the sums of reciprocals of certain sequences of prime numbers. The results were not always what his theory predicted, even after he took into account the inevitable roundoff errors. Then Dr. Nicely noted that the same program did produce the correct results when run on the slower 486 processor, which preceded the Pentium in Intel’s lineup. This should not have happened. The optimal roundoff behavior of floating-point calculations has been standardized by the Institute of Electrical and Electronics Engineers (IEEE), and Intel claimed to adhere to the IEEE standard in both the 486 and the Pentium processors. Upon further checking, Dr. Nicely discovered that indeed there was a very small set of numbers for which the product of two numbers was computed differently on the two processors. For example,

4,195,835 ((4,195,835 / 3,145,727) 3,145,727)

is mathematically equal to 0, and it did compute as 0 on a 486 processor. On a Pentium processor, however, the result was 256.

As it turned out, Intel had independently discovered the bug in its testing and had started to produce chips that fixed it. (Subsequent versions of the Pentium, such as the Pentium III and IV, are free of the problem.) The bug was caused by an error in a table that was used to speed up the floating-point multiplication algorithm of the processor.

Intel determined that the problem was exceedingly rare. They claimed that under normal use a typical consumer would only notice the problem once every 27,000 years. Unfortu- nately for Intel, Dr. Nicely had not been a normal user.

**Random Fact** 3.1

Now Intel had a real problem on its hands. It figured that replacing all the Pen- tium processors that it had already sold would cost it a great deal of money. Intel already had more orders for the chip than it could produce, and it would be partic- ularly galling to have to give out the scarce chips as free replacements instead of selling them. Intel’s management decided to punt on the issue and initially offered to replace the processors only for those customers who could prove that their work required absolute precision in mathematical calculations. Naturally, that did not go over well with the hundreds of thousands of customers who had paid retail prices of $700 and more for a Pentium chip and did not want to live with the nagging feeling that perhaps, one day, their income tax program would produce a faulty return.

Ultimately, Intel had to cave in to public demand and replaced all defective chips, at a cost of about 475 million dollars.

What do you think? Intel claims that the probability of the bug occurring in any cal- culation is extremely small—smaller than many chances you take every day, such as driv- ing to work in an automobile. Indeed, many users had used their Pentium computers for many months without reporting any ill effects, and the computations that Professor Nicely was doing are hardly examples of typical user needs. As a result of its public rela- tions blunder, Intel ended up paying a large amount of money. Undoubtedly, some of that money was added to chip prices and thus actually paid by Intel’s customers. Also, a large number of processors, whose manufacture consumed energy and caused some envi- ronmental impact, were destroyed without benefiting anyone. Could Intel have been jus- tified in wanting to replace only the processors of those users who could reasonably be expected to suffer an impact from the problem?

Suppose that, instead of stonewalling, Intel had offered you the choice of a free replacement processor or a $200 rebate. What would you have done? Would you have replaced your faulty chip, or would you have taken your chance and pocketed the money?

Here is the constructor of the ^{Purse} class:

public Purse() {

nickels = 0;

dimes = 0;

quarters = 0;

}

The ^{=}* operator is called the assignment operator. On the left, you need a variable name.*

The right-hand side can be a single value or an expression. The assignment operator sets
the variable to the given value. So far, that’s straightforward. But now let’s look at a more
interesting use of the assignment operator, in the ^{addNickels} method.

**3.2** **Assignment**

public void addNickels(int count) {

nickels = nickels + count;

}

It means, “Compute the value of the expression nickels + count*, and place the result*
*again into the variable *^{nickels}.” (See Figure 1.)

The ^{=}* sign doesn’t mean that the left-hand side is equal to the right-hand side but that the*
right-hand-side value is copied into the left-hand-side variable. You should not confuse this
*assignment operation with the = used in algebra to denote equality. The assignment operator is*
an instruction to do something, namely place a value into a variable. The mathematical equal-
ity states the fact that two values are equal. For example, in Java it is perfectly legal to write

nickels = nickels + 1;

It means to look up the value stored in the variable ^{nickels}, to add 1 to it, and to
stuff the sum back into ^{nickels}. (See Figure 2.) The net effect of executing this

**F i g u r e 1**
Assignment

**F i g u r e 2**

Incrementing a Variable count =

nickels =

nickels + count

nickels =

nickels + 1

statement is to increment ^{nickels} by 1. Of course, in mathematics
*it would make no sense to write that n = n + 1; no integer can equal*
itself plus 1.

The concepts of assignment and equality have no relationship
with each other, and it is a bit unfortunate that the Java language
(following C and C++) uses ^{=} to denote assignment. Other pro-
gramming languages use a symbol such as ^{<-} or ^{:=}, which avoids
the confusion.

Consider once more the statement nickels = nickels + 1.
This statement increments the ^{nickels} variable. For example, if
nickels was 3 before execution of the statement, it is set to 4 after-
wards. This increment operation is so common when writing pro-
grams that there is a special shorthand for it, namely

nickels++;

This statement has exactly the same effect—namely, to add 1 to ^{nickels}—but it is
easier to type. As you might have guessed, there is also a decrement operator ^{--}. The
statement

nickels--;

subtracts 1 from ^{nickels}.

**Combining Assignment and Arithmetic**

In Java you can combine arithmetic and assignment. For example, the instruction nickels += count;

is a shortcut for

nickels = nickels + count;

Similarly,

nickels *= 2;

is another way of writing nickels = nickels * 2;

Many programmers find this a convenient shortcut. If you like it, go ahead and use it in your own code. For simplicity, we won’t use it in this book, though.

**Advanced Topic** 3.3

Assignment to a variable is not the same as mathematical equality.

The ++ and -- operators increment and decrement a variable.

**Avoid Unstable Layout**

You should arrange program code and comments so that the program is easy to read. For
example, you should not cram all statements on a single line, and you should make sure
that braces ^{{ }} line up.

However, you should be careful when you embark on beautification efforts. Some
programmers like to line up the ^{=} signs in a series of assignments, like this:

nickels = 0;

dimes = 0;

quarters = 0;

*This looks very neat, but the layout is not stable. Suppose you add a line like the one at*
the bottom of this:

nickels = 0;

dimes = 0;

quarters = 0;

halfDollars = 0;

Oops, now the ^{=} signs no longer line up, and you have the extra work of lining them up
*again. *

Here is another example. Suppose you have a comment that goes over multiple lines:

// In this test class, we compute the value of a set of coins.

// We add a number of nickels, dimes, and quarters^{ }
// to a purse. We then get and display the total value.

When the program is extended to work for half-dollar coins as well, you must modify the comment to reflect that change.

// In this test class, we compute the value of a set of coins.

// We add a number of nickels, dimes, quarters, and
half-dollars^{ // }to a purse. We then get and display the total
value.

Now you need to rearrange the ^{//}* to fix up the comment. This scheme is a disincentive to*
keep comments up to date. Don’t do it. Instead, for comments that are longer than one line,
use the ^{/*...*/} style for comments, and block off the entire comment like this:

/*

In this test class, we compute the value of a set of coins.

We add a number of nickels, dimes, and quarters to a purse. We then get and display the total value.

*/

You may not care about these issues. Perhaps you plan to beautify your program just before it is finished, when you are about to turn in your homework. That is not a

**Productivity Hint** 3.1

particularly useful approach. In practice, programs are never finished. They are con- tinuously improved and updated. It is better to develop the habit of laying out your programs well from the start and keeping them legible at all times. As a conse- quence, you should avoid layout schemes that are hard to maintain.

Consider once again the ^{getTotal} method, paying attention to whether it is easy to
understand the code.

public double getTotal() {

return nickels * 0.05 + dimes * 0.1 + quarters * 0.25;

}

Most of the code is self-documenting. However, the three numeric quantities, 0.05, 0.1, and 0.25, are included in the arithmetic expression without any explanation. Of course, in this case, you know that the value of a nickel is five cents, which explains the 0.05, and so on. However, the next person who needs to maintain this code may live in another country and may not know that a nickel is worth five cents.

*Thus, it is a good idea to use symbolic names for all values, even those that appear*
obvious. Here is a clearer version of the computation of the total:

double nickelValue = 0.05;

double dimeValue = 0.1;

double quarterValue = 0.25;

return nickels * nickelValue + dimes * dimeValue + quarters * quarterValue;

There is another improvement we can make. There is a difference
between the ^{nickels} and nickelValue variables. The ^{nickels}
variable can truly vary over the life of the program, as more coins are
added to the purse. But nickelValue* is always 0.05. It is a constant.*

In Java, constants are identified with the keyword ^{final}. A variable
tagged as ^{final} can never change after it has been set. If you try to
change the value of a ^{final} variable, the compiler will report an error
and your program will not compile.

Many programmers use all-uppercase names for constants (^{final}
variables), such as NICKEL_VALUE. That way, it is easy to distinguish
between variables (with mostly lowercase letters) and constants. We will
follow this convention in this book. However, this rule is a matter of good style, not a
requirement of the Java language. The compiler will not complain if you give a ^{final} vari-
able a name with lowercase letters.

**3.3** **Constants**

A final variable is a constant. Once its value has been set, it cannot be changed.

Use named constants to make your programs easier to read and maintain.

Here is the improved version of the ^{getTotal} method:

public double getTotal() {

final double NICKEL_VALUE = 0.05;

final double DIME_VALUE = 0.1;

final double QUARTER_VALUE = 0.25;

return nickels * NICKEL_VALUE + dimes * DIME_VALUE + quarters * QUARTER_VALUE;

}

In this example, the constants are needed only inside one method of the class. Fre-
quently, a constant value is needed in several methods. Then you need to declare it
together with the instance variables of the class and tag it as static final. The mean-
ing of the keyword ^{static} will be explained in Chapter 6.

public class Purse {

// methods . . . // constants

private static final double NICKEL_VALUE = 0.05;

private static final double DIME_VALUE = 0.1;

private static final double QUARTER_VALUE = 0.25;

// instance variables private int nickels;

private int dimes;

private int quarters;

}

Here we defined the constants to be ^{private} because we didn’t think they were of
interest to users of the ^{Purse} class. However, it is also possible to declare constants as
public:

public static final double NICKEL_VALUE = 0.05;

Then methods of other classes can access the constant as Purse.NICKEL_VALUE.
The ^{Math} class from the standard library defines a couple of useful constants:

public class Math {

. . .

public static final double E = 2.7182818284590452354;

public static final double PI = 3.14159265358979323846;

}

You can refer to these constants as ^{Math.PI} and ^{Math.E} in any of your methods. For
example,

double circumference = Math.PI * diameter;

**File Purse.java**

**1 ** ^{/**}

**2 ** ^{ }A purse computes the total value of a collection of coins.

**3 ** ^{*/}

**4 ** public class Purse
**5 ** ^{{}

**6 ** ^{ /**}

**7 ** ^{ }Constructs an empty purse.

**8 ** ^{ */}

**9 ** public Purse()
**10 ** ^{ {}

**11 ** nickels = 0;

**12 ** dimes = 0;

**13 ** quarters = 0;

**14 ** ^{ }}
**15 **

**16 ** ^{ /**}

**17 ** ^{ }Add nickels to the purse.

**18 ** @param count the number of nickels to add
**19 ** ^{ */}

**20 ** public void addNickels(int count)
**21 ** ^{ {}

**22 ** nickels = nickels + count;

**23 ** ^{ }}
**24 ** ^{ /**}

**25 ** ^{ }Add dimes to the purse.

**26 ** @param count the number of dimes to add

**Syntax 3.1 : Constant Definition**

In a method:

final *typeName* *variableName* *expression*^{; }
In a class:

*accessSpecifier* static final *typeName* *variableName*^{ = }*expression*^{;}

**Example:**

final double NICKEL_VALUE = 0.05;

public static final double LITERS_PER_GALLON = 3.785;

**Purpose:**

To define a constant of a particular type

**27 ** ^{ */}

**28 ** public void addDimes(int count)
**29 ** ^{ {}

**30 ** dimes = dimes + count;

**31 ** ^{ }}
**32 **

**33 ** ^{ /**}

**34 ** ^{ }Add quarters to the purse.

**35 ** @param count the number of quarters to add
**36 ** ^{ */}

**37 ** public void addQuarters(int count)
**38 ** ^{ {}

**39 ** quarters = quarters + count;

**40 ** ^{ }}
**41 **

**42 ** ^{ /**}

**43 ** ^{ }Get the total value of the coins in the purse.

**44 ** @return the sum of all coin values
**45 ** ^{ */}

**46 ** public double getTotal()
**47 ** ^{ {}

**48 ** return nickels * NICKEL_VALUE

**49 ** + dimes * DIME_VALUE + quarters * QUARTER_VALUE;

**50 ** ^{ }}
**51 **

**52 ** private static final double NICKEL_VALUE = 0.05;

**53 ** private static final double DIME_VALUE = 0.1;

**54 ** private static final double QUARTER_VALUE = 0.25;

**55 **

**56 ** private int nickels;

**57 ** private int dimes;

**58 ** private int quarters;

**59 ** ^{}}

**File PurseTest.java**

**1 ** ^{/**}

**2 ** ^{ }This program tests the^{ Purse }class.

**3 ** ^{*/}

**4 ** public class PurseTest
**5 ** ^{{}

**6 ** public static void main(String[] args)
**7 ** ^{ {}

**8 ** Purse myPurse = new Purse();

**9 **

**10 ** myPurse.addNickels(3);

**11 ** myPurse.addDimes(1);

**12 ** myPurse.addQuarters(2);

**13 ** double totalValue = myPurse.getTotal();

**14 ** System.out.print("The total is ");

**15 ** System.out.println(totalValue);

**16 ** ^{ }}
**17 ** ^{}}

**Do Not Use Magic Numbers**

*A magic number is a numeric constant that appears in your code without explanation. For*
*example, consider the following scary example that actually occurs in the Java library source: *

h = 31 * h + ch;

Why 31? The number of days in January? One less than the number of bits in an integer?

Actually, this code computes a “hash code” from a string—a number that is derived from the characters in such a way that different strings are likely to yield different hash codes.

The value 31 turns out to scramble the character values nicely.

You should use a named constant instead:

final int HASH_MULTIPLIER = 31;

h = HASH_MULTIPLIER * h + ch;

*You should never use magic numbers in your code. Any number that is not completely self-*
explanatory should be declared as a named constant. Even the most reasonable cosmic con-
stant is going to change one day. You think there are 365 days in a year? Your customers on
Mars are going to be pretty unhappy about your silly prejudice. Make a constant

final int DAYS_PER_YEAR = 365;

By the way, the device

final int THREE_HUNDRED_AND_SIXTY_FIVE = 365;

is counterproductive and frowned upon.

You already saw how to add, subtract, and multiply values. Division is indicated with a ^{/},
not a fraction bar. For example,

becomes

(a + b) / 2

Parentheses are used just as in algebra: to indicate in which order the subexpressions
should be computed. For example, in the expression (a + b) / 2, the sum ^{a + b} is
computed first, and then the sum is divided by 2. In contrast, in the expression

a + b / 2

**Quality Tip** 3.2

**3.4** **Arithmetic and Mathematical Functions**

*a**b*
---2

only ^{b} is divided by 2, and then the sum of ^{a} and ^{b / 2} is formed. Just as in regular alge-
*braic notation, multiplication and division bind more strongly than*
addition and subtraction. For example, in the expression ^{a + b / 2},
the ^{/} is carried out first, even though the ^{+} operation occurs further to
the left.

Division works as you would expect, as long as at least one of the numbers involved is a floating-point number. That is,

7.0 / 4.0 7 / 4.0 7.0 / 4

*all yield 1.75. However, if both numbers are integers, then the result of the division is*
always an integer, with the remainder discarded. That is,

7 / 4

evaluates to 1, because 7 divided by 4 is 1 with a remainder of 3 (which is discarded).

This can be a source of subtle programming errors—see Common Error 3.1.

If you are interested only in the remainder of an integer division, use the ^{%} operator:

7 % 4

is 3, the remainder of the integer division of 7 by 4. The ^{%} symbol has no
analog in algebra. It was chosen because it looks similar to ^{/}, and the
remainder operation is related to division.

Here is a typical use for the integer ^{/} and ^{%} operations. Suppose you
want to know the value of the coins in a purse in dollars and cents. You can compute the value
as an integer, denominated in cents, and then compute the whole dollar amount and the
remaining change:

final int PENNIES_PER_NICKEL = 5;

final int PENNIES_PER_DIME = 10;

final int PENNIES_PER_QUARTER = 25;

final int PENNIES_PER_DOLLAR = 100;

// compute total value in pennies

int total = nickels * PENNIES_PER_NICKEL + dimes * PENNIES_PER_DIME

+ quarters * PENNIES_PER_QUARTER;

// use integer division to convert to dollars, cents int dollars = total / PENNIES_PER_DOLLAR;

int cents = total % PENNIES_PER_DOLLAR;

For example, if ^{total} is 243, then ^{dollars} is set to 2 and ^{cents} to 43.

To take the square root of a number, you use the ^{Math.sqrt} method. For example,
is written as Math.sqrt(x)*. To compute x** ^{n}*, you write Math.pow(x, n). However,

*to compute x*

^{2}it is significantly more efficient simply to compute

^{x * x}.

*x*

If both arguments of the / operator are integers, the result is an integer and the remainder is discarded.

The % operator computes the remainder of a division.

**Integer Division**

It is unfortunate that Java uses the same symbol, namely ^{/}, for both integer and floating-point
division. These are really quite different operations. It is a common error to use integer divi-
sion by accident. Consider this program segment that computes the average of three integers.

int s1 = 5; // score of test 1 int s2 = 6; // score of test 2 int s3 = 3; // score of test 3

double average = (s1 + s2 + s3) / 3; // Error System.out.print("Your average score is ");

System.out.println(average);

What could be wrong with that? Of course, the average of ^{s1}, ^{s2}, and ^{s3} is

Here, however, the ^{/} does not mean division in the mathematical sense. It denotes
integer division, because the values s1 + s2 + s3 and ^{3} are both integers. For example,
if the scores add up to 14, the average is computed to be 4, the result of the integer divi-
sion of 14 by 3. That integer 4 is then moved into the floating-point variable ^{average}.
The remedy is to make the numerator or denominator into a floating-point number:

double total = s1 + s2 + s3;

double average = total / 3;

or

double average = (s1 + s2 + s3) / 3.0;

As you can see, the visual effect of the ^{/}, ^{Math.sqrt}, and
Math.pow notations is to flatten out mathematical terms. In algebra,
you use fractions, superscripts for exponents, and radical signs for
roots to arrange expressions in a compact two-dimensional form. In
Java, you have to write all expressions in a linear arrangement. For
example, the subexpression

of the quadratic formula becomes

(-b + Math.sqrt(b * b - 4 * a * c)) / (2 * a)

Figure 3 shows how to analyze such an expression. With complicated expressions like these,
it is not always easy to keep the parentheses ^{(}* ... *^{)} matched—see Common Error 3.2.

Table 1 shows additional methods of the ^{Math} class. Inputs and outputs are floating-
point numbers.

**Common Error** 3.1

*sˆ*1 *s*_{2} *s*_{3}
---3

*b* *b*^{2}4ac
2*a*
---
The Math class contains

methods sqrt and pow to compute square roots and powers.

**F i g u r e 3**

Analyzing an Expression

(–b + Math.sqrt(b * b – 4 * a * c)) / (2 * a)
*b*^{2}

*b*^{2}*– 4ac*
*b*^{2}*– 4ac*

*4ac* *2a*

*2a*
*–b +* *b*^{2}*– 4ac*

*–b +* *b*^{2}*– 4ac*

**Ta b l e 1**

Mathematical Methods

Math.pow(x, y) * x *^{y }*(x0, or x=0 and y0, or x0 and y is an integer)*
Math.sqrt(x) *Square root of x (0)*

*Sine of x (x in radians)*
*Cosine of x*

*Tangent of x*

Arc sine (sin^{–1}*x [–/2, /2], x [–1,1])*
Arc cosine (cos^{–1}*x[0,], x [–1,1])*
Arc tangent (tan^{–1}*x (–/2, /2))*

Arc tangent (tan^{–1}*(y/x) [–/2,/2], x may be 0*
*Convert x radians to degrees (i.e., returns x 180/)*
*Convert x degrees to radians (i.e., returns x /180)*

*e*^{x}

*Natural log (ln(x), x >0)*
Math.sin(x)

Math.cos(x) Math.tan(x) Math.asin(x) Math.acos(x) Math.atan(x) Math.atan2(y, x) Math.toRadians(x) Math.toDegrees(x) Math.exp(x) Math.log(x)

*Closest integer to x (as a *^{long})
Math.round(x)

Smallest integer x (as a ^{double})
Math.ceil(x)

Largest integer x (as a ^{double})
Math.floor(x)

*Absolute value |x|*

Math.abs(x)

**Function** **Returns**

**Unbalanced Parentheses**
Consider the expression

1.5 * ((-(b - Math.sqrt(b * b - 4 * a * c)) / (2 * a))

What is wrong with it? Count the parentheses. There are five opening parentheses ^{(} and
four closing parentheses ^{)}*. The parentheses are unbalanced. This kind of typing error is*
very common with complicated expressions. Now consider this expression.

1.5 * (Math.sqrt(b * b - 4 * a * c))) - ((b / (2 * a))

This expression has five opening parentheses ^{(} and five closing parentheses ^{)}, but it is
still not correct. In the middle of the expression,

1.5 * (Math.sqrt(b * b - 4 * a * c))) - ((b / (2 * a))

there are only two opening parentheses ^{(} but three closing parentheses ^{)}, which is an
error. In the middle of an expression, the count of opening parentheses ^{(} must be greater
than or equal to the count of closing parentheses ^{)}, and at the end of the expression the
two counts must be the same.

Here is a simple trick to make the counting easier without using pencil and paper. It is difficult for the brain to keep two counts simultaneously, so keep only one count when scanning the expression. Start with 1 at the first opening parenthesis; add 1 whenever you see an opening parenthesis; and subtract 1 whenever you see a closing parenthesis.

Say the numbers aloud as you scan the expression. If the count ever drops below zero, or if it is not zero at the end, the parentheses are unbalanced. For example, when scanning the previous expression, you would mutter

1.5 * (Math.sqrt(b * b - 4 * a * c) ) ) - ((b / (2 * a))
1** ** 2** ** ** **1 0 –1

and you would find the error.

**On-Line Help **

The Java library has hundreds of classes and thousands of methods. It is neither necessary nor useful trying to memorize them. Instead, you should become familiar with using the on-line documentation. You can download the documentation from http://java.sun.com/

j2se/1.3/docs.html. Install the documentation set and point your browser to your Java installation directory /docs/api/index.html. Alternatively, you can browse http://

java.sun.com/j2se/1.3/docs/api/index.html. For example, if you are not sure how the ^{pow}
method works, or cannot remember whether it was called ^{pow} or ^{power}, the on-line help

**Common Error** 3.2

**Productivity Hint** 3.2

can give you the answer quickly. Click on the ^{Math} class in the class window on the left, and
look at the method summary in the main window (see Figure 4).

If you use ^{javadoc} to document your own classes, then this documentation format
will look extremely familiar to you. The programmers who implement the Java library
use ^{javadoc} themselves. They too document every class, every method, every parame-
ter, and every return value, and then use ^{javadoc} to extract the documentation in
HTML format.

**White Space**

The compiler does not care whether you write your entire program onto a single line or place every symbol onto a separate line. The human reader, though, cares very much. You should use blank lines to group your code visually into sections. For example, you can signal to the reader that an output prompt and the corresponding input statement belong together by inserting a blank line before and after the group. You will find many exam- ples in the source code listings in this book.

White space inside expressions is also important. It is easier to read x1 = (-b + Math.sqrt(b * b - 4 * a * c)) / (2 * a);

**F i g u r e 4**
On-Line Help

**Quality Tip** 3.3

than

X1=(-b+Math.sqrt(b*b-4*a*c))/(2*a);

Simply put spaces around all operators + - * / % =. However, don’t put a space after
*a unary minus: a *^{-} used to negate a single quantity, as in ^{-b}. That way, it can be easily
*distinguished from a binary minus, as in *^{a - b}. Don’t put spaces between a method
name and the parentheses, but do put a space after every Java keyword. That makes
it easy to see that the ^{sqrt} in Math.sqrt(x) is a method name, whereas the ^{if} in
if (x > 0)... is a keyword.

**Factor Out Common Code**

*Suppose you want to find both solutions of the quadratic equation ax*^{2}* + bx + c = 0. The*
*quadratic formula tells us that the solutions are *

In Java, there is no analog to the operation, which indicates how to obtain two solutions simultaneously. Both solutions must be computed separately:

x1 = (-b + Math.sqrt(b * b - 4 * a * c)) / (2 * a);

x2 = (-b - Math.sqrt(b * b - 4 * a * c)) / (2 * a);

This approach has two problems. First, the computation of Math.sqrt(b * b - 4 * a * c)
is carried out twice, which wastes time. Second, whenever the same code is replicated, the
*possibility of a typing error increases. The remedy is to factor out the common code:*

double root = Math.sqrt(b * b - 4 * a * c);

x1 = (-b + root) / (2 * a);

x2 = (-b - root) / (2 * a);

You could go even further and factor out the computation of ^{2 * a}, but the gain from
factoring out very simple computations is too small to warrant the effort.

In the preceding section, you encountered the ^{Math} class, which contains a collection of
helpful methods for carrying out mathematical computations.

There is one important difference between the methods of the ^{Math} class, such as the
sqrt method, and the methods that you have seen so far (such as ^{getTotal} or

**Quality Tip** 3.4

*x*_{1,2} *b* *b*^{2}4*ac*
---2a

**3.5** **Calling Static Methods**

println). The ^{getTotal} and ^{println} methods, as you have seen, operate on an object
such as ^{myPurse} or ^{System.out}. In contrast, the ^{sqrt} method does not operate on any
object. That is, you don’t call

double x = 4;

double root = x.sqrt(); // Error

The reason is that, in Java, numbers are not objects, so you can never
invoke a method on a number. Instead, you pass a number as an
explicit parameter to a method, enclosing the number in parentheses
after the method name. For example, the number value ^{x} can be a
parameter of the ^{Math.sqrt} method: Math.sqrt(x).

This call makes it appear as if the ^{sqrt} method is applied to an object called
Math, because ^{Math} precedes ^{sqrt} just as ^{myPurse} precedes ^{getTotal} in a method
call myPurse.getTotal(). However, ^{Math} is a class, not an object. A method such
as ^{Math.round}* that does not operate on any object is called a static method. (The*
term “static” is a historical holdover from C and C++ that has nothing to do with
the usual meaning of the word.) Static methods do not operate on objects, but they
are still defined inside classes. You must specify the class to which the ^{sqrt} method
belongs—hence the call is Math.sqrt(x).

How can you tell whether ^{Math} is a class or an object? All classes in the Java
library start with an uppercase letter (such as ^{System}). Objects and methods
start with a lowercase letter (such as ^{out} and ^{println}). You can tell objects and
methods apart because method calls are followed by parentheses. Therefore,
System.out.println() denotes a call of the ^{println} method on the ^{out} object
inside the ^{System} class. On the other hand, Math.sqrt(x) denotes a call to the
sqrt method inside the ^{Math} class. This use of upper- and lowercase letters is merely
*a convention, not a rule of the Java language. It is, however, a convention that the*
authors of the Java class libraries follow consistently. You should do the same in your
programs. If you give names to objects or methods that start with an uppercase let-
ter, you will likely confuse your fellow programmers. Therefore, we strongly recom-
mend that you follow the standard naming convention.

**Syntax 3.2 : Static** **Method Call**

*ClassName*.*methodName*^{(}*parameters*^{)}

**Example:**

Math.sqrt(4)
**Purpose:**

To invoke a static method (a method that does not operate on an object) and supply its parameters

A static method does not operate on an object.

*When you make an assignment of an expression into a variable, the types of the variable*
*and the expression must be compatible. For example, it is an error to assign *

double total = "a lot"; // Error

because ^{total} is a floating-point variable and "a lot" is a string. It is, however, legal to
store an integer expression in a ^{double} variable:

int dollars = 2;

double total = dollars; // OK

In Java, you cannot assign a floating-point expression to an integer variable.

double total = . . .;

int dollars = total; // Error

*You must convert the floating-point value to integer with a cast:*

int dollars = (int)total;

The cast ^{(int)} converts the floating-point value ^{total} to an integer.

The effect of the cast is to discard the fractional part. For example, if
total is 13.75, then ^{dollars} is set to 13. If you want to convert the
value of a floating-point expression to an integer, you need to enclose
the expression in parentheses to ensure that it is computed first:

int pennies = (int)(total * 100);

This is different from the expression int pennies = (int)total * 100;

In the second expression, ^{total}* is first converted to an integer, and then the resulting*
integer is multiplied by 100. For example, if ^{total} is 13.75, then the first expression
computes total * 100, or 1375, and then converts that value to the integer 1375. In
the second expression, ^{total} is first cast to the integer 13, and then the integer is multi-
*plied by 100, yielding 1300. Normally, you will want to apply the integer conversion after*
all other computations, so that your computations use the full precision of their input
values. That means you should enclose your computation in parentheses and apply the
cast to the expression in parentheses.

There is a good reason why you must use a cast in Java when you convert a floating-
*point number to an integer: The conversion loses information. You must confirm that you*
agree to that information loss. Java is quite strict about this. You must use a cast when-
ever there is the possibility of information loss. A cast always has the form ^{(}*typeName*^{)},
for example ^{(int)} or ^{(float)}.

Actually, simply using an ^{(int)} cast to convert a floating-point number to an integer
is not always a good idea. Consider the following example:

double price = 44.95;

int dollars = (int)price; // sets dollars to 44

**3.6** **Type Conversion**

You use a cast (typeName) to convert a value to a different type.

What did you want to achieve? Did you want to get the number of dollars in the price?

Then dropping the fractional part is the right thing to do. Or did you want to get the
*approximate dollar amount? Then you really want to round up when the fractional part is*
0.5 or larger.

One way to round to the nearest integer is to add 0.5, then cast to an integer:

double price = 44.95;

int dollars = (int)(price + 0.5); // OK for positive values System.out.print("The price is approximately $")

System.out.println(dollars); // prints 45

Adding 0.5 and casting to the ^{int} type works, because it turns all
*values that are between 44.50 and 45.4999... into 45. *

Actually, there is a better way. Simply adding 0.5 works fine for positive numbers, but it doesn’t work correctly for negative numbers.

Instead, use the ^{Math.round} method in the standard Java library. It
works for both positive and negative numbers. However, that
method returns a ^{long} integer, because large floating-point numbers
cannot be stored in an ^{int}. You need to cast the return value to an ^{int}:

int dollars = (int)Math.round(price); // better

**Carrying Out Computations**

Many programming problems require that you use mathematical formulas to compute values. It is not always obvious how to turn a problem statement into a sequence of mathematical formulas and, ultimately, statements in the Java programming language.

**Step 1 **

Understand the problem: What are the inputs? What are the desired outputs?
For example, suppose you are asked to simulate a postage stamp vending machine. A customer inserts money into the vending machine. Then the customer pushes a “First class stamps”

**Syntax 3.3 : Cast**

(*typeName*) *expression*
**Example:**

(int)(x + 0.5)

(int)Math.round(100 * f)
**Purpose:**

To convert an expression to a different type

**HOWTO** 3.1

Use the Math.round method to round a floating-point number to the nearest integer.

button. The vending machine gives out as many first-class stamps as the customer paid for. (A first-class stamp cost 34 cents at the time this book was written.) Finally, the customer pushes a “Penny stamps” button. The machine gives the change in penny (1-cent) stamps.

In this problem, there is one input:

The amount of money the customer inserts There are two desired outputs:

The number of first-class stamps that the machine returns

The number of penny stamps that the machine returns

**Step 2 **

Work out examples by hand
This is a very important step. If you can’t compute a couple of solutions by hand, it’s unlikely that you’ll be able to write a program that automates the computation.

Let’s assume that a first-class stamp costs 34 cents and the customer inserts $1.00.

That’s enough for two stamps (68 cents) but not enough for three stamps ($1.02).

Therefore, the machine returns 2 first-class stamps and 32 penny stamps.

**Step 3 **

Find mathematical equations that compute the answers
Given an amount of money and the price of a first-class stamp, how can you compute how many first-class stamps can be purchased with the money? Clearly, the answer is related to the quotient

For example, suppose the customer paid $1.00. Use a pocket calculator to compute the quotient: $1.00/$0.34 ≈ 2.9412.

How do you get “2 stamps” out of 2.9412? It’s the integer part. By discarding the fractional part, you get the number of whole stamps that the customer has purchased.

In mathematical notation,

where *x denotes the largest integer ≤ x. That function is sometimes called the “floor*
function”.

You now know how to compute the number of stamps that are given out when the customer pushes the “First-class stamps” button. When the customer gets the stamps, the amount of money is reduced by the value of the stamps purchased. For example, if the customer gets two stamps, the remaining money is $0.32. It is the difference between

$1.00 and 2 $0.34. Here is the general formula:

remaining money money − number of first-class stamps price of first-class stamp How many penny stamps does the remaining money buy? That’s easy. If $0.32 is left, the customer gets 32 stamps. In general, the number of penny stamps is

number of penny stamps 100 remaining money

amount of money price of first-class stamp ---

number of first-class stamps money

price of first-class stamp ---

**Step 4 **

Turn the mathematical equations into Java statements
In Java, you can compute the integer part of a nonnegative floating-point value by apply-
ing an ^{(int)} cast. Therefore, you can compute the number of first-class stamps with the
following statement:

firstClassStamps =

(int)(money / FIRST_CLASS_STAMP_PRICE);

money = money -

firstClassStamps * FIRST_CLASS_STAMP_PRICE;

Finally, the number of penny stamps is pennyStamps = 100 * money;

That’s not quite right, though. The value of pennyStamps should be an integer, but the right hand side is a floating-point number. Therefore, the correct statement is

pennyStamps = (int)Math.round(100 * money);

**Step 5 **

Build a class that carries out your computations
HOWTO 2.1 explains how to develop a class by finding methods and instance variables.

In our case, we can find three methods:

void insert(double amount)

int giveFirstClassStamps()

int givePennyStamps()

The state of a vending machine can be described by the amount of money that the cus-
tomer has available for purchases. Therefore, we supply one instance variable, ^{money}.

Here is the implementation:

public class StampMachine {

public StampMachine() {

money = 0;

}

public void insert(double amount) {

money = money + amount;

}

public int giveFirstClassStamps() {

int firstClassStamps =

(int)(money / FIRST_CLASS_STAMP_PRICE);

money = money -

firstClassStamps * FIRST_CLASS_STAMP_PRICE;