Subscribe

RSS Feed (xml)

Showing posts with label Operators. Show all posts
Showing posts with label Operators. Show all posts

Short-Circuit Logical Operators in C#

C# supplies special short-circuit versions of its AND and OR logical operators that can be used to produce more efficient code. To understand why, consider the following: In an AND operation, if the first operand is false, the outcome is false no matter what value the second operand has. In an OR operation, if the first operand is true, the outcome of the operation is true no matter what the value of the second operand. Thus, in these two cases there is no need to evaluate the second operand. By not evaluating the second operand, time is saved and more efficient code is produced.
The short-circuit AND operator is && and the short-circuit OR operator is | |. As described earlier, their normal counterparts are & and |. The only difference between the normal and short-circuit versions is that the normal operands will always evaluate each operand, but short-circuit versions will evaluate the second operand only when necessary.
Here is a program that demonstrates the short-circuit AND operator. The program determines if the value in d is a factor of n. It does this by performing a modulus operation. If the remainder of n / d is zero, then d is a factor. However, since the modulus operation involves a division, the short-circuit form of the AND is used to prevent a divide-by-zero error.
// Demonstrate the short-circuit operators,

using System;

class SCops {
  public static void Main() {
    int n, d;
    
    n = 10;
    d = 2;
    if(d != 0 && (n % d) == 0)
      Console.WriteLine(d + " is a factor of " + n);
      
    d = 0; // now, set d to zero
    
    // Since d is zero, the second operand is not evaluated,
    if(d != 0 && (n % d) == 0)
      Console.WriteLine(d + " is a factor of " + n);
      
    /* Now, try the same thing without short-circuit operator.
       This will cause a divide-by-zero error. */
    if(d != 0 & (n % d) == 0)
      Console.WriteLine(d + " is a factor of " + n);
  }
} 
To prevent a divide-by-zero error, the if statement first checks to see if d is equal to zero. If it is, the short-circuit AND stops at that point and does not perform the modulus division. Thus, in the first test, d is 2 and the modulus operation is performed. The second test fails because d is set to zero, and the modulus operation is skipped, avoiding a divide-by-zero error. Finally, the normal AND operator is tried. This causes both operands to be evaluated, which leads to a runtime error when the division-by-zero occurs.
Since the short-circuit operators are, in some cases, more efficient than their normal counterparts, you might be wondering why C# still offers the normal AND and OR operators. The answer is that in some cases you will want both operands of an AND or OR operation to be evaluated because of the side effects produced. Consider the following:
// Side effects can be important,

using System;

class SideEffects {
  public static void Main() {
    int i;
    bool someCondition = false;

    i = 0;

    /* Here, i is still incremented even though
       the if statement fails. */
    if(someCondition & (++i < 100))
       Console.WriteLine("this won't be displayed");
    Console.WriteLine("if statement executed: " + i); // displays 1

    /* In this case, i is not incremented because
       the short-circuit operator skips the increment. */
    if(someCondition && (++i < 100))
      Console.WriteLine("this won't be displayed");
    Console.WriteLine("if statement executed: " + i); // still 1 !!
  }
}
First, notice that the bool variable someCondition is initialized to false. Next, examine each if statement. As the comments indicate, in the first if statement, i is incremented despite the fact that someCondition is false. When the & is used, as it is in the first if, the expression on the right side of the & is evaluated no matter what value the expression on the left has. However, in the second if statement, the short-circuit operator is used. In this case, the variable i is not incremented because the left operand, someCondition, is false, which causes the expression on the right to be skipped. The lesson here is that if your code expects the right-hand operand of an AND or OR operation to be evaluated, then you must use C#'s non-short-circuit forms of these operations.

Relational and Logical Operators in C#

In the terms relational operator and logical operator, relational refers to the relationships that values can have with one another, and logical refers to the ways in which true and false values can be connected together. Since the relational operators produce true or false results, they often work with the logical operators. For this reason they will be discussed together here.
The relational operators are as follows:
Operator
Meaning
= =
Equal to
!=
Not equal to
>
Greater than
<
Less than
>=
Greater than or equal to
<=
Less than or equal to
The logical operators are shown next:
Operator
Meaning
&
AND
|
OR
^
XOR (exclusive OR)
||
Short-circuit OR
&&
Short-circuit AND
!
NOT
The outcome of the relational and logical operators is a bool value.
In C#, all objects can be compared for equality or inequality using = = and !=. However, the comparison operators, <, >, <=, or >=, can be applied only to those types that support an ordering relationship. Therefore, all of the relational operators can be applied to all numeric types. However, values of type bool can only be compared for equality or inequality, since the true and false values are not ordered. For example, true > false has no meaning in C#.
For the logical operators, the operands must be of type bool, and the result of a logical operation is of type bool. The logical operators, &, |, ^, and !, support the basic logical operations AND, OR, XOR, and NOT, according to the following truth table:
p
q
p&q
p|q
p^q
!p
False
False
False
False
False
True
True
False
False
True
True
False
False
True
False
True
True
True
True
True
True
True
False
False
As the table shows, the outcome of an exclusive OR operation is true when exactly one and only one operand is true.
Here is a program that demonstrates several of the relational and logical operators:
// Demonstrate the relational and logical operators,

using System;

class RelLogOps {
  public static void Main() {
    int i, j;
    bool b1, b2;

    i = 10;
    j = 11;
    if(i < j) Console.WriteLine("i < j");
    if(i <= j) Console.WriteLine("i <= j");
    if(i != j) Console.WriteLine("i != j");
    if(i == j) Console.WriteLine("this won't execute");
    if(i >= j) Console.WriteLine("this won't execute");
    if(i > j) Console.WriteLine("this won't execute");

    b1 = true;
    b2 = false;
    if(b1 & b2) Console.WriteLine("this won't execute");
    if(!(b1 & b2)) Console.WriteLine("!(b1 & b2) is true");
    if(b1 b2) Console.WriteLine("b1 | b2 is true");
    if(b1 ^ b2) Console.WriteLine("b1 ^ b2 is true");
  } 
}
The output from the program is shown here:
i < j
i <= j
i != j
! (b1 & b2) is true
b1 | b2 is true
b1 ^ b2 is true   
The logical operators provided by C# perform the most commonly used logical operations. However, there are several other operations defined by the rules for formal logic. These other logical operations can be constructed using the logical operators supported by C#. Thus, C# supplies a set of logical operators sufficient to construct any other logical operation. For example, another logical operation is implication. Implication is a binary operation in which the outcome is false only when the left operand is true and the right operand is false. (The implication operation reflects the idea that true cannot imply false.) Thus, the truth table for the implication operator is shown here:
p
q
p implies q
True
True
True
True
False
False
False
False
True
False
True
True
The implication operation can be constructed using a combination of the ! and the I operator, as shown here:
!p | q
The following program demonstrates this implementation:
// Create an implication operator in C#.

using System;

class Implication {
  public static void Main() {
    bool p=false, q=false;
    int i, j;

    for(i =0; i < 2; i++) {
      for(j = 0; j < 2; j++) {
        if (i==0) p = true;
        if (i==1) p = false;
        if (j==0) q = true;
        if (j==1) q = false;

        Console .WriteLine ("p is " + p + '' q is " + q);
        if(!p | q) Console.WriteLine(p + implies " + q +
                    " is " + true);
        Console.WriteLine();
      }
    }
  }
}

The output is shown here:
p is True, q is True
True implies True is True

p is True, q is False

p is False, q is True
False implies True is True

p is False, q is False
False implies False is True

Arithmetic Operators in C#

C# defines the following arithmetic operators:
Operator
Meaning
+
; Addition
Subtraction (also unary minus)
*
Multiplication
/
Division
%
Modulus
++
Increment
−−
Decrement
The operators +, −, *, and / all work the same way in C# as they do in any other computer language (or in algebra, for that matter). These can be applied to any built-in numeric data type.
Although the actions of arithmetic operators are well known to all readers, a few special situations warrant some explanation. First, remember that when / is applied to an integer, any remainder will be truncated; for example, 10/3 will equal 3 in integer division. You can obtain the remainder of this division by using the modulus operator, %. The % is also referred to as the remainder operator. It yields the remainder of an integer division. For example, 10 % 3 is 1. In C#, the % can be applied to both integer and floating-point types.
Thus, 10.0 % 3.0 is also 1. (This differs from C/C++, which allow modulus operations only on integer types.) The following program demonstrates the modulus operator:
// Demonstrate the % operator,

using System;

class ModDemo {
  public static void Main() {
    int iresult, irem;
    double dresult, drem;

    iresult = 10 / 3;
    irem = 10 % 3;

    dresult = 10.0 / 3.0;
    drem = 10.0 % 3.0;

    Console.WriteLine("Result and remainder of 10 / 3: " +
                       iresult + " " + irem);
    Console.WriteLine("Result and remainder of 10.0 / 3.0: " +
                       dresult + " " + drem);
  }
}
The output from the program is shown here:
Result and remainder of 10 / 3: 3 1
Result and remainder of 10.0 / 3.0: 3.33333333333333 1
As you can see, the % yields a remainder of 1 for both integer and floating-point operations.

Increment and Decrement

The ++ and the −− are the increment and decrement operators. As you will see, they have some special properties that make them quite interesting. Let’s begin by reviewing precisely what the increment and decrement operators do.
The increment operator adds 1 to its operand, and the decrement operator subtracts 1. Therefore,
x = x + 1;
is the same as
x++;
and
x = x − 1;
is the same as
x−−;   
Both the increment and decrement operators can either precede (prefix) or follow (postfix) the operand. For example:
x = x + 1;
can be written as
++x; // prefix form
or as
x++; // postfix form
In the foregoing example, there is no difference whether the increment is applied as a prefix or a postfix. However, when an increment or decrement is used as part of a larger expression, there is an important difference. When an increment or decrement operator precedes its operand, C# will perform the operation prior to obtaining the operand’s value for use by the rest of the expression. If the opera tor follows its operand, then C# will obtain the operand's value before incrementing or decrementing it. Consider the following:
x = 10;
y = ++x;
In this case, y will be set to 11. However, if the code is written as
x = 10;
y = x++;
then y will be set to 10. In both cases, x is still set to 11; the difference is when it happens.
There are significant advantages in being able to control when the increment or decrement operation takes place. Consider the following program, which generates a series of numbers:
/*
   Demonstrate the difference between prefix
   postfix forms of ++.
*/
using System;

class PrePostDemo {
  public static void Main() {
    int x, y;
    int i;

    x = 1;
    Console.WriteLine("Series generated using y = x + x++;");
    for(i = 0; i < 10; i++) {

      y = x + x++; // postfix ++

      Console.WriteLine(y + " ");
    }
    Console.WriteLine();
    x = 1;
    Console.WriteLine("Series generated using y = x + ++x;");
    for(i = 0; i < 10; i++) {

      y = x + ++x; // prefix ++

      Console.WriteLine(y + " ");
    }
    Console.WriteLine();

  }
}
The output is shown here:
Series generated using y = x + x++;
2
4
6
8
10
12
14
16
18
20

Series generated using y = x + ++x;
3
5
7
9
11
13
15
17
19
21
As the output confirms, the statement
y = x + x++;
adds the value of x to x and assigns that result to y. It then increments x. However, the statement
y = x + ++x;
obtains the value of x, then increments x, and then adds that value to the original value of x. The result is assigned to y. As the output shows, simply changing x++ to ++x changes the number series from even to odd.
One other point about the preceding example: Don't let expressions like
x + ++x
intimidate you. Although having two operators back-to-back is a bit unsettling at first glance, the compiler keeps it all straight. Just remember, this expression simply adds the value of x to the value of x incremented.

LocalsAdda.com-Variety In Web World

Fun Mail - Fun in the Mail