Simple Arithmetic in Java

You have already seen how to use Java to read and write strings of text.
As we all know, computers are wonderful at dealing with numbers. This
set of exercises will introduce you to simple arithmetic calculations in
Java, as well as some new types of variables used to store numbers.
Solutions are available here.

Copies of the code in these notes can be found in the directory:

/import/teaching/BSc/1st/ItP

Adding two numbers

Consider the program below, which adds two numbers together and prints
the result on the screen. The program can be found in the file
/import/teaching/BSc/1st/ItP/Prog21.java.

Lines 5 and 6 are variable declarations with initialisers, similar to
those you have already seen in the HelloYou programs. However,
in this program we want our variables to hold numbers rather than text
strings, so we declare i and j as type
int instead of String. The word
'int' is Java shorthand for 'integer', that is, a number
with no fractional part. 27, -16 and 0 are all examples of integers,
whereas 42.7 is not. An important point to note is that the integer
'10' is not necessarily stored by the computer as the two digits '1' and
'0'. Numbers will usually be stored in a respresentation that is easier
(and faster) for the computer to understand, but not particularly
readable for humans. We will return to this subject later in the
exercise set when we cover reading numbers from the keyboard.

Line 7 adds together the numbers stored in i and
j and stores the sum back into i. Note that
the previous value of i is destroyed by this operation.
Variables can be treated as named 'storage boxes' in the memory of the
computer, where each box can hold a single item of a particular type
(text string, integer, etc). Assigning a new value to the box named
i means that the old contents of the box must be thrown
away.

Line 8 should be familiar to you already. It prints out the text
The sum is: followed by the number stored in
i. As before, the plus symbol is used to join together the
two strings to be printed. But i is an integer, not a
string! How does this work? The Java compiler knows that
println requires a string to print, so it arranges to
convert the value of i into its string representation when
the command is executed. This automatic conversion feature will work
for most Java types, converting them to text strings that can be printed
out or otherwise displayed. Most other programming languages offer
similar features for easily displaying values of different types.
Unfortunately, automatic conversions in the other direction, from a text
string to a number, are not generally provided.

As well as addition, several other basic arithmetic operations are
provided by Java. These include subtraction, multiplication, division
and remainder, represented by the symbols '-',
'*', '/' and '%' respectively.
Experiment with changing the program to use these different operations.
Do you always get the results you expect, particularly when using the
division and remainder operations?

Exercises

What is the value in i after executing the following
program segments?

int i = 12;
int j = 5;
i = i / j;

int i = 12;
int j = 5;
i = i % j;

int i = 10;
int j = 5;
i = i / j;

The answers to exercises 1.1 and 1.3 are the same. Explain why.

More complex arithmetic

More complicated arithmetic expressions cn be written quite easily. The
program below shows one example of combining the various operators in a
more interesting calculation (this program can be found in the file
Prog22.java in the usual directory).

You should experiment with some different calculations of your own and
see if you always obtain the results you expect: especially when
combining multiplication and division with addition and subtraction.
For example, the program above produces an answer of 77, whereas you
might expect the result to be 41: (12 times 6 = 72; 72 plus 20 = 92; 92
divided by 2 = 46; 46 minus 5 = 41). What's going on here?

It turns out that Java's arithmetic operations have a built in
'priority', so that multiplications, divisions and remainders are
evaluated before additions and subtractions. In Prog22, Java
will first calculate 12 times 6 = 72; then 20 divided by 2 = 10; then 72
+ 10 = 82; and finally 82 minus 5 = 77. You can use parentheses
'(' and ')' to force a particular order of
evaluation: anything inside parentheses is calculated before the rest of
the expression. So to evaluate the expression in Prog22 in strict
left-to-right order you would use:

i = (i * 6 + i) / 2 - k;

which should produce the desired answer of 41. As a matter of style and
readability it is often desirable to include parentheses in expressions
even when the default operator priority does exactly what you want. If
we write the original calculation from Prog22 as:

i = (i * 6) + (i / 2) - k;

the parentheses do not change the result, but make the program much
easier for a human being to read and understand.

Exercises

What is the value of i after executing the following
code segments? Assume that the variables have been initialised to
i = 21, j = 42 and k = 11;

i = 4 * (j + 16) % k;

i = i - j + k * 7;

i = (i - j + k) * 7;

Explain why the answers to exercises 3.2 and 3.3 are different.

More on integer variables

Although we have said that a Java int variable holds an
'integer' value, the two are in fact not exactly the same thing. The
mathematical definitionof integers includes all positive and
negative numbers with no fractional part; clearly, there must be an
infinite number of different integers. However, because of the way the
Java compiler is written (and the way that most computers internally
represent numbers) each Java int variable must fit within a
small, fixed amount of memory. This means that an int can
only represent a subset of the true integers. To illustrate this point,
compile and run the program below:

The correct answer is, of course, 4000000000. Unfortunately this number
is too large to fit in an int variable, so the program
prints an incorrect result. When this occurs, we say that the answer
has overflowed the range of the variable. Note that the exact
incorrect answer printed is not important at this stage, the program
simply serves as an example of the overflow effect.

Exercises

Modify Prog23 so that it will print both the largest (most positive)
and smallest (most negative) values that will fit into a Java
int variable.

The Java language supports two other types of 'integer' variables:
long and short. Produce two further
modified versions of Prog23 that print the largest and smallest
possible values of a long and a short
respectively. Note: long variables should be
initialised using commands such as:

long l;
l = 2042L;

or

long l = 2042L;

Where the 'L' character indicates that the value should
be treated as a long instead of a normal
int. No special syntax is necessary when initialising
variables of type short.

Reading numbers from the keyboard

You have already seen how to print numeric values on the screen; Java
provides a useful automatic conversion of numbers into text strings for
display purposes. The reverse conversion is not provided -- there is no
automatic facility in the Java language itself for converting strings to
integers (or any other non-string type). Fortunately the large
collection of supporting classes supplied with Java comes to the rescue.
In this example we will make use of the Integer class which
contains a set of methods for transforming integers to and from strings
and other numeric types. The program below shows how to read a single
integer from the keyboard and display it on the screen:

Most of this program, down as far as line 12, should be quite familiar
to you. Line 12 reads a line of input from the keyboard as a string
text: at this point the program neither knows nor cares whether the text
might represent a number, someone's name or anything else.

Line 13 uses the parseInt method from the
Integer class to attempt to extract an integer value from
the text that was entered. The term parse refers to the process
of assigning structure to an unstructured collection of text or other
raw data. Parsing is the first step carried out by most compilers,
taking the raw text of the program and breaking it down into classes,
methods, declarations, method calls, etc. In this case, the parsing
task consists of determining whether the entered text could represent an
integer value and if so, assigning that value to i. If the
text does not respresent a valid integer (for instance, if you were to
enter '19.8' or 'foo42', the
parseInt method will throw a
NumberFormatException. You should try entering some
invalid text to see what happens when the exception is thrown.

A method such as parseInt would be relatively difficult and
complex to write from scratch, as it has to carry out a large amount of
so-called error checking to make sure that the text it is given
does in fact represent an integer. You will find as you start to write
larger programs, especially when these process input that you have no
control over, that a significant amount of code is concerned with just
checking for, and dealing with, all of the things that could possibly go
wrong. Most of the time -- when there is nothing wrong with the input
-- this code does nothing, but it is important for it to be there when
some bad input does come along. Having the program simply terminate
after producing an obscure error message, as Prog24 does when given bad
input, is usually not an acceptable solution. In future weeks you will
learn how to 'catch' exceptions and other error conditions thrown by
your programs and respond to them in an appropriate way.

Exercises

Modify Prog24 so that it reads two integers from the keyboard, then
prints their sum, difference, product, quotient and remainder after
division.

Modify your program further to use longs instead of
ints. (Hint: Look at the methods provided by the
Long class.