Friday, 29 May 2015

Java Selection Statements (Decision Control Structure)

Java supports the following selection statements:

  • simple if Statement
  • if-else Statement
  • nested-if Statement
  • if-else-if Ladder
  • switch Statement

The syntax of these statements is same as in C/C++ so we will be discussing in details only if there is some difference from C/C++.

Simple if Statement

The syntax of the simple if statement is:

if (condition)
Statement;

if-else Statement

The syntax of the if-else statement is

if(condition)
   Statement1;
else
   Statement2;

Example: The following program illustrates the use of simple if statement as well as if-else statement. The program reads elements in an array of type int, followed by the element to be searched in the array using the linear search method. The program then displays the suitable message according to the search result.

import java.util.*;

class LinearSearch

{ public static void main(String args[]) throws IOException

{ int n, x, a[]; boolean found = false;

String number;

Buffered Reader in

System.out.print("Enter the number of elements in the array: ");

number = in.readLine();

n = Integer.parseInt(number);

a = new int[n];

for(int i = 0; i < n; i++) // read the array elements

{ number = in.readLine(); // enter only one element in one line

}

System.out.print("Enter the element to be searched in the array: ");

number = in.readLine();

x = Integer.parseInt(number);

for(int i = 0; i < n; i++) // search the specified element

{

}

if(found) // if-else statement

else

}

}

nested-if Statement

Any type of if statement may appear in the if or else part of another if statement. The rules for nesting are same as in C/C++. The following example illustrates the use of nested-if statement.

Example: The following program finds the largest among three given numbers.

import java.util.*;

class LargestOfThree

{ public static void main(String args[]) throws IOException

{ int a,b,c,max;  String number;

Buffered Reader in

System.out.print("Enter the first number : ");

number = in.readLine(); a = Integer.parseInt(number);

System.out.print("Enter the second number : ");

number = in.readLine(); b = Integer.parseInt(number);

System.out.print("Enter the third number : ");

number = in.readLine(); c = Integer.parseInt(number);

if(a > b)

else

System.out.println("Maximum among "+a+","+b+","+c+" is:"+max);

}

}

if-else-if Ladder

The syntax of the if-else-if ladder statement is as follows:

if(condition)
  Statement;
else if (condition)
  Statement;
else if (condition)
  Statement;
else
  Statement;

Example: The following program demonstrates the use of if-else-if ladder. The program reads

the weekday as an integer and displays corresponding weekday.

import java.util.*;

class DisplayWeekDay

{ public static void main(String args[]) throws IOException

{ int weekDay;

Buffered Reader in = new BufferedReader(new InputStreamReader(System.in));

System.out.print("Enter the day of week (1 to 7) : ");

number = in.readLine(); weekDay = Integer.parseInt(number);

if (weekDay == 1)

System.out.println("Sunday");

else if(weekDay == 2)

System.out.println("Monday");

else if(weekDay == 3)

System.out.println("Tuesday");

else if(weekDay == 4)

System.out.println("Wednesday");

else if(weekDay == 5)

System.out.println("Thursday");

else if(weekDay == 6)

System.out.println("Friday");

else if(weekDay == 7)

System.out.println("Saturday");

else

System.out.println("Valid values are from 1 to 7");

}

}

switch Statement

The switch statement is a multi-way branch statement. Its syntax is as follows:

switch(expression)

{ case label-1: Statement Sequence

case label-2 : Statement Sequence

[break;]

[break;]

case label-n: Statement Sequence

default: Statement Sequence

[break;]

[break;]

}

The syntax is same as in C/C++, with the following differences:

(i) In Java, switch expression can be any integer expression except long i.e. the type of the switch expression can be byte, short, char or int. But the Java’s int is of 4 bytes which is same as size of long in C/C++.

(ii) The case labels are constant expressions as in C/C++ but the values of the case labels must be in the range of the type of the switch expression otherwise the program will not compile. For example, if switch expression is of type byte then the valid values for case labels are from –128 to 127.

Example: The following program demonstrates the use of switch statement. The program reads the weekday as an integer and displays the corresponding weekday in character form.

import java.util.*;

class DisplayWeekDay1

{ public static void main(String args[]) throws IOException

{ int weekDay;

String number;

Buffered Reader in

= new BufferedReader(new InputStreamReader(System.in));

System.out.print("Enter the day of week (1 to 7) : ");

number = in.readLine();

weekDay = Integer.parseInt(number);

switch(weekDay)

{

case 1: System.out.println("Sunday");

case 2: System.out.println("Monday");

case 3: System.out.println("Tuesday");

case 4: System.out.println("Wednesday");

case 5: System.out.println("Thursday");

case 6: System.out.println("Friday");

break;

break;

break;

break;

break;

break;

case 7: System.out.println("Saturday");

break;

default:

System.out.println("Valid values are from 1 to 7");

}
}
}

Java Control Statements

Control statements are used to change the flow of execution. Java’s control statements can be classified into three categories:

  • Selection Statements (Decision Control Structure)
  • Iteration Statements (Loop Control Structure)
  • Jump statements

Most of the statements have same syntax as the corresponding statements in C/C++. However there are some significant differences:

(i) The conditional expressions used in the if, for, while and do statements must be valid boolean expressions i.e. their values should be either true or false. You cannot use 0 (Zero) instead of false or a non-zero value instead of true that is valid in C/C++.

(ii) Java does not have any goto statement although goto is a reserved word in the language. Java provides labeled break and labeled continue statements, which are often referred to as the civilized form of goto as they are supposed to be better substitutes of goto statement.

Thursday, 28 May 2015

Java Type Conversions during Assignments

Types of the left hand side variable and right hand side expression in an assignment may differ from each other as long as they are type-compatible with each other. For example all the primitive types excluding boolean are type-compatible with each other. When value of an expression is assigned to a variable, it should be converted to the type of the variable on the left hand side. The type conversion may take place automatically or we may have to convert the type explicitly using typecast operator.

Type conversions can be classified as:

  • Widening (or Broadening or UpCasting) Type Conversions
  • Narrowing (or DownCasting) Type Conversions
Widening Conversions

Widening conversion takes place when we assign a lower type expression to a higher type. There is no possibility of any data/precision loss in a widening conversion so it takes place implicitly/automatically.

Examples: The following examples will clarify this.

Suppose following variables are declared in a method/block:

int i ; byte b= 3; short s = 16; char c = 65; long l; float f; double d;

The following expressions are valid as widening conversion takes place automatically:

i  = b; l = s; f = b; d = c;

Narrowing Conversions


Narrowing conversion takes place when we assign a higher type expression to a lower type.

There is possibility of data/precision loss in a narrowing conversion. So normally a narrowing conversion does not take place implicitly/automatically. The programmer needs to explicitly typecast the higher type to lower type so that he/she is aware of the possibility of data/precision loss. However, there are some cases where even narrowing conversion takes place automatically.

Simple assignments always need explicit type conversion.

Examples: The following examples will clarify this.

Suppose following variables are declared in a method/block:

int i = 10 ; byte b; short s; char c; long l = 23; float f = 18.1f; double d = 5.77;

The following expressions are not valid, as narrowing conversions need explicit typecast:

b = i; s  = l; b = f; c = d;

To use these expressions you need to do explicit typecasting as follows:

b = (byte) i; s = (short) l; b = (byte) f; c = (char) d;

Java Arithmetic Expressions

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:

  • 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.
Examples: The following examples will clarify these 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:

  • 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.
There are three special floating-point values infinity, minus infinity and not a number to represent out-of-range values.

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.

Java Shift Operators

The Java supports the following bit-wise shift operators:

<< (left shift)

>> (right shift with sign fill)

>>> (right shift with zero fill)

Both the operands must be of integer type. The type promotion rule is applied to each operand before performing the shift operation. The type of the result is same as the promoted type of the left hand operand. This means that type of result will be either int or long.

The shift distance should be in the range 0 to 31 if the promoted type of the left hand operand is int. This means you can shift the bits to left or right by at the most 31 places.

If the shift distance is more than 31 then it will be converted to a value in the range 0 to 31 by obtaining mod with 32. So shifting by 32 is equivalent to shifting by 0 i.e. no shifting al all;

shifting by 33 is equivalent to shifting by 1, and so on.

If the shift distance is negative then actual shift distance is obtained by adding some multiple of 32 to the shift distance such that it falls in the range 0 to 31. For example, if shift distance is –30

then the actual shift distance will be 2 (-30 + 1*32); if the shift distance is –44 then the actual shift distance will be 20 (-44 + 2 * 32).

The shift distance should be in the range 0 to 63 if the promoted type of the left hand operand is long. This means you can shift the bits to left or right by at the most 63 places. If the shift distance is more than 63 then it will be converted to a value in the range 0 to 63 by obtaining mod with 64. So shifting by 64 is equivalent to shifting by 0 i.e. no shifting at all; shifting by 65 is equivalent to shifting by 1, and so on.

If the shift distance is negative then actual shift distance is obtained by adding some multiple of 64 to the shift distance such that it falls in the range 0 to 63. For example, if shift distance is –60

then the actual shift distance will be 4 (-60 + 1*64); if the shift distance is –88 then the actual shift distance will be 40 (-88 + 2 * 64).

Left Shift (<<) Operator

To obtain the result of << operator, the bits in the left hand side operand (which can be any integer expression) are shifted to the left as specified by the right hand operand (which can also be any integer expression) and the empty bit positions to the right are filled with zero.  Left shifting by 1 is equivalent to multiplication by 2. It is possible that sign of the result may differ from the sign of the left hand side operand. This may happen because the sign depends on the
left-most bit, which can change from 0 to 1 or 1 to 0 hence the change in sign.

Example:

y = x << 4

To obtain the value of y, shift the bits in x by 4 positions to the left and fill the 4 right bits with zero.

Right Shift with sign fill (>>) Operator

To obtain the result of >> operator, the bits in the left hand side operand (which can be any integer expression) are shifted to the right as specified by the right hand operand (which can also be any integer expression) and the empty bit positions to the left are filled with sign bit. Right shifting by 1 is equivalent to division 2. This operator never changes the sign of the result i.e. it will be same as the sign of the left hand operand.

Example:

y = x >> 4

To obtain the value of y, shift the bits in x by 4 positions to the right and fill the 4 left bits with sign bit (i.e. with 0 if the leftmost bit before shifting is 0 or 1 if the leftmost bit before shifting is 1).

Right Shift with zero fill (>>>) Operator

To obtain the result of >>> operator, the bits in the left hand side operand (which can be any integer expression) are shifted to the right as specified by the right hand operand (which can also be any integer expression) and the empty bit positions to the left are filled with 0.  Right shifting by 1 is equivalent to division 2. If shifting tales place then result will always be positive, as the rightmost bit would become zero.

Example:

y = x >>> 4

To obtain the value of y, shift the bits in x by 4 positions to the right and fill the 4 left bits with 0.