
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*javajava ArithmeticOperatorGamelongThe 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);
}
}