Module 2 Notes Review Questions (4)
Module 2 Notes Review Questions (4)
MODULE 2
Syllabus: Operators: Arithmetic Operators, The Bitwise Operators, Relational Operators, Boolean Logical
Operators, The Assignment Operator, The ? Operator, Operator Precedence, Using Parentheses.
Control Statements: Java’s Selection Statements, Iteration Statements, Jump Statements.
Operators
Java provides rich set of operators, mainly divided into four groups viz. arithmetic, bitwise, relational and
logical. These operators are discussed here.
Operator Meaning
+ Addition
- Subtraction
* Multiplication
/ Division
% Modulus
++ Increment
-- Decrement
+= Addition assignment
-= Subtraction assignment
*= Multiplication assignment
/= Division assignment
%= Modulus assignment
The operands of the arithmetic operators must be of a numeric type. You cannot use them on boolean
types, but you can use them on char types, since the char type in Java is a subset of int.
1
Module 2:Operators
NOTE that in C/C++, the % operator cannot be used on float or double and should be used only on
integer variable.
Operator Meaning
~ Bitwise unary NOT
& Bitwise AND
| Bitwise OR
^ Bitwise exclusive OR
>> Shift right
>>> Shift right zero fill
<< Shift left
&= Bitwise AND assignment
|= Bitwise OR assignment
^= Bitwise exclusive OR assignment
>>= Shift right assignment
>>>= Shift right zero fill assignment
<<= Shift left assignment
Since bitwise operators manipulate the bits within the integer, let us first understand the bit- representation
of integer data in Java.
All of the integer types are represented by binary numbers of varying bit widths. For example, the byte
value for 42 in binary is 00101010, where each position represents a power of two, starting with 2 0 at the
rightmost bit. All of the integer types are signed integers. Java uses an encoding known as two’s
complement, which means that negative numbers are represented by inverting (changing 1’s to 0’s and
vice versa) all of the bits in a value, then adding 1 to the result. For example, –42 is represented by
inverting all of the bits in 42, or 00101010, which yields 11010101, then adding 1, which results in
11010110, or –42. To decode a negative number, first invert all of the bits, and then add 1. For example, –
42, or 11010110 inverted, yields 00101001, or 41, so when you add 1 you get 42.
2
.
Bitwise NOT
A unary NOT operator ~, also called as bitwise complement inverts all the bits of the operand. For
example, the number 42, which has the following bit pattern: 00101010 becomes 11010101 after the NOT
operator is applied.
Bitwise AND
As the name suggests, initially, operands are converted into binary-format. Then, the AND (&) operation
is performed on the corresponding bits of operands. Consider an example –
Bitwise OR
Here, the OR (|) operations is performed on individual bit of operands. For example –
x 0000 0101
y | 0000 0110
z 0000 0111
Bitwise XOR
In XOR operation, if both bits are same (either both are 1 or both 0), then the resulting bit will be 0 (false).
Otherwise, the resulting bit is 1 (true). For example –
Left Shift
The left shift operator, <<, shifts all of the bits in a value to the left by a specified number of times. It has
this general form:
value << num
For each shift, one higher order bit is shifted out (or lost) and extra zero is appended as the lower order bit.
Thus, for int, after 31 shifts, all the bits will be lost and result will be 0, whereas for long, after 63 shifts,
all bits will be lost.
Java’s automatic type promotions produce unexpected results when you are shifting byte and short
values. As you know, byte and short values are promoted to int when an expression is evaluated.
Furthermore, the result of such an expression is also an int. This means that the outcome of a left shift on
a byte or short value will be an int, and the bits shifted left will not be lost until they shifted for 31 times.
To avoid this problem, we should use type-casting as shown in the following example.
Since a is promoted to int for evaluation, left-shifting the value 64 (0100 0000) twice results in i
containing the value 256 (1 0000 0000). However, the value in b contains 0 because after the shift, the
low-order byte is now zero.
Each left shift can be thought of as multiplying the number by 2. But, one should be careful because once
the number crosses its range during left shift, it will become negative. Consider an illustration –
.
Example Program
class ShiftDemo1{
public static void main(String args[])
{
int i;
int num = 0xFFFFFFE;
for(i=0; i<4; i++)
{
num = num << 1;
System.out.println(num);
}
}
}
class MultByTwo {
public static void main(String args[]) {
int i;
int num = 00001010
for(i=0; i<2; i++)
{
num = num << 1;
System.out.println(num);
}
}
}
Output:00010100
00101000
Right Shift
The right shift operator, >> shifts all of the bits in a value to the right by a specified number of times. It
has this general form:
value >> num
For each shift, one lower order bit is shifted out (or lost) and extra zero is appended as the higher order
bit. For example,
int a = 35; //00100011 is the binary equivalent
a = a >> 2; // now, a contains 8
Each right shift can be thought of as dividing the number by 2. When you are shifting right, the top
(leftmost) bit is filled with the previous content of the top bit. This is called sign extension and is needed
to preserve the sign of negative numbers when you shift them right. For example, –8 >> 1 is –4, which, in
binary, is
.
11111000 (–8)
>>1
11111100 (–4)
class MultByTwo {
public static void main(String args[]) {
int i;
int num = 00001010
for(i=0; i<2; i++)
{
num = num >> 1;
System.out.println(num);
}
}
}
Output:00000101
00000010
Difference between >> and >>> operator. Both >> and >>> are used to shift the bits towards the right. The
difference is that the >> preserve the sign bit while the operator >>> does not preserve the sign bit. To
preserve the sign bit, you need to add 0 in the MSB.
//This program Illustrates the difference between >> and >>> operator.
class OperatorShifting
{
public static void main(String args[])
{
byte x, y;
x=10;
.
y=-10;
System.out.println("Bitwise Left Shift: x<<2 = "+(x<<2));
System.out.println("Bitwise Right Shift: x>>2 = "+(x>>2));
System.out.println("Bitwise Zero Fill Right Shift: x>>>2 = "+(x>>>2));
System.out.println("Bitwise Zero Fill Right Shift: y>>>2 = "+(y>>>2));
}
}
Output:
Bitwise Left Shift: x<<2 = 40
Bitwise Right Shift: x>>2 = 2
Bitwise Zero Fill Right Shift: x>>>2 = 2
Bitwise Zero Fill Right Shift: y>>>2 = 1073741821
Operator Meaning
== Equal to (or comparison)
!= Not equal to
> Greater than
< Less than
>= Greater than or equal to
<= Less than or equal to
The outcome of these operations is a boolean value. Any type in Java, including integers, floating-point
numbers, characters, and Booleans can be compared using the equality test, ==, and the inequality test,
!=. Only numeric types can be compared using the ordering operators. That is, only integer, floating-
point, and character operands may be compared to see which is greater or less than the other. For example,
the following code fragment is perfectly valid:
int a = 4;
int b = 1;
boolean c = a < b;
In this case, the result of a<b (which is false) is stored in c.
Operator Meaning
& Logical AND
| Logical OR
^ Logical XOR (exclusive OR)
|| Short-circuit OR
2.5 Boolean Logical Operators
The Boolean logical operators shown here operate only on boolean operands. All of the binary logical
operators combine two boolean values to form a resultant boolean value.
Operator Meaning
& Logical AND
| Logical OR
^ Logical XOR (exclusive OR)
|| Short-circuit OR
& Short-circuit AND
! Logical unary NOT
&= AND assignment
|= OR assignment
^= XOR assignment
== Equal to
!= Not equal to
?: Ternary if-then-else
The truth table is given below for few operations:
Note: In C/C++, the logical AND/OR operations never evaluates the second operand if the value of first
operand itself can judge the result. That is, if the first operand is false, then second operand is not
evaluated in AND operation and result will be false. Similarly, if the first operand is true in OR operation,
without evaluating the second operand, it results true. But in Java, Boolean logical operators will not act
so. Even if the first operand is decisive, the second operand is evaluated. This can be observed in the
above program while evaluating h= b& (a= !a). Here, b is false and hence ANDed with anything results
false. But, still the second operand (a= !a) is evaluated resulting a as false.
If we don’t want the second operand to be evaluated, we can use short-circuit logical operators.
Here, the first operand x!= 0 is false. If we use logical AND (&) then the second operand n/x>0 will be
evaluated and we will get DivisionByZero Exception. So, to avoid this problem we use && operator
which will never evaluated second operand if the first operand results into false.
It is standard practice to use the short-circuit forms of AND and OR in cases involving Boolean logic,
leaving the single-character versions exclusively for bitwise operations. However, there are exceptions to
this rule. For example, consider the following statement:
if(c==1 & e++ < 100)
d = 100;
Here, using a single & ensures that the increment operation will be applied to e whether c is equal to 1 or
not.
Example Programs:
class ShortCircuitAnd
{
public static void main(String arg[])
{
int c = 0, d = 100, e = 50;
if( c == 1 && e++ < 100 )
{
d = 150;
}
System.out.println("e = " + e );
}
}
output:
e = 50
This fragment sets the variables x, y, and z to 100 using a single statement. This works because the = is an
operator that yields the value of the right-hand expression. Thus, the value of z = 100 is 100, which is
then assigned to y, which in turn is assigned to x. Using a “chain of assignment” is an easy way to set a
.
group of variables to a common value.
Here, expression1 is evaluated first and it must return Boolean type. If it results true, then value of
expression2 is assigned to var, otherwise value of expression3 is assigned to var. For example,
int a, b, c ;
……….
c= (a>b)?a:b; //c will be assigned with biggest among a and b
Example program:
Write a program to find biggest among three numbers using ternary operator.
import java.util.Scanner;
public class Largest_Ternary
Highest (), [ ], .
++, --, ~, !
*, /, %
+, -
>>, >>>, <<
>, >=, <, <=
==, !=
&
^
|
&&
||
?:
=, op=
Lowest
a= b – c * d;
Here, c and d are multiplied first and then the result is subtracted from b. If we want subtraction first, we
should use parenthesis like
a= (b-c)*d;
Sometimes, parenthesis is useful for clarifying the meaning of an expression and for making readers to
understand the code. For example,
a | 4 + c >> b & 7 can be written as (a | (((4 + c) >> b) & 7))
In such situations, though parenthesis seems to be redundant, it existence will not reduce the
performance of the program.
If the condition is true, then the statements written within true block will be executed, otherwise false
block will be executed. The condition should result into Boolean type. For example,
int a, b, max;
…………
if(a>b)
max=a;
else
max=b;
class IfElseExample {
public static void main(String[] args)
{
//defining a variable
int number=13;
//Check if the number is divisible by 2 or not
if(number%2==0)
{
System.out.println("even number");
}
else
{
System.out.println("odd number");
}
}
}
Output:
odd number
Nested-if Statement
General form of nested if
If( condition1)
{
If(condition 2)
Statement ;
if (condition 3)
Statement.;
……
……….
else
statement ;
}
else
Statement ;
if(a==10){
if(b!=20){
System.out.println("if is executed");
}
else{
System.out.println(" else is executed");
}
}
}
}
Output:
else is executed
The if statements are executed from the top down. As soon as one of the conditions controlling the if is
true, the block associated with that if is executed, and the rest of the ladder is bypassed. The final else acts
as a default condition; that is, if all other conditional tests fail, then the last else statement is performed.
Example Program:
class elseif {
public static void main(String[] args)
{
// initializing expression
.
int i = 20;
// condition 1
if (i == 10)
System.out.println("i is 10\n");
// condition 2
else if (i == 15)
System.out.println("i is 15\n");
// condition 3
else if (i == 20)
System.out.println("i is 20\n");
else
System.out.println("i is not present\n");
System.out.println("Outside if-else-if");
}
}
Output:
i is 20
Outside if-else-if
switch Statement
The switch statement is Java’s multi-way branch statement. It provides an easy way to dispatch execution
to different parts of your code based on the value of an expression. As such, it often provides a better
alternative than a large series of if-else-if statements. Here is the general form of a switch statement:
switch (expression)
{
case value1:
// statement sequence break;
case value2:
// statement sequence break;
…………....
case valueN:
// statement sequence break;
default:
// default statement sequence
}
The expression must be of type byte, short, int, or char; each of the values specified in the case
statements must be of a type compatible with the expression. The switch statement works like this: The
.
value of the expression is compared with each of the literal values in the case statements. If a match is
found, the code sequence following that case statement is executed. If none of the constants matches the
value of the expression, then the default statement is executed. However, the default statement is
optional. If no case matches and no default is present, then no further action is taken. The break
statement is used inside the switch to terminate a statement sequence. When a break statement is
encountered, execution branches to the first line of code that follows the entire switch statement. This has
the effect of “jumping out” of the switch. The break statement is optional. If you omit the break,
execution will continue on into the next case.
Example program for switch statement
Output:
i is zero.
i is one.
i is two.
i is three.
i is greater than 3.
i is greater than 3.
Note:We can even nest switch statements one within the other.
The switch differs from the if in that switch can only test for equality, whereas if can evaluate
any type of Boolean expression. That is, the switch looks only for a match between the value of
the expression and one of its case constants.
No two case constants in the same switch can have identical values. Of course, a switch
statement and an enclosing outer switch can have case constants in common.
A switch statement is usually more efficient than a set of nested ifs.
The last point is particularly interesting because it gives insight into how the Java compiler works. When it
compiles a switch statement, the Java compiler will inspect each of the case constants and create a “jump
table” that it will use for selecting the path of execution depending on the value of the expression.
Therefore, if you need to select among a large group of values, a switch statement will run much faster
than the equivalent logic coded using a sequence of if-elses. The compiler can do this because it knows
that the case constants are all the same type and simply must be compared for equality with the switch
expression. The compiler has no such knowledge of a long list of if expressions.
while Loop
The general form is –
while(condition)
{
//body of the loop
}
.
The condition can be any Boolean expression. The body of the loop will be executed as long as the
conditional expression is true. When condition becomes false, control passes to the next line of code
immediately following the loop.
Example Program:
public class WhileExample {
public static void main(String[] args) {
int i=1;
while(i<=10)
{
System.out.println(i);
i++;
}
}
}
Output:
1
2
3
4
5
6
7
8
9
10
Each iteration of the do-while loop first executes the body of the loop and then evaluates the conditional
expression. If this expression is true, the loop will repeat. Otherwise, the loop terminates. As with all of
Java’s loops, condition must be a Boolean expression.
Output:
1
2
3
4
5
6
7
8
9
10
While do while
The controlling condition here appears at the The controlling condition is present at the end of the
beginning of the loop. loop.
There is no condition at the end of the loop There is a condition at the end of the loop
It doesn’t need to execute at least one. The code is executed at least once.(if condition is
false).
.
for Loop
The general form is –
for(initialization; condition; updation)
{
// body of loop
}
When the loop first starts, the initialization portion of the loop is executed. Generally, this is an expression
that sets the value of the loop control variable, which acts as a counter that controls the loop. It is important
to understand that the initialization expression is only executed once. Next, condition is evaluated. This must
be a Boolean expression. It usually tests the loop control variable against a target value. If this expression is
true, then the body of the loop is executed. If it is false, the loop terminates. Next, the updation portion of the
loop is executed. This is usually an expression that increments or decrements the loop control variable. The
loop then iterates, first evaluating the conditional expression, then executing the body of the loop, and then
executing the iteration expression with each pass. This process repeats until the controlling expression is
false.
class Main {
public static void main(String[] args) {
int sum = 0;
int n = 10;
// for loop
for (int i = 1; i <= n; ++i)
{
// body inside for loop
sum += i; // sum = sum + i
}
Output:
Sum=55
for-each Loop
The for-each style of for is also referred to as the enhanced for loop. The general form of the for-each
version of the for is shown here:
for(type itr-var : collection) statement-
block
Here, type specifies the type and itr-var specifies the name of an iteration variable that will receive the
.
elements from a collection, one at a time, from beginning to end. The collection being cycled through is
specified by collection. There are various types of collections that can be used with the for, but the only
type used in this chapter is the array. With each iteration of the loop, the next element in the collection is
retrieved and stored in itr-var. The loop repeats until all elements in the collection have been obtained.
Because the iteration variable receives values from the collection, type must be the same as (or compatible
with) the elements stored in the collection. Thus, when iterating over arrays, type must be compatible with
the base type of the array.
Consider an example –
int nums[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int sum = 0;
for(int i=0; i < 10; i++) sum +=
nums[i];
With each pass through the loop, x is automatically given a value equal to the next element in nums.
Thus, on the first iteration, x contains 1; on the second iteration, x contains 2; and so on. Not only is the
syntax streamlined, but it also prevents boundary errors.
The for-each version of for has several applications viz. Finding average of numbers, finding minimum
and maximum of a set, checking for duplicate entry in an array, searching for an element in unsorted list
etc. The following program illustrates the sequential (linear) search.
for(int x : nums)
{
if(x == val)
{
found = true; break;
}
}
if(found)
System.out.println("Value found!");
}
}
Using break
In java, break can be used in 3 different situations:
To terminate statement sequence in switch
To exit from a loop
Can be used as a civilized version of goto
.
The above code snippet prints values from 0 to 4 and when i become 5, the loop is terminated.
first:
{
second:
{
third:
{
System.out.println("Before the break.");
if(t)
break second; // break out of second block
System.out.println("This won't execute");
}
System.out.println("This won't execute");
}
System.out.println("This is after second block.");
}
}
}
As we can see in the above program, the usage of break with a label takes the control out of the second block
directly.
Using continue
Sometimes, we may need to proceed towards next iteration in the loop by leaving some statements. In
such situations, we can use continue statement within for, while and do-while. For example –
// Demonstrate continue.
class Continue {
public static void main(String args[]) {
for(int i=0; i i<10; i++)
{
System.out.print(i + " ");
if (i%2 == 0)
continue;
System.out.println(" ");
.
}
}
}
Output:
01
23
45
67
89
This code uses the % operator to check if i is even. If it is, the loop continues without printing a newline.
Using return
The return statement is used to explicitly return the method. At any time in a method the return statement
can be used to cause execution to branch back to the caller of the method. Thus, the return statement
immediately terminates the method in which it is executed. Based on some condition, we may need to go
back to the calling method sometimes. So, we can use return in such situations.
// Demonstrate return.
class Return {
public static void main(String args[]) {
boolean t = true;
System.out.println("Before the return.");
if(t) return; // return to caller
System.out.println("This won't execute.");
}
}
Output:
Before the return.
QUESTION BANK:
1. What are different types of operators in Java? Explain any two of them.
2. Discuss ternary operator with examples.
3. Differentiate >> and >>> with suitable examples.
4. Briefly explain short-circuit logical operators with examples.
5. Explain different types of iteration statements with examples.
6. Discuss various selective control structures.
7. Write a note on jump statements in Java.
8. Discuss different versions of for - loop with examples.
9. Write a program to illustrate break statement with labels.