Skip to main content

Section 2.8 Mathematical Expressions

Expressions in Java are combinations of variables, literals, operators, and other subexpressions that evaluate to a value with a type. Expressions are the building blocks of Java programs and are used to perform computations and help make decisions programmatically.
Four of the more common types of Java expressions are:
  1. Mathematical Expressions
  2. Assignment Expressions
  3. Relational Expressions
  4. Logical Expressions
Mathematical Expressions involve mathematical operations such as addition (+), subtraction (-), multiplication (*), division (/), and modulus (%). The evaluation of an arithmetic expression produces a number. For example:
jshell> 9 + 5;        // Addition
$1 ==> 14
|  created scratch variable $1 : int

jshell> 9 - 5;        // Subtraction
$2 ==> 4
|  created scratch variable $2 : int

jshell> 9 * 5;        // Multiplication
$3 ==> 45
|  created scratch variable $3 : int

jshell> 9 / 5;        // Integer division
$4 ==> 1
|  created scratch variable $4 : int

jshell> 9 % 5;        // Modulus (remainder of division)
$5 ==> 4
|  created scratch variable $5 : int

jshell>
Table 2.8.1. Common Java Mathematical Operators
Operator Type Description
+ binary, infix addition
- binary, infix subtraction
- unary, prefix negation
* binary, infix multiplication
/ binary, infix division
% binary, infix modulus
The unary prefix operator - in Java is negation, which is used to compute the additive inverse of a numeric value or variable. In other words, it turns a positive value negative, and a negative value positive.
An important general rule to know regarding Java’s binary operators is as follows.

Rule: Binary Operators Require Operands of the Same Type.

Operands of standard mathematical operators must have the same type, even if Java must automatically promote one operand type to match the other operand type.
This applies to the numeric operand types int, long, float, and double, and implies the following.
  • If we add two doubles, the sum produced is a double.
  • If we multiply two floats, the product is a float.
  • If we subtract two longs, the difference is a long.
  • If we divide two ints, the quotient is an int.
That last implication is a bit troubling. The value 3 divided by 2 is 1.5. If 3 and 2 are int types, how can the quotient hold a value of type int? Let’s give it a try in JShell.
jshell> int x = 3, y = 2;       // Declare and init two ints
x ==> 3
|  created variable x : int
y ==> 2
|  created variable y : int

jshell> x / y;                  // Divide ints
$3 ==> 1                        // Is this a mistake?
|  created scratch variable $3 : int

jshell>
Sure enough, as you can see by the session above, dividing 3 by 2 produces an int with a value of 1, not 1.5. Because 1.5 cannot be stored in an int, the result produced has value of 1. Specifically, dividing two integer number types performs integer division, not floating point division. Integer division drops any fractional parts of the result. A frequent pitfall of novice Java programmers is to expect a fractional part in a result after dividing two integer types, which is impossible, where would it be stored? Of course, this is not a problem when dividing floating point types.

Rule: Operand Type Dictates Operator Implementation.

If the division operator has two integer operand types, integer division is performed, resulting in an integer result of a type matching operands. Decimals in the result are dropped.
Mathematical functions are available in Java by preceding the function with Math and a dot, for example Math.pow(2,3) evaluates 23 producing 8. Technically, when using this notation we are accessing static methods of the Math class. The following table lists many of the common mathematical functions implemented by Math. These may be included in any Java expression and will be invoked during expression evaluation.
Table 2.8.2. Java Math class static methods
Method/Constant Description
Math.PI The mathematical constant Ο€.
Math.E Euler’s mathematical constant e.
Math.pow(x, y) Raise x to the power of e and return result
Math.abs(x) Return the absolute value of x.
Math.sqrt(x) Compute the square root of x.
Math.min(x, y) Return the minimum of x and y.
Math.max(x, y) Return the maximum of x and y.
Math.ceil(x) Return the next integer greater than x.
Math.floor(x) Return the next integer below than x.
Math.round(x) Round x to the nearest integer.
Math.exp(x) Raise Euler’s number (e) to the power of x (ex).
Math.log(x) Compute the natural logarithm of x (ln(x)).
Math.log10(x) Compute the base-10 logarithm of x (log10(x)).
Math.sin(x) Compute the sine function of x.
Math.cos(x) Compute the cosine function of x.
Math.tan(x) Compute the tangent function of x.
Math.sinh(x) Compute the hyperbolic sine function of x.
Math.cosh(x) Compute the hyperbolic cosine function of x.
Math.tanh(x) Compute the hyperbolic tangent function of x.
Math.asin(x) Compute the inverse (arc) sine function of x.
Math.acos(x) Compute the inverse (arc) cosine function of x.
Math.atan(x) Compute the inverse (arc) tangent function of x.
Math.atan2(x, y) An alternative inverse tangent function taking rectilinear
coordinates x,y and returning the angle ΞΈ.
For example, consider the following JShell session, where we compute c=a2+b2.
jshell> double a = 3, b = 4;
a ==> 3.0
|  created variable a : double
b ==> 4.0
|  created variable b : double

jshell> double c = Math.sqrt( Math.pow(a,2) + Math.pow(b,2) );
c ==> 5.0
|  created variable c : double

jshell>
When expressions become more complex, involving multiple operators, operands, functions, etc., the standard mathematical operator precedence determines the order of evaluation, which is: parentheses > exponents > multiplication and division > addition and subtraction. PEMDAS is an mnemonic that helps us recall operator precedence in arithmetic expressions. When multiple operators of the same precedence are adjacent, evaluation is performed left-to-right. Expressions within parentheses take precedence over all other operations.
The PEMDAS mnemonic is represented below with standard operator precedence
In the following example, note how the result of 2+3βˆ—4 is 14, not 20. A value of 20 would be expected if the expression was evaluated strictly left-to-right. Because the * operator takes precedence over +, the multiplication is performed before the addition. Surrounding the first subexpression with parentheses causes the subexpression to be evaluated first due to the higher precedence of parentheses relative to *.
jshell> 2 + 3 * 4;
$1 ==> 14
|  created scratch variable $1 : int

jshell> (2 + 3) * 4;
$2 ==> 20
|  created scratch variable $2 : int

jshell>

Activity 2.8.1.

Using JShell in verbose mode, evaluate the expression 1 / 3. Why did you get the answer you did?
Answer.
Operands are type int so the / operator is integer division. The resulting value is one-third (~0.333…), but the fractional part is dropped, so the result is the int 0.

Activity 2.8.2.

Evaluate 8 - 4 / 2 and (8 - 4) / 2. Why are the answers different?
Answer.
The answers are 6 and 2, respectively. These result differ because in the first expression, division occurs before subtraction. In the second expression, parentheses ensure that the subtraction occurs before the division.

Activity 2.8.3.

Evaluate 14 % 12. Where did that answer come from?
Answer.
14 divided by 12 is 1, with a remainder of 2. The modulus operator (%) computes the remainder after integer division.

Activity 2.8.4.

A customer just ordered 100 bagels from my bagel shop. I charge one price for each baker’s dozen (13) and another price for single bagels. How might I calculate the number of baker’s dozens and the number of remain single bagels using the operators / and %?
Answer.
Divide by 13 using integer division to compute the number of baker’s dozens, and then use modulus to compute the remaining single bagels. Multply each result by their respoective prices and add both for the total.
jshell> int nbagels = 100;
nbagels ==> 100
|  created variable nbagels : int

jshell> int bdozens = nbagels / 13;
bdozens ==> 7
|  created variable bdozens : int

jshell> int nsingle = nbagels % 13;
nsingle ==> 9
|  created variable nsingle : int

jshell> "Charge for " + bdozens + " baker's dozens and " + nsingle + " single bagels"
$4 ==> "Charge for 7 baker's dozens and 9 single bagels"
|  created scratch variable $4 : String

Activity 2.8.5.

Write an expression that calculates the length of the hypotenuse of a right-triangle with two sides of length 5 and 12 connected by a right angle.
Answer.
jshell> Math.sqrt(5*5 + 12*12);
$1 ==> 13.0
|  created scratch variable $1 : double