# Numerical Data Confirming Pages

```wu23305_ch03.qxd
12/31/08
12:54 PM
Page 85
Confirming Pages
Numerical Data
3
O b j e c t i v e s
After you have read and studied this chapter, you
should be able to
• Select proper types for numerical data.
• Write arithmetic expressions in Java.
arithmetic expressions, following the
• Evaluate
precedence rules.
how the memory allocation works for
• Describe
objects and primitive data values.
mathematical expressions, using
• Write
methods in the Math class.
the GregorianCalendar class in
• Use
manipulating date information such as year,
month, and day.
the DecimalFormat class to format
• Use
numerical data.
• Convert input string values to numerical data.
numerical data by using System.in and
• Input
output numerical data by using System.out.
the incremental development technique
• Apply
in writing programs.
Describe how the integers and real
• (Optional)
numbers are represented in memory.
85
wu23305_ch03.qxd
86
12/31/08
Chapter 3
12:54 PM
Page 86
Confirming Pages
Numerical Data
I n t r o d u c t i o n
W
hen we review the Ch2Monogram sample program, we can visualize three tasks:
input, computation, and output. We view computer programs as getting input, performing computation on the input data, and outputting the results of the computations. The type of computation we performed in Chapter 2 is string processing. In
this chapter, we will study another type of computation, the one that deals with
numerical data. Consider, for example, a metric converter program that accepts
measurements in U.S. units (input), converts the measurements (computation), and
displays their metric equivalents (output). The three tasks are not limited to numerical or string values, though. An input could be a mouse movement. A drawing program may accept mouse dragging (input), remember the points of mouse positions
(computation), and draw lines connecting the points (output). Selecting a menu item
is yet another form of input. For beginners, however, it is easiest to start writing
programs that accept numerical or string values as input and display the result of
computation as output.
We will introduce more standard classes to reinforce the object-oriented style
of programming. The Math class includes methods we can use to express mathematical formulas. The DecimalFormat class includes a method to format numerical
data so we can display the data in a desired precision. The GregorianCalendar class
includes methods to manipulate the date. The Random class includes methods to
generate different types of random numbers. In Chapter 2, we performed String
input and output by using the standard input (Scanner) and output (System.out). We
will describe the input and output routines for numerical data in this chapter.
Finally, we will continue to employ the incremental development technique
introduced in Chapter 2 in developing the sample application, a loan calculator program. As the sample program gets more complex, well-planned development steps
will smooth the development effort.
3.1 Variables
Suppose we want to compute the sum and difference of two numbers. Let’s call the
two numbers x and y. In mathematics, we say
x + y
and
x – y
To compute the sum and the difference of x and y in a Java program, we must first
declare what kind of data will be assigned to them. After we assign values to them,
we can compute their sum and difference.
Let’s say x and y are integers. To declare that the type of data assigned to them
is an integer, we write
int
x, y;
wu23305_ch03.qxd
12/31/08
12:54 PM
Confirming Pages
Page 87
3.1 Variables
variable
87
When this declaration is made, memory locations to store data values for x and y are
allocated. These memory locations are called variables, and x and y are the names
we associate with the memory locations. Any valid identifier can be used as a variable name. After the declaration is made, we can assign only integers to x and y. We
cannot, for example, assign real numbers to them.
A variable has three properties: a memory location to store the value, the type of
data stored in the memory location, and the name used to refer to the memory
location.
Although we must say “x and y are variable names” to be precise, we will use the
abbreviated form “x and y are variables” or “x and y are integer variables” whenever
appropriate.
The general syntax for declaring variables is
variable
declaration
syntax
<data type>
<variables> ;
where <variables> is a sequence of identifiers separated by commas. Every variable
we use in a program must be declared. We may have as many declarations as we
wish. For example, we can declare x and y separately as
int
int
x;
y;
However, we cannot declare the same variable more than once; therefore, the second declaration below is invalid because y is declared twice:
int
int
six numerical
data types
higher
precision
x, y, z;
y;
There are six numerical data types in Java: byte, short, int, long, float, and
double. The data types byte, short, int, and long are for integers; and the data types
float and double are for real numbers. The data type names byte, short, and others
are all reserved words. The difference among these six numerical data types is in
the range of values they can represent, as shown in Table 3.1.
A data type with a larger range of values is said to have a higher precision. For
example, the data type double has a higher precision than the data type float. The
tradeoff for higher precision is memory space—to store a number with higher precision, you need more space. A variable of type short requires 2 bytes and a variable
of type int requires 4 bytes, for example. If your program does not use many
integers, then whether you declare them as short or int is really not that critical. The
difference in memory usage is very small and not a deciding factor in the program
wu23305_ch03.qxd
88
12/31/08
Chapter 3
Table
Table 3.1
†
‡
12:54 PM
Confirming Pages
Page 88
Numerical Data
Java numerical data types and their precisions
Data
Type
Content
byte
short
int
long
float
double
Integer
Integer
Integer
Integer
Real
Real
Default
Value†
Minimum Value
0
0
0
0
0.0
0.0
128
32768
2147483648
9223372036854775808
3.40282347E+38‡
1.79769313486231570E+308
Maximum Value
127
32767
2147483647
9223372036854775807
3.40282347E+38
1.79769313486231570E+308
No default value is assigned to a local variable. A local variable is explained on page 191 in Section 4.8.
The character E indicates a number is expressed in scientific notation. This notation is explained on page 100.
design. The storage difference becomes significant only when your program uses
thousands of integers. Therefore, we will almost always use the data type int for integers. We use long when we need to process very large integers that are outside the
range of values int can represent. For real numbers, it is more common to use double. Although it requires more memory space than float, we prefer double because
of its higher precision in representing real numbers. We will describe how the numbers are stored in memory in Section 3.10.
Application programs we develop in this book are intended for computers with
a large amount of memory (such as desktops or laptops), so the storage space is
not normally a major concern because we have more than enough. However,
when we develop applications for embedded or specialized devices with a very
limited amount of memory, such as PDAs, cellular phones, mobile robots for
Mars exploration, and others, reducing the memory usage becomes a major
concern.
Here is an example of declaring variables of different data types:
int
float
long
double
i, j, k;
numberOne, numberTwo;
bigInteger;
bigNumber;
At the time a variable is declared, it also can be initialized. For example, we may
initialize the integer variables count and height to 10 and 34 as in
int count = 10, height = 34;
wu23305_ch03.qxd
12/31/08
12:54 PM
Page 89
Confirming Pages
3.1 Variables
89
As we mentioned in Chapter 2, you can declare and create an object just as you
can initialize variables at the time you declare them. For example, the declaration
Date today = new Date();
is equivalent to
Date today;
today = new Date();
assignment
statement
We assign a value to a variable by using an assignment statement. To assign
the value 234 to the variable named firstNumber, for example, we write
firstNumber = 234;
Be careful not to confuse mathematical equality and assignment. For example, the
following are not valid Java code:
rsion
e
V
4 + 5 = x;
x + y = y + x;
The syntax for the assignment statement is
assignment
statement
syntax
<variable> = <expression> ;
where <expression> is an arithmetic expression, and the value of <expression> is
assigned to the <variable>. The following are sample assignment statements:
sum
solution
average
= firstNumber + secondNumber;
= x * x - 2 * x + 1;
= (x + y + z) / 3.0;
We will present a detailed discussion of arithmetic expressions in Section 3.2. One
key point we need to remember about variables is the following:
Before using a variable, we must first declare and assign a value to it.
The diagram in Figure 3.1 illustrates the effect of variable declaration and assignment. Notice the similarity with this and memory allocation for object declaration and creation, illustrated in Figure 2.4 on page 36. Figure 3.2 compares the two.
wu23305_ch03.qxd
90
12/31/08
Chapter 3
12:54 PM
Page 90
Confirming Pages
Numerical Data
State of Memory
A
int firstNumber, secondNumber;
firstNumber = 234;
secondNumber = 87;
after A is executed
firstNumber
secondNumber
The variables firstNumber and secondNumber
are declared and set in memory.
int firstNumber, secondNumber;
B
firstNumber = 234;
secondNumber = 87;
after B is executed
firstNumber
234
secondNumber
87
Values are assigned to the variables firstNumber
and secondNumber.
Figure 3.1 A diagram showing how two memory locations (variables) with names firstNumber and
secondNumber are declared, and values are assigned to them.
What we have been calling object names are really variables. The only difference
between a variable for numbers and a variable for objects is the contents in the memory locations. For numbers, a variable contains the numerical value itself; and for
objects, a variable contains an address where the object is stored. We use an arrow
in the diagram to indicate that the content is an address, not the value itself.
Object names are synonymous with variables whose contents are references to
Figure 3.3 contrasts the effect of assigning the content of one variable to another variable for numerical data values and for objects. Because the content of a
variable for objects is an address, assigning the content of a variable to another
makes two variables that refer to the same object. Assignment does not create a new
object. Without executing the new command, no new object is created. We can view
the situation in which two variables refer to the same object as the object having two
distinct names.
wu23305_ch03.qxd
12/31/08
12:54 PM
Confirming Pages
Page 91
3.1 Variables
Numerical Data
Object
int number;
Customer customer;
number = 237;
number = 35;
customer = new Customer();
customer = new Customer();
number
91
customer
int number;
Customer customer;
number = 237;
customer = new Customer();
number = 35;
customer = new Customer();
customer
number
237
:Customer
int number;
Customer customer;
number = 237;
customer = new Customer();
number = 35;
customer = new Customer();
customer
number
35
:Customer
:Customer
Figure 3.2 A difference between object declaration and numerical data declaration.
For numbers, the amount of memory space required is fixed. The values for
data type int require 4 bytes, for example, and this won’t change. However, with objects, the amount of memory space required is not constant. One instance of the
Account class may require 120 bytes, while another instance of the same class may
require 140 bytes. The difference in space usage for the account objects would
occur if we had to keep track of checks written against the accounts. If one account
has 15 checks written and the second account has 25 checks written, then we need
more memory space for the second account than for the first account.
We use the new command to actually create an object. Remember that declaring an object only allocates the variable whose content will be an address. On the
wu23305_ch03.qxd
92
12/31/08
Chapter 3
12:54 PM
Confirming Pages
Page 92
Numerical Data
Numerical Data
Object
int number1, number2;
Professor alan, turing;
number1 = 237;
number2 = number1;
alan
= new Professor();
turing = alan;
number1
alan
number2
turing
int number1, number2;
Professor alan, turing;
number1 = 237;
alan
number2 = number1;
turing = alan;
number1
237
number2
= new Professor();
alan
turing
:Professor
int number1, number2;
number1 = 237;
Professor alan, turing;
alan
= new Professor();
number2 = number1;
turing = alan;
number1
237
alan
number2
237
turing
:Professor
Figure 3.3 An effect of assigning the content of one variable to another.
reference
versus
primitive data
types
other hand, we don’t “create” an integer because the space to store the value is
already allocated at the time the integer variable is declared. Because the contents
are addresses that refer to memory locations where the objects are actually stored,
objects are called reference data types. In contrast, numerical data types are called
primitive data types.
wu23305_ch03.qxd
12/31/08
12:54 PM
Confirming Pages
Page 93
3.1 Variables
In addition to the six numerical data types, there are two nonnumerical primitive
data types.The data type boolean is used to represent two logical values true and
false. For example, the statements
boolean raining;
raining = true;
assign the value true to a boolean variable raining. We will explain and start using
boolean variables beginning in Chapter 5. The second nonnumerical primitive
data type is char (for character). It is used to represent a single character (letter,
digit, punctuation marks, and others). The following example assigns the uppercase letter A to a char variable letter:
char letter;
letter = 'A';
A char constant is designated by single quotes. We will study the char data type in
Chapter 9 on string processing.
1. Why are the following declarations all invalid (color highlighting is disabled)?
int
float
float
bigNumber
a, b, a;
x, int;
w, int x;
double;
2. Assuming the following declarations are executed in sequence, why are the
second and third declarations invalid?
a, b;
a;
b;
int
int
float
3. Name six data types for numerical values.
4. Which of the following are valid assignment statements (assuming the
variables are properly declared)?
x
12
y + y
y
=
=
=
=
12;
x;
x;
x + 12;
5. Draw the state-of-memory diagram for the following code.
Account latteAcct, espressoAcct;
latteAcct
= new Account();
espressoAcct = new Account();
latteAcct
= espressoAcct;
93
wu23305_ch03.qxd
94
12/31/08
Chapter 3
12:54 PM
Confirming Pages
Page 94
Numerical Data
3.2 Arithmetic Expressions
An expression involving numerical values such as
23 + 45
arithmetic
operator
integer division
is called an arithmetic expression, because it consists of arithmetic operators and
operands. An arithmetic operator, such as + in the example, designates numerical
computation. Table 3.2 summarizes the arithmetic operators available in Java.
Notice how the division operator works in Java. When both numbers are integers, the result is an integer quotient. That is, any fractional part is truncated. Division between two integers is called integer division. When either or both numbers
are float or double, the result is a real number. Here are some division examples:
Division Operation
23
23
25.0
/
/
/
Result
5
5.0
5.0
4
4.6
5.0
The modulo operator returns the remainder of a division. Although real numbers can be used with the modulo operator, the most common use of the modulo
operator involves only integers. Here are some examples:
Modulo Operation
23
23
16
Table
Table 3.2
%
%
%
Result
5
25
2
3
23
0
Arithmetic operators
Operation
Java
Operator
Subtraction
Multiplication
Division
+
–
*
/
Modulo division
(remainder)
%
Example
x
x
x
x
x
x
+
–
*
/
/
%
y
y
y
y
z
y
Value
(x 10, y 7, z 2.5)
17
3
70
1
4.0
3
wu23305_ch03.qxd
12/31/08
12:54 PM
Confirming Pages
Page 95
3.2 Arithmetic Expressions
operand
95
The expression 23 % 5 results in 3 because 23 divided by 5 is 4 with remainder 3.
Notice that x % y = 0 when y divides x perfectly; for example, 16 % 2 = 0. Also notice
that x % y = x when y is larger than x; for example, 23 % 25 = 23.
An operand in arithmetic expressions can be a constant, a variable, a method
call, or another arithmetic expression, possibly surrounded by parentheses. Let’s
look at examples. In the expression
x + 4
binary operator
we have one addition operator and two operands—a variable x and a constant 4.
The addition operator is called a binary operator because it operates on two operands.
All other arithmetic operators except the minus are also binary. The minus and
plus operators can be both binary and unary. A unary operator operates on one
operand as in
–x
In the expression
x + 3 * y
subexpression
the addition operator acts on operands x and 3 * y. The right operand for the addition
operator is itself an expression. Often a nested expression is called a subexpression.
The subexpression 3 * y has operands 3 and y. The following diagram illustrates this
relationship:
3
y
x
precedence
rules
When two or more operators are present in an expression, we determine
the order of evaluation by following the precedence rules. For example, multiplication has a higher precedence than addition. Therefore, in the expression
x + 3 * y, the multiplication operation is evaluated first, and the addition operation
is evaluated next. Table 3.3 summarizes the precedence rules for arithmetic
operators.
wu23305_ch03.qxd
96
12/31/08
Chapter 3
Table
Table 3.3
12:54 PM
Confirming Pages
Page 96
Numerical Data
Precedence rules for arithmetic operators and parentheses
Order
Group
Operator
Rule
High
Subexpression
( )
Unary operator
-, +
Multiplicative
operator
*, /, %
+, -
Subexpressions are evaluated first. If
parentheses are nested, the innermost
subexpression is evaluated first. If two or
more pairs of parentheses are on the same
level, then they are evaluated from left to
right.
Unary minuses and pluses are evaluated
second.
Multiplicative operators are evaluated
third. If two or more multiplicative
operators are in an expression, then they
are evaluated from left to right.
Additive operators are evaluated last. If
two or more additive operators are in an
expression, then they are evaluated from
left to right.
Low
The following example illustrates the precedence rules applied to a complex
arithmetic expression:
a * (b + -(c / d) / e) * (f - g % h)
1
6
2
5
3
4
7
8
When an arithmetic expression consists of variables and constants of the same
data type, then the result of the expression will be that data type also. For example,
if the data type of a and b is int, then the result of the expression
a * b + 23
implicit and
explicit typecasting
is also an int. When the data types of variables and constants in an arithmetic expression are different data types, then a casting conversion will take place. A casting
conversion, or typecasting, is a process that converts a value of one data type to another data type. Two types of casting conversions in Java are implicit and explicit.
wu23305_ch03.qxd
12/31/08
12:54 PM
Confirming Pages
Page 97
3.2 Arithmetic Expressions
Table
Table 3.4
numeric
promotion
typecast
operator
97
Rules for arithmetic promotion
Operator Type
Promotion Rule
Unary
1. If the operand is of type byte or short, then it is
converted to int.
2. Otherwise, the operand remains the same type.
Binary
1. If either operand is of type double, then the other operand
is converted to double.
2. Otherwise, if either operand is of type float, then the other
operand is converted to float.
3. Otherwise, if either operand is of type long, then the other
operand is converted to long.
4. Otherwise, both operands are converted to int.
An implicit conversion called numeric promotion is applied to the operands of an
arithmetic operator. The promotion is based on the rules stated in Table 3.4. This
conversion is called promotion because the operand is converted from a lower to a
higher precision.
Instead of relying on implicit conversion, we can use explicit conversion to
convert an operand from one data type to another. Explicit conversion is applied to
an operand by using a typecast operator. For example, to convert the int variable x
in the expression
x / 3
to float so the result will not be truncated, we apply the typecast operator (float) as
(float) x / 3
The syntax is
typecasting
syntax
( <data type> ) <expression>
The typecast operator is a unary operator and has a precedence higher than that of
any binary operator. You must use parentheses to typecast a subexpression; for example, the expression
a + (double) (x + y * z)
will result in the subexpression x + y * z typecast to double.
Assuming the variable x is an int, then the assignment statement
x = 2 * (14343 / 2344);
will assign the integer result of the expression to the variable x. However, if the
data type of x is other than int, then an implicit conversion will occur so that the
wu23305_ch03.qxd
98
12/31/08
Chapter 3
12:54 PM
Confirming Pages
Page 98
Numerical Data
data type of the expression becomes the same as the data type of the variable. An
assignment conversion is another implicit conversion that occurs when the variable and the value of an expression in an assignment statement are not of the
same data type. An assignment conversion occurs only if the data type of the
variable has a higher precision than the data type of the expression’s value. For
example,
assignment
conversion
double number;
number = 25;
is valid, but
rsion
e
V
int number;
number = 234.56;
INVALID
is not.
In writing programs, we often have to increment or decrement the value of a
variable by a certain amount. For example, to increase the value of sum by 5, we
write
sum = sum + 5;
We can rewrite this statement without repeating the same variable on the left- and
right-hand sides of the assignment symbol by using the shorthand assignment
operator:
shorthand
assignment
operator
sum += 5;
Table 3.5 lists five shorthand assignment operators available in Java.
These shorthand assignment operators have precedence lower than that of any
other arithmetic operators; so, for example, the statement
sum *= a + b;
is equivalent to
sum = sum * (a + b);
Table
Table 3.5
Shorthand assignment operators
Operator
Usage
Meaning
+=
=
*=
/=
%=
a += b;
a = b;
a *= b;
a /= b;
a %= b;
a = a + b;
a = a b;
a = a * b;
a = a / b;
a = a % b;
wu23305_ch03.qxd
12/31/08
12:54 PM
Page 99
Confirming Pages
3.3 Constants
99
If we wish to assign a value to multiple variables, we can cascade the assignment
operations as
x = y = 1;
which is equivalent to saying
y = 1;
x = 1;
The assignment symbol = is actually an operator, and its precedence order is
lower than that of any other operators. Assignment operators are evaluated
right to left.
1. Evaluate the following expressions.
a.
b.
c.
d.
3
3
3
2
+
*
+
*
5 / 7
3 + 3 % 2
2 / 5 + -2 * 4
(1 + -(3/4) / 2) * (2 - 6 % 3)
2. What is the data type of the result of the following expressions?
a. (3 + 5) / 7
b. (3 + 5) / (float) 7
c. (float) ( (3 + 5) / 7 )
3. Which of the following expressions is equivalent to b(c 34)(2a)?
a. -b * (c + 34) / 2 * a
b. -b * (c + 34) / (2 * a)
c. -b * c + 34 / (2 * a)
4. Rewrite the following statements without using the shorthand operators.
a. x += y;
b. x *= v + w;
c. x /= y;
3.3 Constants
constant
While a program is running, different values may be assigned to a variable at different times (thus the name variable, since the values it contains can vary), but in
some cases we do not want this to happen. In other words, we want to “lock” the
assigned value so that no changes can take place. If we want a value to remain fixed,
then we use a constant. A constant is declared in a manner similar to a variable but
wu23305_ch03.qxd
100
12/31/08
Chapter 3
12:54 PM
Confirming Pages
Page 100
Numerical Data
with the additional reserved word final. A constant must be assigned a value at the
time of its declaration. Here’s an example of declaring four constants:
final
final
final
final
named
constant
literal constant
double PI = 3.14159;
short
FARADAY_CONSTANT = 23060; // unit is cal/volt
double CM_PER_INCH = 2.54;
int
MONTHS_IN_YEAR = 12;
We follow the standard Java convention to name a constant, using only capital letters and underscores. Judicious use of constants makes programs more readable. You will be seeing many uses of constants later in the book, beginning with the
sample program in this chapter.
The constant PI is called a named constant or symbolic constant. We refer to
symbolic constants with identifiers such as PI and FARADAY_CONSTANT. The second type of constant is called a literal constant, and we refer to it by using an actual
value. For example, the following statements contain three literal constants:
final double
PI
= 3.14159 ;
double area;
area = 2 * PI * 345.79 ;
Literal constants
When we use the literal constant 2, the data type of the constant is set to int by
default. Then how can we specify a literal constant of type long?1 We append the
constant with an l (a lowercase letter L) or L as in
2L * PI * 345.79
How about the literal constant 345.79? Since the literal constant contains a
decimal point, its data type can be only float or double. But which one? The answer
is double. If a literal constant contains a decimal point, then it is of type double by
default. To designate a literal constant of type float, we must append the letter f or
F. For example,
2 * PI * 345.79F
To represent a double literal constant, we may optionally append a d or D. So
the following two constants are equivalent:
2 * PI * 345.79
is equivalent to
2 * PI * 345.79D
We also can express float and double literal constants in scientific notation as
Number 10exponent
1
In most cases, it is not significant to distinguish the two because of automatic type conversion; see Section 3.2.
wu23305_ch03.qxd
12/31/08
12:54 PM
Page 101
Confirming Pages
3.4 Displaying Numerical Values
exponential
notation in
Java
101
which in Java is expressed as
<number> E <exponent>
Since a numerical constant such as 345.79 represents a double value, these
statements
float number;
number = 345.79;
for example, would result in a compilation error. The data types do not match,
and the variable (float) has lower precision than that of the constant (double).
To correct this error, we have to write the assignment statement as
number = 345.79f;
or
number = (float) 345.79;
This is one of the common errors that people make in writing Java programs, especially those with prior programming experience.
where <number> is a literal constant that may or may not contain a decimal point
and <exponent> is a signed or an unsigned integer. Lowercase e may be substituted
for the exponent symbol E. The whole expression may be suffixed by f, F, d, or D.
The <number> itself cannot be suffixed with symbols f, F, d, or D. Here are some
examples:
12.40e+209
23E33
29.0098e–102
234e+5D
4.45e2
Here are some additional examples of constant declarations:
final double SPEED_OF_LIGHT = 3.0E+10D; // unit is cm/s
final short MAX_WGT_ALLOWED = 400;
3.4 Displaying Numerical Values
In Chapter 2, we learned how to output string values to the console window
by using System.out. We can easily output numerical values to the console window
wu23305_ch03.qxd
102
12/31/08
Chapter 3
12:54 PM
Page 102
Confirming Pages
Numerical Data
as well. We will use the same print and println methods to output numerical values.
Here’s a simple example that outputs the values of a constant and a variable:
int num = 15;
System.out.print(num); //print a variable
System.out.print(" "); //print a blank space
System.out.print(10); //print a constant
Executing the code will result in the following console window:
15 10
Console
Window
We can use the println method to skip a line after printing out the value.
Executing
int num = 15;
System.out.println(num);
System.out.println(10);
will result in
Console
Window
15
10
By using the concatenation operation, it is possible to output multiple values
with a single print or println method. For example, the statement
System.out.print(30 + " " + 40);
is equivalent to
System.out.print(30);
System.out.print(" ");
System.out.print(40);
Notice that the expression
30 + " " + 40
mixes numerical values and a string. We learned in Chapter 2 that the plus symbol
is used to concatenate strings, for example,
"Benjamin" + " " + "Franklin"
wu23305_ch03.qxd
12/31/08
12:54 PM
Page 103
Confirming Pages
103
3.4 Displaying Numerical Values
And, in this chapter, we learned the same plus symbol is used to add numerical
values, for example,
4 + 36
operator
The plus symbol, therefore, could mean two different things: string concatenation
or numerical addition. When a symbol is used to represent more than one operation,
What happens when the plus symbol appears in a mixed expression? When the
Java compiler encounters an overloaded operator, the compiler determines the meaning of a symbol by its context. If the left operand and the right operand of the plus
symbol are both numerical values, then the compiler will treat the symbol as addition;
otherwise, it will treat the symbol as concatenation. The plus symbol operator is evaluated from left to right, and the result of concatenation is a string, so the code
int x = 1;
int y = 2;
String output = "test" + x + y;
"test"
1
"test1"
will result in output being set to
2
test12
"test12"
while the statement
String output = x + y + "test";
will result in output being set to
1
2
3
"test"
3test
"3test"
To get the result of test3, we have to write the statement as
String output = "test" + (x + y);
so the arithmetic addition is performed first.
Now let’s look at a small sample program that illustrates a typical use of
string concatenation in displaying computation results. In this sample program, we
compute the circumference and the area of a circle with a given radius. The value
for the radius is assigned in the program (we will discuss how to input this value in
Section 3.5). Here’s the program:
/*
Chapter 3 Sample Program: Compute Area and Circumference
File: Ch3Circle.java
*/
wu23305_ch03.qxd
104
12/31/08
Chapter 3
12:54 PM
Page 104
Confirming Pages
Numerical Data
class Ch3Circle {
public static void main(String[] args) {
final double PI = 3.14159;
//compute the area and circumference
area
circumference = 2.0 * PI * radius;
System.out.println("Area: " + area);
System.out.println("Circumference: " + circumference);
}
}
When we run this program, we get the following output:
Console
Window
Area: 17.349430775000002
Circumference: 14.765473
Notice the precision of decimal places displayed for the results, especially the one
for the circumference. Although we desire such a high level of precision provided
by double values during the computation, we may not when displaying the result.
We can restrict the number of decimal places to display by using the DecimalFormat
class from the java.text package.
Although the full use of the DecimalFormat class can be fairly complicated,
it is very straightforward if all we want is to limit the number of decimal places
to be displayed. To limit the decimal places to three, for example, we create a
DecimalFormat object as
DecimalFormat df = new DecimalFormat("0.000");
and use it to format the number as
double num = 234.5698709;
System.out.println("Num: " + df.format(num));
When we add an instance of the DecimalFormat class named df and change
the output statement of the Ch3Circle class to
System.out.println("Area: " + df.format(area));
System.out.println("Circumference: "
+ df.format(circumference));
wu23305_ch03.qxd
12/31/08
12:54 PM
Page 105
Confirming Pages
3.4 Displaying Numerical Values
105
we produce the following result:
Console
Window
new-line
control
character
Area: 17.349
Circumference: 14.765
The modified class is named Ch3Circle2 (not shown here).
Instead of using one println method per line of output, it is possible to output
multiple lines with a single println or print method by embedding a new-line control
character in the output. We briefly mentioned a control character in Section 2.4.4. A
control character is for controlling the output, and we use the backslash symbol to
denote a control character. The new-line control character is denoted as \n and has the
effect of pressing the Enter key in the output. For example, the statements
System.out.println("Area: " + area);
System.out.println("Circumference: " + circumference);
can be written by using only one println statement as
"Area: " + area
+ "\n" +
"Circumference: " + circumference);
There is no limit to the number of new-line control characters you can embed, so we
can easily skip two lines, for example, by putting two new-line control characters as
follows:
System.out.println("Number 1: " + num1 + "\n\n" +
"Number 2: " + num2);
tab
control
character
Another useful control character is a tab, which is denoted as \t. We can use
the tab control character to output the labels, and this results in two columns as
follows:
"Area: " + "\t\t" + area + "\n" +
"Circumference: " + "\t" + circumference);
Notice there are two tabs before we output the area. You need to experiment with
the actual number of tabs to get the right output (the actual number of spaces used
for each tab could be different depending on your Java IDE). The resulting output
will be
Console
Window
Area:
17.349430775000002
Circumference: 14.765473
wu23305_ch03.qxd
106
12/31/08
Chapter 3
12:54 PM
Page 106
Confirming Pages
Numerical Data
You can also adjust the output format by appending blank spaces in the label.
For example, you can rewrite the sample statement as
"Area:
" + "\t" + area + "\n" +
"Circumference: " + "\t" + circumference);
And, as always, the use of symbolic constants will clean up the code:
...
final String TAB = "\t";
final String NEWLINE = "\n";
...
System.out.println(
"Area:
" + TAB + area
+ NEWLINE +
"Circumference: " + TAB + circumference);
The new program that illustrates the use of both DecimalFormat and control characters is named Ch3Circle3. Here’s the program:
/*
Chapter 3 Sample Program: Compute Area and Circumference
File: Ch3Circle3.java
*/
import java.text.*;
class Ch3Circle3 {
public static void main(String[] args) {
final double PI = 3.14159;
final String TAB = "\t";
final String NEWLINE = "\n";
DecimalFormat df = new DecimalFormat("0.000");
//compute the area and circumference
area
circumference = 2.0 * PI * radius;
//Display the results
System.out.println(
wu23305_ch03.qxd
12/31/08
12:54 PM
Confirming Pages
Page 107
3.5 Getting Numerical Input
107
"Area:
" + TAB + df.format(area)
+ NEWLINE +
"Circumference: " + TAB + df.format(circumference));
}
}
1. What is the purpose of the control characters?
2. Which control character is used for a new line?
3. Using one print statement, output the following:
Hello, world!
My favorite Ben Franklin quote:
An investment in knowledge
always pays the best interest.
3.5 Getting Numerical Input
We learned how to input string values by using the Scanner class in Chapter 2. We
study how to input numerical values with the Scanner class in this section. To input
strings, we use the next method of the Scanner class. For the numerical input values,
we use an equivalent method that corresponds to the data type of the value we try
to input. For instance, to input an int value, we use the nextInt method. Here’s an
example of inputting a person’s age:
Scanner scanner = new Scanner(System.in);
int age;
age = scanner.nextInt( );
In addition to the int data type, we have five input methods that correspond to
the other numerical data types. The six input methods for the primitive numerical
data types are listed in Table 3.6.
Table
Table 3.6
Methods to input six numerical data types
Method
Example
nextByte( )
nextDouble( )
nextFloat( )
nextInt( )
nextLong( )
nextShort( )
byte b
double d
float f
int i
long l
short s
=
=
=
=
=
=
scanner.nextByte( );
scanner.nextDouble( );
scanner.nextFloat( );
scanner.nextInt( );
scanner.nextLong( );
scanner.nextShort( );
wu23305_ch03.qxd
108
12/31/08
Chapter 3
12:54 PM
Confirming Pages
Page 108
Numerical Data
The following example inputs a person’s height in inches (int) and GPA (float):
Scanner scanner = new Scanner(System.in);
int height;
float gpa;
System.out.print("Enter your height in inches: ");
height = scanner.nextInt( );
gpa = scanner.nextFloat( );
Remember that the default delimiter between the input values is a white space
(such as the blank space or a tab); it is possible to input more than one value on a
single line. The following code inputs two integers:
Scanner scanner = new Scanner(System.in);
int num1, num2;
System.out.print("Enter two integers: ");
num1 = scanner.nextInt( );
num2 = scanner.nextInt( );
System.out.print("num1 = " + num1 + " num2 = " + num2);
And here’s a sample interaction:
Space separates the
two input values.
Enter two integers: 12 8
num1 = 12 and num2 = 87
ENTER
Since the new-line character (when we press the Enter key, this new-line character is entered into the system) is also a white space, we can enter the two integers
by pressing the Enter key after each number. Here’s a sample:
Enter two integers: 12
87 ENTER
num1 = 12 and num2 = 87
input buffer
ENTER
When we enter data using System.in, they are placed in input buffer. And the
next available data in the input buffer are processed when one of the input methods
is called. This means that the actual processing of input data does not necessarily
correspond to the display timing of the prompts. Let’s look at an example. Consider
the following code:
Scanner scanner = new Scanner(System.in);
int num1, num2, num3;
wu23305_ch03.qxd
12/31/08
12:55 PM
Confirming Pages
Page 109
3.5 Getting Numerical Input
109
System.out.print("Enter Number 1: ");
num1 = scanner.nextInt( );
System.out.print("Enter Number 2: ");
num2 = scanner.nextInt( );
System.out.print("Enter Number 3: ");
num3 = scanner.nextInt( );
System.out.print("Values entered are " +
num1 + " " + num2 + " " + num3);
We expect the majority of users will input three integers, one at a time, as requested
by the prompts:
Enter Number 1: 10 ENTER
Enter Number 2: 20 ENTER
Enter Number 3: 30 ENTER
Values entered are 10 20 30
However, users do not really have to enter the values one at a time. It is possible
to enter all three values on a single line without waiting for prompts, for example. This
will result in an awkward display in the console window. Here’s an example:
ENTER
Enter Number 1: 10, 20, 30
Enter Number 2: Enter Number 3: Values entered are 10 20 30
Although the display is awkward, the input values are assigned to the respective variables correctly. The three input values are placed in the input buffer, and
when the second and third nextInt methods are called, the corresponding values are
already in the input buffer, so they get assigned to the variables correctly.
In Section 3.2, we explained the assignment conversion that allows us to
assign a value to a higher-precision variable (e.g., assigning an int value to a double variable). This type of implicit conversion also occurs with the Scanner class.
For example, the nextDouble method works without a problem as long as the user
enters a value that is assignable to a double variable. Here’s an example:
Scanner scanner = new Scanner(System.in);
double num;
System.out.print("Enter a double: ");
num = scanner.nextDouble( );
System.out.print("You entered " + num);
Enter a double: 35
You entered 35.0
ENTER
wu23305_ch03.qxd
110
12/31/08
Chapter 3
12:55 PM
Confirming Pages
Page 110
Numerical Data
The nextDouble method accepts the value 35 and then converts it to a double data
type. This method returns a double value, so even if the user enters an integer, you
cannot assign the input to an int variable. The following code is therefore invalid:
Scanner scanner = new Scanner(System.in);
n
o
i
s
r
e
V
d
a
B
int num;
System.out.print("Enter an integer: ");
num = scanner.nextDouble( );
Type mismatch
System.out.print("You entered " + num);
Now let’s study how we can mix the input of strings and numerical values. We
begin with an example. Consider inputting a racehorse’s name and age. Here are a
proposed code and a sample of expected interaction:
Scanner scanner = new Scanner(System.in);
String horseName;
int age;
System.out.print("Enter the horse name: ");
horseName = scanner.next( );
System.out.print("Enter the age: ");
age = scanner.nextInt( );
System.out.print(horseName + " is " + age + "years old." );
Enter the horse name: Barbaro
ENTER
Enter the age: 3
Barbaro is 3 years old.
ENTER
Everything seems to be working okay. What will happen if the name of a horse has
more than one word, such as Sea Biscuit? The code will not work because only the
first word is assigned to the String variable horseName. Remember that the default
delimiter is the white space, so the blank space after the first word is treated as the
end of the first input. Here’s the result when you enter Sea Biscuit:
ENTER
Enter the horse name: Sea Biscuit
Enter the age: java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:819)
at java.util.Scanner.next(Scanner.java:1431)
at java.util.Scanner.nextInt(Scanner.java:2040)
...
Only the first four lines of error
messages are shown here.
wu23305_ch03.qxd
12/31/08
12:55 PM
Page 111
Confirming Pages
3.5 Getting Numerical Input
111
The most reasonable solution here is to change the delimiter to the line separator, as described in Section 2.4.4. Here’s how:
Scanner scanner = new Scanner(System.in);
scanner.useDelimiter(System.getProperty("line.separator"));
//the rest is the same
Enter the horse name: Sea Biscuit
Enter the age: 3 ENTER
Sea Biscuit is 3 years old.
ENTER
For most situations, using the line separator as the delimiter and inputting one
value per input line are the best approach. We can, however, use any string for the
delimiter. So, for example, we can delimit the input values with a character such as
the pound sign (#), provided, of course, that the pound sign does not occur in the
actual input values.
To input more than one string and primitive numerical data, set the line separator
as the delimiter and input one value per input line.
Instead of using the data type specific methods such as nextInt, nextDouble,
and others of the Scanner class, we can input a numerical value in a string format
and convert it to an appropriate data type by ourselves. For example, we can use the
class method parseInt of the Integer class to convert a string to an int. Here’s a statement that converts "14" to an int value 14:
int num = Integer.parseInt("14");
So, the statement
int num = Integer.parseInt(scanner.next( ));
is equivalent to
int num = scanner.nextInt( );
Passing a string that cannot be converted to an int (e.g., "12b") will result in
an error. The conversion method is not particularly useful or necessary with the
scanner, but it can be when the input source is different from the scanner. Other
common conversion methods are parseDouble, parseFloat, and parseLong of the
Double, Float, and Long classes, respectively.
wu23305_ch03.qxd
112
12/31/08
Chapter 3
12:55 PM
Page 112
Confirming Pages
Numerical Data
We close this section by presenting a sample program that extends the
Ch3Circle3 class by accepting the radius of a circle as an input. Here’s the program:
/*
Chapter 3 Sample Program: Compute Area and Circumference with formatting
and standard I/O
File: Ch3Circle4.java
*/
import java.text.*;
import java.util.*;
class Ch3Circle4 {
public static void main(String[] args) {
final double PI = 3.14159;
final String TAB = "\t";
final String NEWLINE = "\n";
Scanner scanner
= new Scanner(System.in);
DecimalFormat df = new DecimalFormat("0.000");
//compute the area and circumference
area
circumference = 2.0 * PI * radius;
//Display the results
System.out.println(
"Area:
" + TAB + df.format(area) + NEWLINE +
"Circumference: " + TAB + df.format(circumference));
}
}
1. Write a code to input the height of a user in feet (int) and inches (int).
2. Write a code to input the full name of a person and his or her age. The full
name of a person includes the first name and the last name.
3. Write a code that creates a Scanner object and sets its delimiter to the pound sign.
wu23305_ch03.qxd
12/31/08
12:55 PM
Confirming Pages
Page 113
3.6 The Math Class
113
3.6 The Math Class
Using only the arithmetic operators to express numerical computations is very limiting. Many computations require the use of mathematical functions. For example,
to express the mathematical formula
1
sin x 2
y
we need the trigonometric sine and square root functions. The Math class in the
java.lang package contains class methods for commonly used mathematical functions. Table 3.7 is a partial list of class methods available in the Math class. The class
also has two class constants PI and E for and the natural number e, respectively.
Using the Math class constant and methods, we can express the preceding formula as
(1.0 /2.0) * Math.sin( x - Math.PI / Math.sqrt(y) )
Table
Table 3.7
Math class methods for commonly used mathematical functions
Class
Method
abs( a )
Argument
Type
Result
Type
Description
Example
Returns the absolute int
value of a.
Returns the absolute
long value of a.
Returns the absolute
float value of a.
Returns the absolute
double value of a.
abs(10) → 10
abs(5) → 5
int
int
long
long
float
float
double
double
acos( a )†
double
double
Returns the arccosine
of a.
acos(1)
→ 3.14159
asin( a )†
double
double
Returns the arcsine
of a.
asin(1)
→ 1.57079
atan( a )†
double
double
Returns the arctangent
of a.
atan(1)
→ 0.785398
ceil( a )
double
double
Returns the smallest
whole number greater
than or equal to a.
ceil(5.6) → 6.0
ceil(5.0) → 5.0
ceil(5.6)
→ 5.0
cos( a )†
double
double
Returns the trigonometric
cosine of a.
cos(2) → 0.0
exp( a )
double
double
Returns the natural
number e (2.718 . . . )
raised to the power of a.
exp(2)
→ 7.389056099
wu23305_ch03.qxd
114
12/31/08
Chapter 3
Table
Table 3.7
Confirming Pages
Page 114
Numerical Data
Math class methods for commonly used mathematical functions (Continued)
Class
Method
Argument
Type
Result
Type
Description
Example
floor( a )
double
double
Returns the largest
whole number less than
or equal to a.
floor(5.6) → 5.0
floor(5.0) → 5.0
floor(5.6)
→ 6.0
log( a )
double
double
Returns the natural
logarithm (base e) of a.
log(2.7183)
→ 1.0
max( a, b )
int
int
Returns the larger of a
and b.
max(10, 20)
→ 20
long
long
Same as above.
float
float
Same as above.
int
int
Returns the smaller of a
and b.
long
long
Same as above.
float
float
Same as above.
pow(a, b)
double
double
Returns the number a
raised to the power of b.
random( )
<none>
double
Generates a random
number greater than or
equal to 0.0 and
less than 1.0.
round( a )
float
int
Returns the int value of
a rounded to the
nearest whole number.
double
long
Returns the float value of
a rounded to the
nearest whole number.
sin( a )†
double
double
Returns the
trigonometric sine of a.
sin(2 )
→ 1.0
sqrt( a )
double
double
Returns the square root
of a.
sqrt(9.0) → 3.0
tan( a )†
double
double
Returns the trigonometric tangent of a.
tan(4)
→ 1.0
toDegrees
double
double
Converts the given
degrees.
toDegrees(4)
→ 45.0
double
double
Reverse of toDegrees.
→ 1.5707963
min(a, b)
†
12:55 PM
All trigonometric functions are computed in radians.
min(10, 20)
→ 10
pow( 2.0, 3.0)
→ 8.0
round(5.6) → 6
round(5.4) → 5
round(5.6)
→ 6
wu23305_ch03.qxd
12/31/08
12:55 PM
Confirming Pages
Page 115
3.6 The Math Class
115
Notice how the class methods and class constants are referred to in the expression. The syntax is
<class name> . <method name> ( <arguments> )
or
<class name> . <class constant>
Let’s conclude this section with a sample program. Today is the final meet of
the women’s rowing team against the arch rival university before the upcoming
Division I NCAA championship. The cheerleaders of the rival team hoisted their
school flag on the other shore of the river to boost their moral. Not to be outdone,
we want to hoist our school flag, too. To bring the Goddess of Victory to our side,
we want our pole to be taller than theirs. Since they won’t let us, we can’t find the
height of their pole by actually measuring it. We can, however, determine the height
without actually measuring it if we know the distance b to their flagpole. We can use
the tangent of angle to determine the pole’s height h as follows:
h
h ⫽ b · tan ␣
b
␣
Unfortunately, there’s no means for us to go across the river to find out the distance b. After a moment of deep meditation, it hits us that there’s no need to go
across the river. We can determine the pole’s height by measuring angles from two
points on this side of the riverbank, as shown below:
␤
h
B
d
␣
A
wu23305_ch03.qxd
116
12/31/08
Chapter 3
12:55 PM
Page 116
Confirming Pages
Numerical Data
And the equation to compute the height h is
d sin sin h sin(
(
) sin)
Once we have this equation, all that’s left is to put together a Java program. Here’s
the program:
/*
Chapter 3 Sample Program: Estimate the Pole Height
File: Ch3PoleHeight.java
*/
import java.text.*;
import java.util.*;
class Ch3PoleHeight {
public static void main( String[] args ) {
double
double
double
double
double
double
height;
distance;
alpha;
beta;
//height of the pole
//distance between points A and B
//angle measured at point A
//angle measured at point B
Scanner scanner = new Scanner(System.in);
scanner.useDelimiter(System.getProperty("line.separator"));
//Get three input values
System.out.print("Angle alpha (in degrees):");
alpha = scanner.nextDouble();
System.out.print("Angle beta (in degree):");
beta = scanner.nextDouble();
System.out.print("Distance between points A and B (ft):");
distance = scanner.nextDouble();
//compute the height of the tower
/
wu23305_ch03.qxd
12/31/08
12:55 PM
Confirming Pages
Page 117
3.7 Random Number Generation
117
DecimalFormat df = new DecimalFormat("0.000");
System.out.println("lnln Estimating the
+ "\n\n"
+ "Angle at point A (deg):
" +
+ "Angle at point B (deg):
" +
+ "Distance between A and B (ft): " +
+ "Estimated height (ft):
" +
height of the pole"
df.format(alpha) + "\n"
df.format(beta)
+ "\n"
df.format(distance)+ "\n"
df.format(height));
}
}
1. What’s wrong with the following?
a.
b.
c.
d.
y
y
y
y
=
=
=
=
(1/2) * Math.sqrt( X );
sqrt(38.0);
Math.exp(2, 3);
math.sqrt( b*b - 4*a*c) / ( 2 * a );
2. If another programmer writes the following statements, do you suspect any
misunderstanding on the part of this programmer? What will be the value
of y?
a. y = Math.sin( 360 ) ;
b. y = Math.cos( 45 );
3.7 Random Number Generation
In many computer applications, especially in simulation and games, we need to generate random numbers. For example, to simulate a roll of dice, we can generate an integer between 1 and 6. In this section, we explain how to generate random numbers
using the Random class from the java.util package. (Alternatively, we can use the
random method of the Math class to generate random numbers, but it is more difficult to use than the Random class).
For most applications, the random numbers we want to generate are integers.
To generate random integers, we use the nextInt method of the Random class. Here’s
an example:
import java.util.*;
...
Random random = new Random( );
int num = random.nextInt( );
wu23305_ch03.qxd
118
12/31/08
Chapter 3
12:55 PM
Page 118
Confirming Pages
Numerical Data
The nextInt method returns an int value, that is any value between 2147483648
and 2147483647 (see Table 3.1). To restrict range of possible values, we can use the
second form of the nextInt method in which we pass an argument that specifies the
upper bound of the range. The lower bound is set to 0. To generate a random integer
between 0 and 10, for example, we write as follows:
int num = random.nextInt(11);
Notice that the argument we pass is 11, not 10. The argument we pass to the
method specifies the total number of possible values, starting from 0. So passing
the value of 11 specifies that we are getting one of the 11 possible values, ranging
from 0 to 10.
Often we want the lower bound of the possible range to be other than 0.
There is no method in the Random class that allows us to specify both the lower
bound. It is possible, however, to generate any number between min and max
where min is greater than 0? Suppose, for example, we want a number between
1 and 6. We can first generate a number between 0 and 5 and then add 1 to the
result as
This generates an integer
between 0 and 5, inclusive.
int num = random.nextInt(6) + 1;
Let’s derive a formula for the general case. To generate a random integer in
the range of [min, max] where 0 <= min < max, we write
int num = random.nextInt(max-min+1) + min;
This generates an integer between
0 and (max-min), inclusive.
The expression random.nextInt(max-min+1) returns an integer between 0 and
(max-min). By adding min to this value, the final result will then be a value between
0 + min = min and (max min) + min = max, as desired.
The nextInt (and other methods) in the Random class is called a pseudorandom number
generator because the number is not truly random. When we call the method repeatedly,
eventually the numbers generated will repeat themselves. Therefore, theoretically the
generated numbers are not random; but for all practical purposes, they are random
enough.
wu23305_ch03.qxd
12/31/08
12:55 PM
Confirming Pages
Page 119
3.7 Random Number Generation
119
Let’s write a short program that selects a winner among the party goers of the
annual spring fraternity dance. The party goers will receive numbers M + 1, M + 2,
M + 3, and so on, as they enter the house. The starting value M is determined by the
fraternity president. The last number assigned is M + N if there are N party goers. At
the end of the party, we run the program that will randomly select the winning number from the range of M + 1 and M + N. Here’s the program:
*/
Chapter 3 Sample Program: Select the Winning Number using the Random class
File: Ch3SelectWinner.java
*/
import java.util.*;
class Ch3SelectWinner {
public static void main(String[] args) {
int
int
int
int
startingNumber;
count;
winningNumber;
min, max;
//the
//the
//the
//the
starting number
number of party goers
winner
range of random numbers to generate
Random random = new Random(); //random number generator
Scanner scan = new Scanner(System.in);
//Get two input values
System.out.print("Enter the starting number M:
startingNumber = scan.nextInt ();
");
System.out.print("Enter the number of party goers: ");
count = scan.nextInt();
//select the winner
min = startingNumber + 1;
max = startingNunber + count;
winningNumber = random.nextInt(max-min+1) + min;
System.out.println("\nThe Winning Number is " + winningNumber);
}
}
wu23305_ch03.qxd
120
12/31/08
Chapter 3
12:55 PM
Page 120
Confirming Pages
Numerical Data
1. What are the possible minimum and the maximum numbers assigned to num
by the following statement?
int num = random.nextInt(15);
2. Write a statement that assigns a random number between 1 and 4, inclusive, to
an integer variable num.
3. Write a statement that assigns a random number between min and max,
inclusive, where 0 <= min < max, to an integer variable num.
3.8 The GregorianCalendar Class
In Chapter 2, we introduced the java.util.Date class to represent a specific instant in
time. Notice that we are using here the more concise expression “the java.util.Date
class” to refer to a class from a specific package instead of the longer expression
“the Date class from the java.util package.” This shorter version is our preferred
way of notation when we need or want to identify the package to which the class
belongs.
When we need to identify the specific package to which a class belongs, we will
commonly use the concise expression with the full path name, such as
java.util.Date, instead of writing “the Date class from the java.util package.”
GregorianCalendar
In addition to this class, we have a very useful class named java.util.GregorianCalendar in manipulating calendar information such as year, month, and day. We can
create a new GregorianCalendar object that represents today as
GregorianCalendar today = new GregorianCalendar( );
or a specific day, say, July 4, 1776, by passing year, month, and day as the parameters as
The value of 6
means July.
GregorianCalendar independenceDay =
new GregorianCalendar(1776, 6, 4);
No, the value of 6 as the second parameter is not an error. The first month of a
year, January, is represented by 0, the second month by 1, and so forth. To avoid
wu23305_ch03.qxd
12/31/08
12:55 PM
Confirming Pages
Page 121
3.8 The GregorianCalendar Class
Table
Table 3.8
121
Constants defined in the Calendar class for retrieved different pieces of
calendar/time information
Constant
Description
YEAR
MONTH
DATE
DAY_OF_MONTH
DAY_OF_YEAR
DAY_OF_MONTH
DAY_OF_WEEK
WEEK_OF_YEAR
WEEK_OF_MONTH
AM_PM
HOUR
HOUR_OF_DAY
MINUTE
The year portion of the calendar date
The month portion of the calendar date
The day of the month
Same as DATE
The day number within the year
The day number within the month
The day of the week (Sun—1, Mon—2, etc.)
The week number within the year
The week number within the month
The indicator for AM or PM (AM—0 and PM—1)
The hour in 12-hour notation
The hour in 24-hour notation
The minute within the hour
confusion, we can use constants defined for months in the superclass Calendar
(GregorianCalendar is a subclass of Calendar). Instead of remembering that the
value 6 represents July, we can use the defined constant Calendar.JULY as
GregorianCalendar independenceDay =
new GregorianCalendar(1776, Calendar.JULY, 4);
Table 3.8 explains the use of some of the more common constants defined in the
Calendar class.
When the date and time are February 13, 2008, 13:30 p.m. and we run the
Ch3TestCalendar program, we will see the result shown in Figure 3.4.
Wed Feb 13:30:51 PST 2008
YEAR:
MONTH:
DATE:
DAY_OF_YEAR:
DAY_OF_MONTH:
DAY_OF_WEEK:
WEEK_OF_YEAR:
WEEK_OF_MONTH:
AM_PM:
HOUR:
HOUR_OF_DAY:
MINUTE:
2008
1
13
44
13
4
7
3
1
1
13
30
Figure 3.4 Result of running the Ch3TestCalender program at February 13, 2008,13:30 p.m.
wu23305_ch03.qxd
122
12/31/08
Chapter 3
12:55 PM
Confirming Pages
Page 122
Numerical Data
/*
Chapter 3 Sample Program: Display Calendar Info
File: Ch3TestCalendar.java
*/
import java.util.*;
class Ch3TestCalendar {
public static void main(String[] args) {
GregorianCalendar cal = new GregorianCalendar();
System.out.println(cal.getTime());
System.out.println("");
System.out.println("YEAR:
System.out.println("MONTH:
System.out.println("DATE:
" + cal.get(Calendar.YEAR));
" + cal.get(Calendar.MONTH));
" + cal.get(Calendar.DATE));
System.out.println("DAY_OF_YEAR:
"
+ cal.get(Calendar.DAY_OF_YEAR));
System.out.println("DAY_OF_MONTH: "
+ cal.get(Calendar.DAY_OF_MONTH));
System.out.println("DAY_OF_WEEK:
"
+ cal.get(Calendar.DAY_OF_WEEK));
System.out.println("WEEK_OF_YEAR: "
+ cal.get(Calendar.WEEK_OF_YEAR));
System.out.println("WEEK_OF_MONTH: "
+ cal.get(Calendar.WEEK_OF_MONTH));
System.out.println("AM_PM:
" + cal.get(Calendar.AM_PM));
System.out.println("HOUR:
" + cal.get(Calendar.HOUR));
System.out.println("HOUR_OF_DAY:
"
+ cal.get(Calendar.HOUR_OF_DAY));
System.out.println("MINUTE:
" + cal.get(Calendar.MINUTE));
}
}
getTime
Notice that the first line in the output shows the full date and time information.
The full date and time information can be accessed by calling the calendar object’s
getTime method. This method returns the same information as a Date object.
Notice also that we get only the numerical values when we retrieve the day
of the week or month information. We can spell out the information by using the
SimpleDateFormat class. Since the constructor of the SimpleDateFormat class accepts only the Date object, first we need to convert a GregorianCalendar object to
an equivalent Date object by calling its getTime method. For example, here’s how
wu23305_ch03.qxd
12/31/08
12:55 PM
Page 123
Confirming Pages
3.8 The GregorianCalendar Class
123
we can display the day of the week on which our Declaration of Independence was
/*
Chapter 3 Sample Program: Day of the week the Declaration of
File: Ch3IndependenceDay.java
*/
import java.util.*;
import java.text.*;
class Ch3IndependenceDay {
public static void main(String[] args) {
GregorianCalendar independenceDay
= new GregorianCalendar(1776, Calendar.JULY, 4);
SimpleDateFormat sdf = new SimpleDateFormat("EEEE");
+ sdf.format(independenceDay.getTime()));
}
}
Let’s finish the section with a sample program that extends the Ch3IndependenceDay program. We will allow the user to enter the year, month, and day; and we
will reply with the day of the week of the given date (our birthday, grandparent’s
wedding day, and so on). Here’s the program:
/*
Chapter 3 Sample Program: Find the Day of Week of a Given Date
File: Ch3FindDayOfWeek.java
*/
import java.util.*;
import java.text.*;
class Ch3FindDayOfWeek {
public static void main(String[] args) {
int year, month, day;
GregorianCalendar cal;
SimpleDateFormat sdf;
wu23305_ch03.qxd
124
12/31/08
Chapter 3
12:55 PM
Page 124
Confirming Pages
Numerical Data
Scanner scanner = new Scanner(System.in);
scanner.useDelimiter(System.getProperty("line.separator"));
System.out.print("Year (yyyy): ");
year = scanner.nextInt();
System.out.print("Month (1-12): ");
month = scanner.nextInt();
System.out.print("Day (1-31): ");
day
= scanner.nextInt();
cal = new GregorianCalendar(year, month-1, day);
sdf = new SimpleDateFormat("EEEE");
System.out.println("");
System.out.println("Day of Week: " + sdf.format(cal.getTime()));
}
}
Notice that we are allowing the user to enter the month as an integer between 1 and 12, so we need to subtract 1 from the entered data in creating a new
GregorianCalendar object.
The Gregorian calendar system was adopted by England and its colonies, including the
colonial United States, in 1752. So the technique shown here works only after this
http://webexhibits.org/calendars/year-countries.html
Running Ch3IndpendenceDay will tell you that our venerable document was signed
on Thursday. History textbooks will say something like “the document was formally
adopted July 4, 1776, on a bright, but cool Philadelphia day” but never the day of the
week. Well, now you know. See how useful Java is? By the way, the document was
adopted by the Second Continental Congress on July 4, but the actual signing did
not take place until August 2 (it was Friday—what a great reason for a TGIF party)
after the approval of all 13 colonies. For more stories behind the Declaration of
Independence, visit
http://www.ushistory.org/declaration/
wu23305_ch03.qxd
12/31/08
12:55 PM
Page 125
Confirming Pages
3.9 Sample Development
3.9
125
Sample Development
Sample Development
Loan Calculator
In this section, we develop a simple loan calculator program. We develop this program by
using an incremental development technique, which develops the program in small incremental steps. We start out with a bare-bones program and gradually build up the program by adding more and more code to it. At each incremental step, we design, code, and
test the program before moving on to the next step. This methodical development of a
program allows us to focus our attention on a single task at each step, and this reduces
the chance of introducing errors into the program.
Problem Statement
The next time you buy a new TV or a stereo, watch out for those “0% down, 0% interest
until next July” deals. Read the fine print, and you’ll notice that if you don’t make the full
payment by the end of a certain date, hefty interest will start accruing. You may be better
off to get an ordinary loan from the beginning with a cheaper interest rate. What matters
most is the total payment (loan amount plus total interest) you’ll have to make. To compare different loan deals, let’s develop a loan calculator. Here’s the problem statement:
Write a loan calculator program that computes both monthly and total
payments for a given loan amount, annual interest rate, and loan period.
Overall Plan
Our first task is to map out the overall plan for development. We will identify classes necessary for the program and the steps we will follow to implement the program.We begin
with the outline of program logic. For a simple program such as this one, it is kind of obvious; but to practice the incremental development, let’s put down the outline of program
flow explicitly. We can express the program flow as having three tasks:
program
1. Get three input values: loanAmount, interestRate, and loanPeriod.
2. Compute the monthly and total payments.
3. Output the results.
Having identified the three major tasks of the program, we now identify the classes
we can use to implement the three tasks. For input and output, we continue to use the
Scanner class and System.out (PrintStream). For computing the monthly and total
payments, there are no standard classes that will provide such computation, so we have
to write our own code.
The formula for computing the monthly payment can be found in any mathematics book that covers geometric sequences. It is
LR
Monthly payment N
1 [1(1 R)]
wu23305_ch03.qxd
126
12/31/08
Chapter 3
12:55 PM
Page 126
Confirming Pages
Numerical Data
3.9 Sample Development—continued
where L is the loan amount,R is the monthly interest rate,and N is the number of payments.
The monthly rate R is expressed in a fractional value,for example,0.01 for 1 percent monthly
rate. Once the monthly payment is derived, the total payment can be determined by multiplying the monthly payment by the number of months the payment is made. Since the
formula includes exponentiation, we will have to use the pow method of the Math class.
Let’s summarize what we have decided so far in a design document:
Design Document: LoanCalculator
program
classes
Class
Purpose
LoanCalculator
The main class of the program.
Scanner
The class is used to get three input values: loan amount,
annual interest rate, and loan period.
PrintStream
(System.out)
System.out is used to display the input values and two
computed results: monthly payment and total payment.
Math
The pow method is used to evaluate exponentiation in the
formula for computing the monthly payment. This class is
from java.lang. Note: You don’t have to import
java.lang. The classes in java.lang are available to a
program without importing.
The program diagram based on the classes listed in the design document is shown
in Figure 3.5. Keep in mind that this is only a preliminary design. The preliminary document is really a working document that we will modify and expand as we progress
through the development steps.
Before we can actually start our development, we must sketch the steps we will
follow to implement the program. There is more than one possible sequence of steps to
implement a program, and the number of possible sequences will increase as the program
becomes more complex. For this program, we will implement the program in four steps:
development steps
2. Add code to output the results.
3. Add code to compute the monthly and total payments.
4. Update or modify code and tie up any loose ends.
Notice how the first three steps are ordered. Other orders are possible to develop
this program. So why did we choose this particular order? The main reason is our desire to
defer the most difficult task until the end. It’s possible, but if we implement the computation part in the second incremental step, then we need to code some temporary output
routines to verify that the computation is done correctly. However, if we implement the
wu23305_ch03.qxd
12/31/08
12:55 PM
Confirming Pages
Page 127
3.9 Sample Development
127
Scanner
LoanCalculator
System.out : PrintStream
Math
Figure 3.5 The object diagram for the program LoanCalculator.
real output routines before implementing the computation routines, then there is no
need for us to worry about temporary output routines. As for step 1 and step 2, their relative order does not matter much. We simply chose to implement the input routine before
the output routine because input comes before output in the program.
Step 1 Development: Input Three Data Values
step 1
design
The next task is to determine how we will accept the input values. The problem statement
does not specify the exact format of input, so we will decide that now. Based on how people normally refer to loans, the input values will be accepted in the following format:
Input
Format
Data Type
Loan amount
Annual interest rate
Loan period
In dollars and cents (for example, 15000.00)
In percent (for example, 12.5)
In years (for example, 30)
double
double
int
Be aware that we need to convert the annual interest rate to the monthly interest rate and
the input value loan period to the number of monthly payments, to use the given
formula. In this case, the conversion is very simple, but even if the conversion routines
were more complicated, we must do the conversion. It is not acceptable to ask users to
wu23305_ch03.qxd
128
12/31/08
Chapter 3
12:55 PM
Page 128
Confirming Pages
Numerical Data
3.9 Sample Development—continued
step 1 code
enter an input value that is unnatural to them. For example, people do not think of interest rates in fractional values such as 0.07. They think of interest in terms of percentages
such as 7 percent. Computer programs work for humans, not the other way round.
Programs we develop should not support an interface that is difficult and awkward for
humans to use.
When the user inputs an invalid value, for example, an input string value that cannot be converted to a numerical value or that converts to a negative number, the program
should respond accordingly, such as by printing an error message. We do not possess
enough skills to implement such a robust program yet, so we will make the following
assumptions: (1) The input values are nonnegative numbers, and (2) the loan period is a
whole number.
One important objective of this step is to verify that the input values are read
in correctly by the program. To verify this, we will echo-print the input values to
System.out.
Here’s our step 1 program:
/*
Chapter 3 Sample Development: Loan Calculator
(Step 1)
File: Step1/Ch3LoanCalculator.java
Step 1: Input Data Values
*/
import java.util.*;
class Ch3LoanCalculator {
public static void main(String[] args) {
double
loanAmount,
annualInterestRate;
int
loanPeriod;
Scanner scanner = new Scanner(System.in);
scanner.useDelimiter(System.getProperty("line.separator"));
//get input values
System.out.print("Loan Amount (Dollars+Cents): ");
loanAmount = scanner.nextDouble();
System.out.print("Annual Interest Rate (e.g., 9.5): ");
annualInterestRate = scanner.nextDouble();
wu23305_ch03.qxd
12/31/08
12:55 PM
Confirming Pages
Page 129
3.9 Sample Development
129
System.out.print("Loan Period - # of years: ");
loanPeriod = scanner.nextInt();
//echo print the input values
System.out.println ("");
System.out.println("Loan Amount:
\$" + loanAmount);
System.out.println("Annual Interest Rate: "
+ annualInterestRate + "%");
System.out.println("Loan Period (years): " + loanPeriod);
}
}
step 1 test
To verify the input routine is working correctly, we run the program multiple times
and enter different sets of data. We make sure the values are displayed in the standard
output window as entered.
Step 2 Development: Output Values
step 2
design
The second step is to add code to display the output values. We will use the standard output window for displaying output values. We need to display the result in a layout that is
meaningful and easy to read. Just displaying numbers such as the following is totally
unacceptable.
132.151.15858.1
We must label the output values so the user can tell what the numbers represent. In addition, we must display the input values with the computed result so it will not be meaningless. Which of the two shown in Figure 3.6 do you think is more meaningful? The
output format of this program will be
For
Loan Amount:
Annual Interest Rate:
Loan Period (years):
\$ <amount>
<annual interest rate> %
<year>
Monthly payment is \$ <monthly payment>
TOTAL payment is \$ <total payment>
with <amount>, <annual interest rate>, and others replaced by the actual figures.
wu23305_ch03.qxd
130
12/31/08
Chapter 3
12:55 PM
Confirming Pages
Page 130
Numerical Data
3.9 Sample Development—continued
Only the computed
values (and their
labels) are shown.
Both the input and
computed values (and
their labels) are shown.
Monthly payment:
Total payment:
\$ 143.47
\$ 17216.50
For
Loan Amount:
Annual Interest Rate:
Loan Period (years):
\$ 10000.00
12.0%
10
Monthly payment is
TOTAL payment is
\$ 143.47
\$ 17216.50
Figure 3.6 Two different display formats, one with input values displayed and the other with only the
computed values displayed.
Since the computations for the monthly and total payments are not yet implemented, we will use the following dummy assignment statements:
monthlyPayment = 135.15;
totalPayment
= 15858.10;
step 2 code
We will replace these statements with the real ones in the next step.
Here’s our step 2 program with the newly added portion surrounded by a rectangle
and white background:
/*
Chapter 3 Sample Development: Loan Calculator (Step 2)
File: Step2/Ch3LoanCalculator.java
Step 2: Display the Results
*/
import java.util.*;
class Ch3LoanCalculator {
public static void main(String[] args) {
double
loanAmount,
annualInterestRate;
double
monthlyPayment,
totalPayment;
int
loanPeriod;
wu23305_ch03.qxd
12/31/08
12:55 PM
Confirming Pages
Page 131
3.9 Sample Development
131
Scanner scanner = new Scanner(System.in);
scanner.useDelimiter(System.getProperty("line.separator"));
//get input values
System.out.print("Loan Amount (Dollars+Cents): ");
loanAmount = scanner.nextDouble();
System.out.print("Annual Interest Rate (e.g., 9.5): ");
annualInterestRate = scanner.nextDouble();
System.out.print("Loan Period - # of years: ");
loanPeriod = scanner.nextInt();
//compute the monthly and total payments
monthlyPayment = 132.15;
totalPayment = 15858.10;
//display the result
System.out.println("");
System.out.println("Loan Amount:
\$" + loanAmount);
System.out.println("Annual Interest Rate:"
+ annualInterestRate + "%");
System.out.println("Loan Period (years): " + loanPeriod);
System.out.println("\n"); //skip two lines
System.out.println("Monthly payment is
\$ " + monthlyPayment);
System.out.println(" TOTAL payment is
\$ " + totalPayment);
}
}
step 2 test
To verify the output routine is working correctly, we run the program and verify the
layout. Most likely,we have to run the program several times to fine-tune the arguments for
the println methods until we get the layout that looks clean and nice on the screen.
Step 3 Development: Compute Loan Amount
step 3
design
We are now ready to complete the program by implementing the formula derived in the
design phase.The formula requires the monthly interest rate and the number of monthly
payments. The input values to the program, however, are the annual interest rate and the
loan period in years. So we need to convert the annual interest rate to a monthly interest
rate and the loan period to the number of monthly payments. The two input values are
converted as
monthlyInterestRate = annualInterestRate / 100.0 / MONTHS_IN_YEAR;
numberOfPayments
= loanPeriod * MONTHS_IN_YEAR;
wu23305_ch03.qxd
132
12/31/08
Chapter 3
12:55 PM
Page 132
Confirming Pages
Numerical Data
3.9 Sample Development—continued
where MONTHS_IN_YEAR is a symbolic constant with value 12. Notice that we need to
divide the input annual interest rate by 100 first because the formula for loan computation requires that the interest rate be a fractional value, for example, 0.01, but the input
annual interest rate is entered as a percentage point, for example, 12.0. Please read Exercise 26 on page 147 for information on how the monthly interest rate is derived from a
given annual interest rate.
The formula for computing the monthly and total payments can be expressed as
monthlyPayment = (loanAmount * monthlyInterestRate)
/
(1 - Math.pow( 1 /(1 + monthlyInterestRate),
numberOfPayments) );
totalPayment = monthlyPayment * numberOfPayments;
step 3 code
Let’s put in the necessary code for the computations and complete the program.
Here’s our program:
/*
Chapter 3 Sample Development: Loan Calculator (Step 3)
File: Step3/Ch3LoanCalculator.java
Step 3: Display the Results
*/
import java.util.*;
class Ch3LoanCalculator {
public static void main(String[] args) {
final int MONTHS_IN_YEAR = 12;
double
loanAmount,
annualInterestRate;
double
monthlyPayment,
totalPayment;
double
monthlyInterestRate;
int
loanPeriod;
wu23305_ch03.qxd
12/31/08
12:55 PM
Page 133
Confirming Pages
3.9 Sample Development
int
133
numberOfPayments;
Scanner scanner = new Scanner(System.in);
scanner.useDelimiter(System.getProperty("line.separator"));
//get input values
System.out.print("Loan Amount (Dollars+Cents): ");
loanAmount = scanner.nextDouble();
System.out.print("Annual Interest Rate (e.g., 9.5): ");
annualInterestRate = scanner.nextDouble();
System.out.print("Loan Period - # of years: ");
loanPeriod = scanner.nextInt();
//compute the monthly and total payments
monthlyInterestRate = annualInterestRate / MONTHS_IN_YEAR / 100;
numberOfPayments
= loanPeriod * MONTHS_IN_YEAR;
monthlyPayment = (loanAmount * monthlyInterestRate)/
(1 - Math.pow(1/(1 + monthlyInterestRate),
numberOfPayments ) );
totalPayment = monthlyPayment * numberOfPayments;
//display the result
System.out.println("");
System.out.println("Loan Amount:
\$" + loanAmount);
System.out.println("Annual Interest Rate: "
+ annualInterestRate + "%");
System.out.println("Loan Period (years): " + loanPeriod);
System.out.println("\n"); //skip two lines
System.out.println("Monthly payment is
\$ " + monthlyPayment);
System.out.println(" TOTAL payment is
\$ " + totalPayment);
}
}
step 3 test
After the program is coded, we need to run the program through a number of tests.
Since we made the assumption that the input values must be valid, we will test the program only for valid input values. If we don’t make that assumption, then we need to test
that the program will respond correctly when invalid values are entered. We will perform
such testing beginning in Chapter 5.To check that this program produces correct results,
we can run the program with the following input values. The right two columns show the
correct results. Try other input values as well.
wu23305_ch03.qxd
134
12/31/08
Chapter 3
12:55 PM
Confirming Pages
Page 134
Numerical Data
3.9 Sample Development—continued
Output
(shown up to three decimal
places only)
Input
Loan
Amount
Annual
Interest
Rate
Loan
Period
(Years)
Monthly
Payment
Total
Payment
10000
15000
10000
0
30
10
7
12
10
8.5
10
15
10
5
50
132.151
134.824
143.471
0.000
0.216
15858.088
24268.363
17216.514
0.000
129.373
Step 4 Development: Finishing Up
step 4
design
step 4 code
We finalize the program in the last step by making any necessary modifications or additions. We will make two additions to the program. The first is necessary while the second
is optional but desirable. The first addition is the inclusion of a program description. One
of the necessary features of any nontrivial program is the description of what the program does for the user. We will print out a description at the beginning of the program to
System.out. The second addition is the formatting of the output values. We will format
the monthly and total payments to two decimal places, using a DecimalFormat object.
Here is our final program:
/*
Chapter 3 Sample Development: Loan Calculator (Step 4)
File: Step4/Ch3LoanCalculator.java
Step 4: Finalize the program
*/
import java.util.*;
import java.text.*;
class Ch3LoanCalculator {
public static void main(String[] args) {
final int MONTHS_IN_YEAR = 12;
wu23305_ch03.qxd
12/31/08
12:55 PM
Confirming Pages
Page 135
3.9 Sample Development
double
loanAmount,
annualInterestRate;
double
monthlyPayment,
totalPayment;
double
monthlyInterestRate;
int
loanPeriod;
int
numberOfPayments;
Scanner scanner = new Scanner(System.in);
scanner.useDelimiter(System.getProperty("line.separator"));
DecimalFormat df = new DecimalFormat("0.00");
//describe the program
System.out.println("This program computes the monthly and total");
System.out.println("payments for a given loan amount, annual ");
System.out.println("interest rate, and loan period.");
System.out.println("Loan amount in dollars and cents,
e.g., 12345.50");
System.out.println("Annual interest rate in percentage,
e.g., 12.75");
System.out.println("Loan period in number of years, e.g., 15");
System.out.println("\n"); //skip two lines
//get input values
System.out.print("Loan Amount (Dollars+Cents): ");
loanAmount = scanner.nextDouble( );
System.out.print("Annual Interest Rate (e.g., 9.5): ");
annualInterestRate = scanner.nextDouble( );
System.out.print("Loan Period - # of years: ");
loanPeriod = scanner.nextInt( );
//compute the monthly and total payments
monthlyInterestRate = annualInterestRate / MONTHS_IN_YEAR / 100;
numberOfPayments
= loanPeriod * MONTHS_IN_YEAR;
monthlyPayment = (loanAmount * monthlyInterestRate) /
(1 - Math.pow(1/(1 + monthlyInterestRate),
numberOfPayments ) );
totalPayment = monthlyPayment * numberOfPayments;
//display the result
System.out.println("");
System.out.println("Loan Amount:
\$" + loanAmount);
135
wu23305_ch03.qxd
136
12/31/08
Chapter 3
12:55 PM
Page 136
Confirming Pages
Numerical Data
3.9 Sample Development—continued
System.out.println("Annual Interest Rate: "
+ annualInterestRate + "%");
System.out.println("Loan Period (years): " + loanPeriod);
System.out.println("\n"); //skip two lines
System.out.println("Monthly payment is \$ "
+ df.format(monthlyPayment));
System.out.println(" TOTAL payment is \$ "
+ df.format(totalPayment));
}
}
step 4 test
We repeat the test runs from step 3 and confirm the modified program still runs
correctly. Since we have not made any substantial additions or modifications, we fully
expect the program to work correctly. However, it is very easy to introduce errors in coding, so even if we think the changes are trivial, we should never skip the testing after even
a slight modification.
Always test after making any additions or modifications to a program, no matter
how trivial you think the changes are.
3.10 Numerical Representation (Optional)
twos
complement
In this section we explain how integers and real numbers are stored in memory.
Although computer manufacturers have used various formats for storing numerical
values, today’s standard is to use the twos complement format for storing integers
and the floating-point format for real numbers. We describe these formats in this
section.
An integer can occupy 1, 2, 4, or 8 bytes depending on which data type
(i.e., byte, short, int, or long) is declared. To make the examples easy to follow,
we will use 1 byte ( 8 bits) to explain twos complement form. The same principle
applies to 2, 4, and 8 bytes. (They just utilize more bits.)
wu23305_ch03.qxd
12/31/08
12:55 PM
Page 137
Confirming Pages
3.10 Numerical Representation (Optional )
137
The following table shows the first five and the last four of the 256 positive
binary numbers using 8 bits. The right column lists their decimal equivalents.
8-Bit Binary Number
00000000
00000001
00000010
00000011
00000100
...
11111100
11111101
11111110
11111111
sign bit
Decimal Equivalent
0
1
2
3
4
252
253
254
255
Using 8 bits, we can represent positive integers from 0 to 255. Now let’s see
the possible range of negative and positive numbers that we can represent, using
8 bits. We can designate the leftmost bit as a sign bit: 0 means positive and 1 means
negative. Using this scheme, we can represent integers from 127 to 127 as
shown in the following table:
8-Bit Binary Number
(with a Sign Bit)
Decimal Equivalent
0 0000000
0 0000001
0 0000010
...
0
1
2
0 1111111
1 0000000
1 0000001
...
127
0
1
1 1111110
1 1111111
126
127
Notice that zero has two distinct representations (0 00000000 and 0 10000000), which adds complexity in hardware design. Twos complement format
avoids this problem of duplicate representations for zero. In twos complement format, all positive numbers have zero in their leftmost bit. The representation of a
negative number is derived by first inverting all the bits (changing 1s to 0s and 0s to
wu23305_ch03.qxd
138
12/31/08
Chapter 3
12:55 PM
Confirming Pages
Page 138
Numerical Data
1s) in the representation of the positive number and then adding 1. The following
diagram illustrates the process:
13 =
00001101
invert
11110010
-13 =
11110011
The following table shows the decimal equivalents of 8-bit binary numbers by
using twos complement representation. Notice that zero has only one representation.
8-Bit Binary Number
(Twos Complement)
Decimal
Equivalent
0
1
2
00000000
00000001
00000010
...
01111111
10000000
10000001
...
11111110
11111111
floating-point
127
128
127
2
1
Now let’s see how real numbers are stored in memory in floating-point format.
We present only the basic ideas of storing real numbers in computer memory here.
We omit the precise details of the Institute of Electronics and Electrical Engineers
(IEEE) Standard 754 that Java uses to store real numbers.
Real numbers are represented in the computer by using scientific notation. In
base-10 scientific notation, a real number is expressed as
A 10N
where A is a real number and N is an integral exponent. For example, the mass of a
hydrogen atom (in grams) is expressed in decimal scientific notation as 1.67339 10–24, which is equal to 0.00000000000000000000000167339.
We use base-2 scientific notation to store real numbers in computer memory.
Base-2 scientific notation represents a real number as follows:
A 2N
The float and double data types use 32 and 64 bits, respectively, with the number A and exponent N stored as follows:
wu23305_ch03.qxd
12/31/08
12:55 PM
Confirming Pages
Page 139
3.10 Numerical Representation (Optional )
Sign bit:
0 — positive
1 — negative
normalized
fraction
1
8
23
S
N
A
139
Number of
bits used
1
11
52
S
N
A
The value A is a normalized fraction, where the fraction begins with a binary point,
followed by a 1 bit and the rest of the fraction. ( Note: A decimal number has a decimal point; a binary number has a binary point.) The following numbers are sample
normalized and unnormalized binary fractions:
Normalized
Unnormalized
1.1010100
1.100011
1.101110011
1.100111
.0000000001
.0001010110
Since a normalized number always start with a 1, this bit does not actually
have to be stored. The following diagram illustrates how the A value is stored.
.1 0 1 1 0 1 1 1
excess format
1
8
S
N
0 1 1 0 1 1 1 0 0 ... 0 0
The sign bit S indicates the sign of a number, so A is stored in memory as an unsigned number. The integral exponent N can be negative or positive. Instead of using
twos complement for storing N, we use a format called excess format. The 8-bit exponent uses the excess-127 format, and the 11-bit exponent uses the excess-1023
format. We will explain the excess-127 format here. The excess-1023 works
similarly. With the excess-127 format, the actual exponent is computed as
N 127
Therefore, the number 127 represents an exponent of zero. Numbers less than 127
represent negative exponents, and numbers greater than 127 represent positive
exponents. The following diagram illustrates that the number 125 in the exponent
field represents 2125127 22.
S
N
A
01111101
201111101⫺127 ⫽ 2125⫺127 ⫽ 2⫺2
wu23305_ch03.qxd
140
12/31/08
Chapter 3
12:55 PM
Page 140
Confirming Pages
Numerical Data
S u m m a r y
•
•
•
•
•
•
•
•
•
A variable is a memory location in which to store a value.
A variable has a name and a data type.
A variable must be declared before we can assign a value to it.
There are six numerical data types in Java: byte, short, int, long, float, and
double.
Object names are synonymous with variables whose contents are memory
Numerical data types are called primitive data types, and objects are called
reference data types.
Precedence rules determine the order of evaluating arithemetic expressions.
Symbolic constants hold values just as variables do, but we cannot change
their values.
The standard classes introduced in this chapter are
Math
GregorianCalendar
DecimalFormat
•
•
System.out is used to output multiple lines of text to the standard output window.
•
•
The Math class contains many class methods for mathematical functions.
The GregorianCalendar class is used in the manipulation of calendar
information.
The DecimalFormat class is used to format numerical data.
(Optional) Twos complement format is used for storing integers, and
floating-pointing format is used for storing real numbers.
•
•
K e y
System.in is used to input a stream of bytes. We associate a Scanner object to
System.in to input primitive data type.
C o n c e p t s
variables
primitive data types
reference data types
arithmetic expression
arithmetic operators
precedence rules
typecasting
implicit and explicit casting
assignment conversion
constants
standard output
standard input
echo printing
twos complement (optional)
floating point (optional)
wu23305_ch03.qxd
12/31/08
12:55 PM
Page 141
Confirming Pages
Exercises
C h a p t e r
3
141
E x e r c i s e s
Review Exercises
1. Suppose we have the following declarations:
int i = 3, j = 4, k = 5;
float x = 34.5f, y = 12.25f;
Determine the value for each of the following expressions, or explain why it
is not a valid expression.
a.
b.
c.
d.
e.
f.
g.
h.
i.
j.
(x + 1.5) / (250.0 * (i/j))
x + 1.5 / 250.0 * i / j
-x * -y * (i + j) / k
(i / 5) * y
Math.min(i, Math.min(j,k))
Math.exp(3, 2)
y % x
Math.pow(3, 2)
(int)y % k
i / 5 * y
2. Suppose we have the following declarations:
int m, n, i = 3, j = 4, k = 5;
float v, w, x = 34.5f, y = 12.25f;
Determine the value assigned to the variable in each of the following
assignment statements, or explain why it is not a valid assignment.
a.
b.
c.
d.
e.
f.
g.
h.
i.
j.
w
v
w
n
x
m
n
i
w
x
=
=
=
=
=
=
=
=
=
=
Math.pow(3,Math.pow(i,j));
x / i;
Math.ceil(y) % k;
(int) x / y * i / 2;
Math.sqrt(i*i - 4*j*k);
n + i * j;
k /(j * i) * x + y;
i + 1;
float(x + i);
x / i / y / j;
3. Suppose we have the following declarations:
int
i, j;
float x, y;
double u, v;
Which of the following assignments are valid?
a.
b.
c.
d.
e.
i
x
x
v
y
=
=
=
=
=
x;
u + y;
23.4 + j * y;
(int) x;
j / i * x;
wu23305_ch03.qxd
142
12/31/08
Chapter 3
12:55 PM
Page 142
Confirming Pages
Numerical Data
4. Write Java expressions to compute each of the following.
a.
b.
c.
d.
The square root of B2 4AC (A and C are distinct variables)
The square root of X 4Y3
The cube root of the product of X and Y
The area R2 of a circle
5. Determine the output of the following program without running it.
class TestOutput {
public static void main(String[] args) {
System.out.println("One");
System.out.print("Two");
System.out.print("\n");
System.out.print("Three");
System.out.println("Four");
System.out.print("\n");
System.out.print("Five");
System.out.println("Six");
}
}
6. Determine the output of the following code.
int x, y;
x = 1;
y = 2;
System.out.println("The output is " + x + y );
System.out.println("The output is " + ( x + y) );
Level 1 Programming Exercises ★
7. Write a program to convert centimeters (input) to feet and inches (output).
1 in 2.54 cm.
8. Write a program that inputs temperature in degrees Celsius and prints out the
temperature in degrees Fahrenheit. The formula to convert degrees Celsius
to equivalent degrees Fahrenheit is
Fahrenheit 1.8 Celsius 32
9. Write a program that accepts a person’s weight and displays the number of
calories the person needs in one day. A person needs 19 calories per pound
of body weight, so the formula expressed in Java is
calories = bodyWeight * 19;
(Note: We are not distinguishing between genders.)
wu23305_ch03.qxd
12/31/08
12:55 PM
Confirming Pages
Page 143
Exercises
143
10. Write a program that does the reverse of Exercise 9, that is, input degrees
Fahrenheit and prints out the temperature in degrees Celsius. The formula to
convert degrees Fahrenheit to equivalent degrees Celsius is
5
Celsius (Fahrenheit 32)
9
11. Write a program that inputs the year a person is born and outputs the age of
the person in the following format:
You were born in 1990 and will be (are) 18 this year.
12. A quantity known as the body mass index (BMI) is used to calculate the risk
of weight-related health problems. BMI is computed by the formula
w
BMI 2
(h100.0)
where w is weight in kilograms and h is height in centimeters. A BMI of
about 20 to 25 is considered “normal.” Write an application that accepts
weight and height (both integers) and outputs the BMI.
13. If you invest P dollars at R percent interest rate compounded annually, in
N years, your investment will grow to
P(1 R100)N
dollars. Write an application that accepts P, R, and N and computes the
amount of money earned after N years.
14. The volume of a sphere is computed by the equation
4
V r3
3
where V is the volume and r is the radius of the sphere. Write a program that
computes the volume of a sphere with a given radius r.
Level 2 Programming Exercises ★★
15. The velocity of a satellite circling around the Earth is computed by the
formula
v GME
r
where ME 5.98 1024 kg is the mass of the Earth, r the distance from the
center of the Earth to the satellite in meters, and G 6.67 1011 m3/kg s2
the universal gravitational constant. The unit of the velocity v is m/s. Write a
program that inputs the radius r and outputs the satellite’s velocity. Confirm
that a satellite that is closer to the Earth travels faster. Define symbolic
constants for ME and G. The distance to the Hubble Space Telescope from
the center of the Earth, for example, is approximately 6.98 106 m.
wu23305_ch03.qxd
144
12/31/08
Chapter 3
12:55 PM
Confirming Pages
Page 144
Numerical Data
16. Your weight is actually the amount of gravitational attraction exerted on
you by the Earth. Since the Moon’s gravity is only one-sixth of the Earth’s
gravity, on the Moon you would weigh only one-sixth of what you weigh on
Earth. Write a program that inputs the user’s Earth weight and outputs her or
his weight on Mercury, Venus, Jupiter, and Saturn. Use the values in this
table.
Planet
Mercury
Venus
Jupiter
Saturn
Multiply the Earth Weight by
0.4
0.9
2.5
1.1
17. When you say you are 18 years old, you are really saying that the Earth has
circled the Sun 18 times. Since other planets take fewer or more days than
Earth to travel around the Sun, your age would be different on other planets.
You can compute how old you are on other planets by the formula
x 365
y d
where x is the age on Earth, y is the age on planet Y, and d is the number of
Earth days the planet Y takes to travel around the Sun. Write an application
that inputs the user’s Earth age and print outs his or her age on Mercury,
Venus, Jupiter, and Saturn. The values for d are listed in the table.
Planet
Mercury
Venus
Jupiter
Saturn
d Approximate Number of Earth
Days for This Planet to Travel
around the Sun
88
225
4,380
10,767
18. Write a program to solve quadratic equations of the form
Ax2 Bx C 0
where the coefficients A, B, and C are real numbers. The two real number
solutions are derived by the formula
2
B B
4
AC
x 2A
For this exercise, you may assume that A 0 and the relationship
B 2 4AC
holds, so there will be real number solutions for x.
wu23305_ch03.qxd
12/31/08
12:55 PM
Confirming Pages
Page 145
Exercises
145
19. Write a program that determines the number of days in a given semester.
Input to the program is the year, month, and day information of the first and
the last days of a semester. Hint: Create GregorianCalendar objects for the
start and end dates of a semester and manipulate their DAY_OF_YEAR data.
20. Modify the Ch3FindDayOfWeek program by accepting the date information
as a single string instead of accepting the year, month, and day information
separately. The input string must be in the MM/dd/yyyy format. For
example, July 4, 1776, is entered as 07/04/1776. There will be exactly two
digits for the month and day and four digits for the year.
21. Leonardo Fibonacci of Pisa was one of the greatest mathematicians of the
Middle Ages. He is perhaps most famous for the Fibonacci sequence, which
can be applied to many diverse problems. One amusing application of the
Fibonacci sequence is in finding the growth rate of rabbits. Suppose a pair of
rabbits matures in 2 months and is capable of reproducing another pair every
month after maturity. If every new pair has the same capability, how many
pairs will there be after 1 year? (We assume here that no pairs die.) The table
below shows the sequence for the first 7 months. Notice that at the end of the
second month, the first pair matures and bears its first offspring in the third
month, making the total two pairs.
Month No.
Number of Pairs
1
2
3
4
5
6
7
1
1
2
3
5
8
13
The Nth Fibonacci number in the sequence can be evaluated with the formula
1
FN 5
1 5
2
1 5
2
N
N
Write an application that accepts N and displays FN. Note that the result of
computation using the Math class is double. You need to display it as an
integer.
22. According to Newton’s universal law of gravitation, the force F between two
bodies with masses M1 and M2 is computed as
M1M2
F k d2
where d is the distance between the two bodies and k is a positive real
number called the gravitational constant. The gravitational constant k is
wu23305_ch03.qxd
146
12/31/08
Chapter 3
12:55 PM
Confirming Pages
Page 146
Numerical Data
approximately equal to 6.67E-8 dyn cm2/g2. Write an application that
(1) accepts the mass for two bodies in grams and the distance between the
two bodies in centimeters and (2) computes the force F. Use the standard
input and output, and format the output appropriately. For your information,
the force between the Earth and the Moon is 1.984E25 dyn. The mass of the
earth is 5.983E27 g, the mass of the moon is 7.347E25 g, and the distance
between the two is 3.844E10 cm.
23. Dr. Caffeine’s Law of Program Readability states that the degree of program
readability R (whose unit is mocha) is determined as
CT 2
R k V3
where k is Ms. Latte’s constant, C is the number of lines in the program that
contain comments, T is the time spent (in minutes) by the programmer
developing the program, and V is the number of lines in the program that
contain nondescriptive variable names. Write an application to compute the
program readability R. Ms. Latte’s constant is 2.5E2 mocha lines2/min2.
(Note: This is just for fun. Develop your own law, using various functions
from the Math class.)
Level 3 Programming Exercises ★★★
24. Write a program that accepts the unit weight of a bag of coffee in pounds and
the number of bags sold and displays the total price of the sale, computed as
totalPrice
= unitWeight * numberOfUnits * 5.99;
totalPriceWithTax = totalPrice + totalPrice * 0.0725;
where 5.99 is the cost per pound and 0.0725 is the sales tax. Display the
result in the following manner:
Number of bags sold:
Weight per bag:
Price per pound:
Sales tax:
Total price:
32
5 lb
\$5.99
7.25%
\$ 1027.884
Draw the program diagram.
25. If the population of a country grows according to the formula
y ce kx
where y is the population after x years from the reference year, then we can
determine the population of a country for a given year from two census
figures. For example, given that a country with a population of 1,000,000 in
1970 grows to 2,000,000 by 1990, we can predict the country’s population in
the year 2000. Here’s how we do the computation. Letting x be the number
of years after 1970, we obtain the constant c as 1,000,000 because
wu23305_ch03.qxd
12/31/08
12:55 PM
Confirming Pages
Page 147
Exercises
147
1,000,000 ce k0 c
Then we determine the value of k as
y 1,000,000e kx
2,000,000
e20k
1,000,000
2,000,000
1
k ln 0.03466
20 1,000,000
Finally we can predict the population in the year 2000 by substituting
0.03466 for k and 30 for x (2000 1970 30). Thus, we predict
y 1,000,000e0.03466(30) 2,828,651
as the population of the country for the year 2000. Write an application that
accepts five input values—year A, population in year A, year B, population
in year B, and year C—and predict the population for year C.
26. In Section 3.9, we use the formula
AR
MR 12
to derive the monthly interest rate from a given annual interest rate,
where MR is the monthly interest rate and AR is the annual interest
rate (expressed in a fractional value such as 0.083). This annual interest
rate AR is called the stated annual interest rate to distinguish it from the
effective annual interest rate, which is the true cost of a loan. If the
stated annual interest rate is 9 percent, for example, then the effective
annual interest rate is actually 9.38 percent. Naturally, the rate that the
financial institutions advertise more prominently is the stated interest
rate. The loan calculator program in Section 3.9 treats the annual
interest rate that the user enters as the stated annual interest rate. If the
input is the effective annual interest rate, then we compute the monthly
rate as
MR (1 EAR)112 1
where EAR is the effective annual interest rate. The difference between
the stated and effective annual interest rates is negligible only when
the loan amount is small or the loan period is short. Modify the loan
calculator program so that the interest rate that the user enters is
treated as the effective annual interest rate. Run the original and modified
loan calculator programs, and compare the differences in the monthly
and total payments. Use loan amounts of 1, 10, and 50 million dollars
with loan periods of 10, 20, and 30 years and annual interest rates of
0.07, 0.10, and 0.18 percent, respectively. Try other combinations also.
wu23305_ch03.qxd
148
12/31/08
Chapter 3
12:55 PM
Confirming Pages
Page 148
Numerical Data
Visit several websites that provide a loan calculator for computing
a monthly mortgage payment (one such site is the financial page at
www.cnn.com). Compare your results to the values computed by the
websites you visited. Determine whether the websites treat the input
annual interest rate as stated or effective.
27. Ask the user to enter his or her birthday in the MM/DD/YYYY format and
output the number of days between the birthday and today. This gives the
person’s age in days.
Development Exercises
For the following exercises, use the incremental development methodology
to implement the program. For each exercise, identify the program tasks,
create a design document with class descriptions, and draw the program
diagram. Map out the development steps at the start. State any assumptions
you must make about the input. Present any design alternatives and justify
your selection. Be sure to perform adequate testing at the end of each
development step.
28. Develop an application that reads a purchase price and an amount tendered
and then displays the change in dollars, quarters, dimes, nickels, and
pennies. Two input values are entered in cents, for example, 3480 for \$34.80
and 70 for \$0.70. Display the output in the following format:
Purchase Price:
Amount Tendered:
\$ 34.80
\$ 40.00
\$ 5.20
5
0
2
0
0
one-dollar bill(s)
quarter(s)
dime(s)
nickel(s)
penn(y/ies)
Notice the input values are to be entered in cents (int data type), but
the echo printed values must be displayed with decimal points (float
data type).
29. MyJava Coffee Outlet runs a catalog business. It sells only one type of
coffee beans, harvested exclusively in the remote area of Irian Jaya. The
company sells the coffee in 2-lb bags only, and the price of a single 2-lb
bag is \$5.50. When a customer places an order, the company ships the
order in boxes. The boxes come in three sizes: the large box holds 20 bags
of 2 lb, the medium 10 bags, and the small 5 bags. The cost of a large
wu23305_ch03.qxd
12/31/08
12:55 PM
Confirming Pages
Page 149
Exercises
149
box is \$1.80; a medium box, \$1.00; and a small box, \$0.60. The order is
shipped in the least expensive manner. For example, the order of 52 bags
will be shipped in four boxes: two large, one medium, and one small. The
rule for packing is to fill the large and medium boxes completely; that is,
the box is fully packed. Only the small boxes can have empty spaces. For
example, to ship 52 bags, you could have used 3 large boxes, but that
would leave the third box not fully packed. Develop a program that
computes the total cost of an order. Display the output in the following
format:
Number of Bags Ordered: 52 - \$ 286.00
Boxes Used:
2 Large - \$3.60
1 Medium - \$1.00
1 Small - \$0.60
\$ 291.20
30. Repeat Exercise 29, but this time, accept the date when the order is placed
and display the expected date of arrival. The expected date of arrival is two
weeks (14 days) from the date of order. The order date is entered as a
single string in the MM/dd/yyyy format. For example, November 1, 2008
is entered as 11/01/2008. There will be exactly two digits each for the
month and day and four digits for the year. Display the output in the
following format:
Number of Bags Ordered: 52 - \$ 286.00
Boxes Used:
2 Large - \$3.60
1 Medium - \$1.00
1 Small - \$0.60
Your total cost is: \$ 291.20
Date of Order:
Expected Date of Arrival:
November 1, 2008
November 15, 2008
31. Using a Turtle object from the galapagos package, draw three rectangles.
Accept the width and the length of the smallest rectangle from the user. The
middle and the largest rectangles are 40 and 80 percent larger, respectively,
than the smallest rectangle. The galapagos package and its documentation
are available at the McGraw-Hill book website.
wu23305_ch03.qxd
150
12/31/08
Chapter 3
12:55 PM
Confirming Pages
Page 150
Numerical Data
32. Develop a program that draws a bar chart using a Turtle object. Input five int
values, and draw the vertical bars that represent the entered values in the
following manner:
12
10
7
5
3
Your Turtle must draw everything shown in the diagram, including the axes
and numbers.
```