Arithmetic in Java looks pretty much like the arithmetic you learned in math, but there are some surprises you need to know about.
int
TypesAssume that you have the following declarations for each example in the table below:
int x = 14; int y = -7;
Operator | Name | Example | Value |
+ | unary plus operator | +x +y |
14 -7 |
- | unary minus operator | -x -y |
-14 7 |
* | mulitplication operator | x * y | -98 |
/ | division operator | x / y | -2 |
% | remainder operator | x % y | 0 |
+ | addition operator | x + y | 7 |
- | subtraction operator | x - y | 21 |
How do you represent the passage of time on a computer? A widely used method is to store the number of seconds that have elapsed since a certain date.
Assuming that there are exactly 24 hours in a day and 365 days in
a year, write a Java program that uses int
literals
(or variables) to calculate the:
Your program should use int
variables, and it should
print the results to the console.
Mathmatical Value | Java Value | |
seconds per year | 31 536 000 | 31536000 |
seconds in 70 years | 2 207 520 000 | -2087447296 |
mins in 30 secs | 0.5 | 0 |
Many existing operating systems represent the passage of time
using an integer type that is similar to Java's int
.
Such systems measure time elapsed since midnight January 1, 1970.
The Year 2038 Problem refers to the fact that this time keeping
system fails on January 19, 2038 (a bit more than 68 years after
the starting date of January 1, 1970).
int
?The Java type int
is used to represent positive
and negative whole numbers within a specified range.
Minimum Value | Maximum Value |
-231 = -2147483648 | 231 - 1 = 2147483647 |
All of the built-in arithmetic operations satisfy the
closure property: the result of an arithmetic
operation has the same type as the type of the operands
(e.g. the sum of two int
variables is
an int
value). This produces some
results that are surprising to novice programmers.
Expression | Mathmatical Value | Java Value |
2000000000 + 150000000 | 2150000000 | -2144967296 |
-2000000000 - 150000000 | -2150000000 | 2144967296 |
7 / 2 | 3.5 | 3 |
3 / 0 | ∞ | ArithmeticException |
int
DivisionThe Java division operator is the /
symbol.
Satisfying closure means that dividing two int
variables must produce an int
result. Java
accomplishes this by discarding the fractional part of the
result:
Expression | True Division | Java Division |
6 / 2 | 3 | 3 |
7 / 2 | 3.5 | 3 |
1 / 2 | 0.5 | 0 |
-9 / 5 | -1.8 | -1 |
9 / -5 | -1.8 | -1 |
3 / 0 | ∞ | ArithmeticException |
int
RemainderJava also provides an operator to compute the remainder after division.
The remainder operator is the %
symbol.
Java Remainder Expression | Java Remainder |
6 % 2 | 0 |
7 % 2 | 1 |
1 % 2 | 1 |
-9 % 5 | -4 |
9 % -5 | 4 |
3 % 0 | ArithmeticException |
Write a Java program that computes the number of quarters, dimes, nickels, and pennies you would need to make 94 cents. You should compute the number of quarters first, followed by the number of dimes, followed by the number of nickels, followed by the number of pennies.
Closure requires that the result of an arithmetic operation with two
int
literals or variables also be of type int
.
What happens when we add 1
to the maximum value that can be
represented by the int
type?
What happens when we subtract 1
from the minimum value that can be
represented by the int
type? When a value falls outside
of the range that the int
type can represent the result is
arithmetic overflow.
Java ensures closure by treating the range as circular
(adding 1
to the maximum int
value produces the
minimum int
value, and subtracting 1
from the
minimum int
value produces the maximum int
value).
public class IntOverflowExample { public static void main(String[] args) { int max = 2147483647; System.out.println(max + 1); int min = -2147483648; System.out.println(min - 1); } }
int
OperatorsThe operators we have seen so far are called binary operators because they require two operands. Java defines six unary operators that require one operand.
The unary plus operator +
simply indicates a positive value.
Note that you cannot use the operator to convert a negative value
to a positive value; thus, this operator does not do anything
when you use it on an int
literal or variable.
The following program prints the number 17 on three lines:
public class IntUnaryPlusExample { public static void main(String[] args) { int x = 17; System.out.println(x); // unary plus applied to an int literal int y = +17; System.out.println(y); // unary plus applied to an int variable y = +x; System.out.println(y); } }
The unary minus operator -
negates an expression.
The following program prints the number -17 on two lines:
public class IntUnaryMinusExample { public static void main(String[] args) { int x = 17; // unary minus applied to an int variable y = -x; System.out.println(y); // unary minus applied to an expression y = -(14 + 3); System.out.println(y); } }
A common occurrence in computer programming is increasing
(incrementing) or decreasing (decrementing)
the value of a variable by 1
.
Java provides the increment operator ++
and the decrement operator --
that can
be used immediately before or after a variable of type
int
.
public class IntIncrementDecrementExample1 { public static void main(String[] args) { int x = 0; ++x; // the value of the variable named x is now 1 --x; // the value of the variable named x is now 0 x++; // the value of the variable named x is now 1 x--; // the value of the variable named x is now 0 } }
Notice that the placement of the operator (before and after the variable) was unimportant in this example. The placement becomes important when you apply the operator to a variable that is used in a larger expression.
The prefix version of the operator occurs when the operator is placed in front of the variable. Java uses the incremented or decremented value of the variable in the expression for prefix increment or decrement.
Expression | Value of y | Final Value of x |
int x = 0; int y = 10 + ++x; |
10 + (1) ⇒ 11 | 1 |
int x = 5; int y = --x + 3; |
(4) + 3 ⇒ 7 | 4 |
public class IntPrefixIncrementExample { public static void main(String[] args) { int x = 10; System.out.println(++x); // should print 11 } }
The value of the expression ++x
is the value of
x
incremented by 1.
The postfix version of the operator occurs when the operator is placed after the variable. Java uses the current value of the variable in the expression for postfix increment or decrement.
Expression | Value of y | Final Value of x |
int x = 0; int y = 10 + x++; |
10 + (0) ⇒ 10 | 1 |
int x = 5; int y = x-- + 3; |
(5) + 3 ⇒ 8 | 4 |
public class IntPostfixDecrementExample { public static void main(String[] args) { int x = 10; System.out.println(x--); // should print 10 } }
The value of the expression x--
is the current value of
x
.
When you use multiple operators in the same expression you need to consider the order that the operators are evaluated. Each operator has a precedence level; operators with a higher precedence level are evaluated before ones with a lower level.
Precedence | Operator | |
highest | ++, -- | postfix operators |
++, --, +, - | prefix unary operators | |
*, /, % | multiply, divide, remainder | |
+, - | addition, subtraction | |
lowest | = | assignment |
Like regular arithmetic, multiplication and division (and remainder) have higher precedence than addition and subtraction.
Like regular arithmetic, expressions inside of parentheses are always evaluated first.
Assume that for each of the following examples shown in the table below we have the declarations:
int x = 10; int y = 15;
Expression | Evaluation |
5 * x + y |
(5 * x) + y (5 * 10) + y 50 + y 50 + 15 65 |
++x * y |
(++x) * y 11 * y 11 * 15 165 |
y-- * (x - 8) |
y-- * (10 - 8) y-- * 2 15 * 2 30 |
Expressions with multiple binary operators (addition, subtraction, multiplication, division, remainder) of the same precedence are evaluated from left to right. These operators are said to be left-associative.
Assume that for each of the following examples shown in the table below we have the declarations:
int x = 10; int y = 15;
Expression | Evaluation |
5 + x + y |
(5 + x) + y (5 * 10) + y 15 + y 15 + 15 30 |
x * 6 / 2 % y |
(x * 6) / 2 % y 60 / 2 % y (60 / 2) % y 30 % y 30 % 15 0 |
50000 * 50000 / 50000 |
(50000 * 50000) / 50000 -1794967296 / 50000 -35899 |
50000 / 50000 * 50000 |
(50000 / 50000) * 50000 1 * 50000 50000 |
You can test your understanding of operator precedence and association by running the ArithmeticOperatorGame.
javac ArithmeticOperator*java
java ArithmeticOperatorGame
long
The Java type long
is used to represent positive
and negative whole numbers within a specified range that is wider
than the range for int
.
Minimum Value | Maximum Value |
-263 = -9,223,372,036,854,775,808 | 263 - 1 = 9,223,372,036,854,775,807 |
Type long
supports all of the operators supported by
type int
.
A long
literal is a whole number followed by
an L
that is inside the range given above; for example:
public class LongLiteralExamples { public static void main(String[] args) { long zero = 0L; long negFive = -5L; long seventyYrsInSecs = 60L * 60L * 24L * 365L * 70L; } }
8 bytes are used to store a variable of type long
.
int
and long
1You are allowed to use a value of type int
whenever a value of type long
is required. The Java
compiler will automatically apply a widening conversion
to the int
value to convert it to
a long
value (we say that the int
value is
promoted to a long
value).
public class IntToLong { public static void main(String[] args) { int x = 5; long y = x; // y is assigned the int value of x long z = 10 * 10; // z is assigned the int value of 100 } }
In the above example, the statement long y = x;
leaves the variable named x
unchanged (i.e.
x
does not change its type to long
).
Instead, the compiler looks up the value of x
and converts
the value to type long
.
int
and long
2The Java compiler will not let you use a value of type
long
where a value of type int
is
required (even if the long
value is inside the
range that can be stored by int
). Converting
a long
value to an int
value is
an example of a narrowing conversion.
When the situation arises where you want to use a
long
value where an int
is
required, you must explicitly cast the
long
value:
public class LongToInt { public static void main(String[] args) { long seventyYrsInSecs = 60L * 60L * 24L * 365L * 70L; int secsPerYr = (int) (seventyYrsInSecs / 70L); } }
Casting a long
value to an int
value
will produce unusual results if the original long
value
does not fall in the range allowed by int
.
int
and long
with OperatorsIf you use an arithmetic operator with an int
and a long
operand, the Java compiler
will automatically promote the int
value to
type long
. The resulting value of the operation
will be have type long
.
public class MixedIntLongExample { public static void main(String[] args) { long x = 5 + 100L; // next statement will cause a compilation error int y = 5 + 100L; } }
In the above example, the expression 5 + 100L
will be evaluated by the compiler as:
⇒ (long)(5) + 100L
The resulting
⇒ 5L + 100L
⇒ 105L
long
value cannot be assigned to the
int
variable y
without a cast.
public class LongDivision { public static void main(String[] args) { // milliseconds in a day long millisPerDay = 1000 * 60 * 60 * 24; // microseconds in a day long microsPerDay = 1000 * 1000 * 60 * 60 * 24; // prints 1000? System.out.println(microsPerDay / millisPerDay); } }