chars
, and Java ArithmeticArithmetic in Java looks pretty much like the arithmetic you learned in math, but there are some surprises you need to know about.
Any sequence of characters surrounded by double quotes is called a string literal. Examples:
"cse1020" "Java By Abstraction" ""
The type of a string literal is String
, which
we study in detail in Chapter 6.
We have already seen that System.out.print
and System.out.println
can be used to print
string literals.
A string is made up of individual characters. The type of an
individual character is char
.
char
literals come in 3 forms. The easiest to
understand is a single character between single quotes:
'A' 'a' '+'
Notice that the single quote and double quote are used by Java
to indicate char
and String
literals.
This begs the question: How do create
String
s such as:
Bart said, "Don't have a cow, man."
that contain single and double quotation marks?
Java uses a backslash to indicate an escape sequence for a small number of special characters.
'\'' // char literal for ' '\"' // char literal for " '\\' // char literal for \ '\t' // char literal for tab '\n' // char literal for line feed (newline on linux and OS X)
See Figure 1.11 in the textbook for the complete list of special characters.
Bart said, "Don't have a cow, man."
System.out.println("Bart said, \"Don\'t have a cow, man.\"");
'\t' is the tab character
System.out.println("\'\\t\' is the tab character");
Unicode is a standard for representing text expressed in most of the world's writing systems. The basic idea is to map the integers 0 through 65,535 to individual characters.
Some types are built into the Java language. These types are called the primitive types.
The primitive types that can hold integer values are:
byte
, from -128 to 127, inclusiveshort
, from -32768 to 32767, inclusive int
, from -2147483648 to 2147483647, inclusivelong
, from -9223372036854775808 to 9223372036854775807, inclusive char
, from 0 to 65535byte
and short
will not really
be used in 1020.
A long
literal is an integer number followed
immediately by L
.
long zero = 0L; long negativeFive = -5L; long thousand = 1000L;
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 |
* | multiplication operator | x * y | -98 |
/ | division operator | x / y | -2 |
% | remainder operator | x % y | 0 |
+ | addition operator | x + y | 7 |
- | subtraction operator | x - y | 21 |
long
TypesAssume that you have the following declarations for each example in the table below:
long x = 14; long y = -7;
Operator | Name | Example | Value |
+ | unary plus operator | +x +y |
14L -7L |
- | unary minus operator | -x -y |
-14L 7L |
* | multiplication operator | x * y | -98L |
/ | division operator | x / y | -2L |
% | remainder operator | x % y | 0L |
+ | addition operator | x + y | 7L |
- | subtraction operator | x - y | 21L |
Java guarantees that if you apply a:
int
, the result is of type int
long
, the result is of type long
int
s, the result is of type int
long
s, the result is of type long
This property is called closure.
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 |
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).
Closure requires that the result of an arithmetic operation with two
int
literals or variables also be of type int
.
When a value falls outside
of the range that the int
type can represent the result is
arithmetic overflow (the same can be said for long
).
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 = Integer.MAX_VALUE; System.out.println(max + 1); int min = Integer.MIN_VALUE; System.out.println(min - 1); } }
The 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 |
7L / 2L | 3.5 | 3L |
1 / 2 | 0.5 | 0 |
-9 / 5 | -1.8 | -1 |
9L / -5L | -1.8 | -1L |
3 / 0 | ∞ | ArithmeticException |
Java also provides an operator to compute the remainder after division.
The remainder operator is the %
symbol.
Java Remainder Expression | Java Remainder |
6 % 2 | 0 |
7L % 2L | 1L |
1L % 2L | 1L |
-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.
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 * 15) 5 + 150 155 |
++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
It makes sense that you can store an int
value in a long
variable
int anInt = 50; long aLong = anInt;
In the above example, nothing happens to the variable
named anInt
. The value stored in
anInt
is copied, converted to type
long
, and stored in aLong
.
Conversion of int
to long
is called a widening conversion, and are always
performed automatically by the compiler when needed.
Storing a long
in an int
variable is dangerous (because the
range of legal values is much smaller for int
).
Conversion of long
to int
is called a narrowing conversion, and is never
performed automatically by the compiler.
If you need to perform a narrowing conversion, you can do so by using a cast:
long seventyYrsInSecs = 60L * 60L * 24L * 365L * 70L; int secsPerYr = (int) (seventyYrsInSecs / 70L);
(int)
converts whatever is immediately to
the right to type int
.
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); } }