Arithmetic expressions are formed by combining numeric types
(constants, variables and expressions) using arithmetic operators. The
basic concepts are same as in case of C/C++ although there are some
differences.
1. Type Conversions in Expressions
Automatic type promotion takes place in arithmetic expressions according to the following rules:
Suppose following variables are declared in a method/block:
int i = 10; byte b= 3; short s = 16; char c = 65; long l = 100;
float f = 10.3f; double d = 4.88;
The following table demonstrates some expressions formed using above variables, their result type and the value calculated using the conversion rules defined above:
2. Integer Expressions
An Integer expression is one where all the operands are of integer type. The result of such an expression will always be integer as in case of C/C++. The fractional part is simply ignored. For example the result of expression 5/3 is 1.
While evaluating an integer expression, the following rules are applied:
1. An operand of type byte, short or char is converted to int before evaluation of the expression. This is true for unary as well as binary operators. So the operands will always be of type int or long.
2. While evaluating expressions the operators are applied according to precedence rules, which are same as in C/C++.
3. If both the operands of an operator are of type int then result will also be of type int.
4. If both the operands of an operator are of type long then result will also be of type long.
5. If one of the operands of an operator is of type int and the other is of type long then the int would be converted to long and the result will also be of type long.
Integer division including modulo (%) operator may result in an ArithmeticException (run time error).
Example: The following example illustrates what happens on division by zero.
class ZeroDivision
{
public static void main(String args[])
{
int i;
int x = 5;
i = x / 0; // x % 0 will also lead to exception.
int y = i + 3;
System.out.println(y);
}
}
On execution of the above program, the following exception (run time error) occurs at statement
i = x/0; and the program terminates:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at ZeroDivision.main(ZeroDivision.java:5)
The reason is that division by zero is not defined in Java when both the operands are integer. In Java, it is possible to recover from a run time error and continue the execution. This is done by using exception-handling mechanism that will be discussed later.
Overflow in Integer Expressions
Except division no other integer calculations result in any exception although the result might be arithmetically incorrect. On evaluation of an operator (or complex integer expression), the result may be outside the range of the result data type. Such a situation is called overflow. The actual result is obtained by truncating the extra bits in the result. For example, if the type of the result is
int and the result contains more than 32 bits, then 32 least significant bits in the result are kept and rest are simply truncated to obtain the result. Thus the result will not be correct and in some cases result may be of the wrong sign.
Example:
int tooBig = Integer.MAX_VALUE + 1;
MAX_VALUE is a static final constant defined in the class Integer. Its value represents the maximum positive value that can be stored in a variable of type int, which is, 2147483647. The result of the above expression will be of type int as both the operands are of type int. But the expression would lead to overflow as we are adding one to highest integer value.
In fact, on displaying value of variable tooBig, you will find that it holds the value -2147483648, which is the minimum value that an integer can hold. The only solution to the overflow problem is to use higher data type i.e. use long type if you expect the result to exceed the limit of the int.
3. Floating-Point Expressions
These are the expressions involving floating-point types. A floating-point expression may also have integer types i.e. a mix of integer and floating-point types. If a floating-point expression has an operator whose both the operands are integer then its result will be calculated as per integer arithmetic rules. For example the expression 3.1 + 5/3 is a floating-point expression but its result will be 4.1 (3.1 + 1) and not 4.76 (3.1 + 1.66) as one might expect because the result of the expression 5/3 would still be int.
While evaluating a floating-point expression, the following rules are applied:
In case of float type these values are represented by constants Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY and Float.NaN respectively defined in the class Float.
Similarly in case of double type these values are represented by constants
Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY and Double.NaN respectively defined in the class Double.
No exception occurs on division by zero as this is defined in case of floating point expressions.
The result of division by zero is either Infinity or –Infinity. Similarly no error occurs if the floating-point expression involves non-determinant forms like 0/0, 0/, /, /0, complex numbers etc. The result of such an expression is NaN (Not a Number).
Examples:
The following code segments demonstrate the use of three special values.
(i) double d = 10.0/0;
System.out.println(d);
The output of the above println() statement would be Infinity.
(ii) double d = -10.0/0;
System.out.println(d);
The output of the above println() statement would be Infinity.
(iii) double d = 0.0/0;
System.out.println(d);
The output of the above println() statement would be NaN.
(iv) double d = Math.sqrt(-25);
System.out.println(d);
The output of the above println() statement would be NaN.
Note: The result will be same if we substitute the type double with float.
Overflow in Floating-Point Expressions
If the result of a floating-point expression exceeds the maximum value (magnitude) it is represented by +Infinity or –Infinity depending on the sign of the result.
Examples:
(i) double d = 1.0E+308 * 10;
System.out.println(d);
The output of the above println() statement would be Infinity. The result exceeds the
maximum value (magnitude) and its sign is positive hence it is represented as positive
Infinity.
(ii) double d = -1.0E+308 * 10;
System.out.println(d);
The output of the above println() statement would be Infinity. The result exceeds the maximum value (magnitude) and its sign is negative hence it is represented as negative Infinity.
Note: The result will be same if we substitute the type double with float and the result exceeds the maximum float value.
Underflow in Floating-Point Expressions
If the result of a floating-point expression is less than the minimum value (magnitude), it is represented by 0 (Zero).
Examples:
(i) double d = 3E-324 – 1.0E-324;
System.out.println(d);
The output of the above println() statement would be 0 (Zero). The result is less than the minimum value (magnitude) hence it is treated as 0 (Zero).
(ii) double d = -3E-324 – 1.5E-324;
System.out.println(d);
The output of the above println() statement would be 0 (Zero). The result is less than the minimum value (magnitude) hence it is treated as 0 (Zero).
Note: The result will be same if we substitute the type double with float and the result is less than the minimum float value.
1. Type Conversions in Expressions
Automatic type promotion takes place in arithmetic expressions according to the following rules:
- An operand of type byte, short or char is always converted to int. This is true even if unary operator is used. This implies that the type of the result will always be int or some higher type.
- If the higher type between two operands is long the other is converted to long.
- If the higher type between two operands is float the other is converted to float.
- If the higher type between two operands is double the other is converted to double.
- If both the operands are of same type (after byte, short or char has been promoted to int) then no conversion takes place.
Suppose following variables are declared in a method/block:
int i = 10; byte b= 3; short s = 16; char c = 65; long l = 100;
float f = 10.3f; double d = 4.88;
The following table demonstrates some expressions formed using above variables, their result type and the value calculated using the conversion rules defined above:
2. Integer Expressions
An Integer expression is one where all the operands are of integer type. The result of such an expression will always be integer as in case of C/C++. The fractional part is simply ignored. For example the result of expression 5/3 is 1.
While evaluating an integer expression, the following rules are applied:
1. An operand of type byte, short or char is converted to int before evaluation of the expression. This is true for unary as well as binary operators. So the operands will always be of type int or long.
2. While evaluating expressions the operators are applied according to precedence rules, which are same as in C/C++.
3. If both the operands of an operator are of type int then result will also be of type int.
4. If both the operands of an operator are of type long then result will also be of type long.
5. If one of the operands of an operator is of type int and the other is of type long then the int would be converted to long and the result will also be of type long.
Integer division including modulo (%) operator may result in an ArithmeticException (run time error).
Example: The following example illustrates what happens on division by zero.
class ZeroDivision
{
public static void main(String args[])
{
int i;
int x = 5;
i = x / 0; // x % 0 will also lead to exception.
int y = i + 3;
System.out.println(y);
}
}
On execution of the above program, the following exception (run time error) occurs at statement
i = x/0; and the program terminates:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at ZeroDivision.main(ZeroDivision.java:5)
The reason is that division by zero is not defined in Java when both the operands are integer. In Java, it is possible to recover from a run time error and continue the execution. This is done by using exception-handling mechanism that will be discussed later.
Overflow in Integer Expressions
Except division no other integer calculations result in any exception although the result might be arithmetically incorrect. On evaluation of an operator (or complex integer expression), the result may be outside the range of the result data type. Such a situation is called overflow. The actual result is obtained by truncating the extra bits in the result. For example, if the type of the result is
int and the result contains more than 32 bits, then 32 least significant bits in the result are kept and rest are simply truncated to obtain the result. Thus the result will not be correct and in some cases result may be of the wrong sign.
Example:
int tooBig = Integer.MAX_VALUE + 1;
MAX_VALUE is a static final constant defined in the class Integer. Its value represents the maximum positive value that can be stored in a variable of type int, which is, 2147483647. The result of the above expression will be of type int as both the operands are of type int. But the expression would lead to overflow as we are adding one to highest integer value.
In fact, on displaying value of variable tooBig, you will find that it holds the value -2147483648, which is the minimum value that an integer can hold. The only solution to the overflow problem is to use higher data type i.e. use long type if you expect the result to exceed the limit of the int.
3. Floating-Point Expressions
These are the expressions involving floating-point types. A floating-point expression may also have integer types i.e. a mix of integer and floating-point types. If a floating-point expression has an operator whose both the operands are integer then its result will be calculated as per integer arithmetic rules. For example the expression 3.1 + 5/3 is a floating-point expression but its result will be 4.1 (3.1 + 1) and not 4.76 (3.1 + 1.66) as one might expect because the result of the expression 5/3 would still be int.
While evaluating a floating-point expression, the following rules are applied:
- An operand of type byte, short or char type is converted to int before evaluation of the expression. This is true for unary as well as binary operators. So the integer operands will always be of type int or long.
- While evaluating expressions the operators are applied according to precedence rules, whichare same as in C/C++.
- If operands of an operator are of different types then the lower type operand will be promoted to the type of the higher type operand and the type of the result will be the higher type.
In case of float type these values are represented by constants Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY and Float.NaN respectively defined in the class Float.
Similarly in case of double type these values are represented by constants
Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY and Double.NaN respectively defined in the class Double.
No exception occurs on division by zero as this is defined in case of floating point expressions.
The result of division by zero is either Infinity or –Infinity. Similarly no error occurs if the floating-point expression involves non-determinant forms like 0/0, 0/, /, /0, complex numbers etc. The result of such an expression is NaN (Not a Number).
Examples:
The following code segments demonstrate the use of three special values.
(i) double d = 10.0/0;
System.out.println(d);
The output of the above println() statement would be Infinity.
(ii) double d = -10.0/0;
System.out.println(d);
The output of the above println() statement would be Infinity.
(iii) double d = 0.0/0;
System.out.println(d);
The output of the above println() statement would be NaN.
(iv) double d = Math.sqrt(-25);
System.out.println(d);
The output of the above println() statement would be NaN.
Note: The result will be same if we substitute the type double with float.
Overflow in Floating-Point Expressions
If the result of a floating-point expression exceeds the maximum value (magnitude) it is represented by +Infinity or –Infinity depending on the sign of the result.
Examples:
(i) double d = 1.0E+308 * 10;
System.out.println(d);
The output of the above println() statement would be Infinity. The result exceeds the
maximum value (magnitude) and its sign is positive hence it is represented as positive
Infinity.
(ii) double d = -1.0E+308 * 10;
System.out.println(d);
The output of the above println() statement would be Infinity. The result exceeds the maximum value (magnitude) and its sign is negative hence it is represented as negative Infinity.
Note: The result will be same if we substitute the type double with float and the result exceeds the maximum float value.
Underflow in Floating-Point Expressions
If the result of a floating-point expression is less than the minimum value (magnitude), it is represented by 0 (Zero).
Examples:
(i) double d = 3E-324 – 1.0E-324;
System.out.println(d);
The output of the above println() statement would be 0 (Zero). The result is less than the minimum value (magnitude) hence it is treated as 0 (Zero).
(ii) double d = -3E-324 – 1.5E-324;
System.out.println(d);
The output of the above println() statement would be 0 (Zero). The result is less than the minimum value (magnitude) hence it is treated as 0 (Zero).
Note: The result will be same if we substitute the type double with float and the result is less than the minimum float value.