Binary Operators
Binary operators are those operators that work with two operands. For example, a common binary expression would be a + b—the addition operator (+) surrounded by two operands. The binary operators are further subdivided into arithmetic, relational, logical, and assignment operators.
Arithmetic Operators
This is the first group of binary operators, those supporting arithmetic expressions. Arithmetic expressions are composed of two expressions with an arithmetic operator between them. This includes all the typical mathematical operators as expected in algebra.
The Multiplication Operator
The multiplication operator (*) evaluates two expressions and returns their product. Here's an example:
int expr1 = 3; int expr2 = 7; int product; product = expr1 * expr2; // product = 21
The Division Operator
The division operator (/), as its name indicates, performs mathematical division. It takes a dividend expression and divides it by a divisor expression to produce a quotient. Here's an example:
int dividend = 45; int divisor = 5; int quotient; quotient = dividend / divisor; // quotient = 9
Notice the use of integers in this expression. Had the result been a fractional number, it would have been truncated to produce the integer result.
The Remainder Operator
The remainder operator (%) returns the remainder of a division operation between a dividend and divisor. A common use of this operator is to create equations that produce a remainder that falls within a specified range. Here's an example:
int dividend = 33; int divisor = 10; int remainder; remainder = dividend % divisor; // remainder = 3
No matter what, as long as the divisor stays at 10, the remainder will always be between 0 and 9.
The Addition Operator
The addition operator (+) performs standard mathematical addition by adding one number to another. Here's an example:
int one = 1; int two; two = one + one; // two = 2
The Subtraction Operator
The subtraction operator (-) performs standard mathematical subtraction by subtracting the value of one expression from another. Here's an example:
decimal debt = 537.50m; decimal payment = 250.00m; decimal balance; balance = debt - payment; // balance = 287.50
The Left Shift Operator
To shift the bits of a number to the left, use the left shift operator (<<). The effect of this operation is that all bits move to the left a specified number of times. High-order bits are lost. Lower order bits are zero filled. This operator may be used on the int, uint, long, and ulong data types. Here's an example.
uint intMax = 4294967295; // 11111111111111111111111111111111b uint byteMask; byteMask = intMax << 8; // 11111111111111111111111100000000b
The Right Shift Operator
The right shift operator (>>) shifts the bits of a number to the right. By providing a number to operate on and the number of digits, every bit shifts to the right by the number of digits specified. Only use the right shift operator on int, uint, long, and ulong data types. The uint, ulong, positive int, and positive long types shift zeros from the left. The negative int and negative long types keep a 1 in the sign bit position and fill the next position to the right with a 0. Here are some examples:
uint intMax = 4294967295; // 11111111111111111111111111111111b uint shortMask; shortMask = intMax >> 16; // 00000000000000001111111111111111b int intMax = -1; // 11111111111111111111111111111111b int shortMask; shortMask = intMax >> 16; // 10000000000000001111111111111111b
For Java Programmers
C# doesn't have a right shift with zero extension operator (>>>).
Relational Operators
Relational operators are used to make a comparison between two expressions. The primary difference between relational operators and arithmetic operators is that relational operators return a bool type rather than a number. Another difference is that arithmetic operators are applicable to certain C# types whereas relational operators can be used on every possible C# type, whether built-in or not. Floating-point types are evaluated according to IEEE 754. The results of a relational expression are either true or false.
The Equal Operator
To see if two expressions are the same, use the equal operator (==). The equal operator works the same for integral, floating-point, decimal, and enum types. It simply compares the two expressions and returns a bool result. Here's an example:
bool bresult; decimal debit = 1500.00m; decimal credit = 1395.50m; bresult = debit == credit; // bresult = false
When comparing floating-point types, +0.0 and -0.0 are considered equal. If either floating-point number is NaN (not a number), equal returns false.
The Not Equal Operator
The not equal operator (!=) is the opposite of the equal operator for all types, with a slight variation for floating-point types only. If one of the floating-point numbers is NAN (not a number), not equal returns true.
There are two forms of not equal applicable to expressions. The first is the normal not equal operator (!=). The other is a negation of the equal operator !(a==b). Normally, these two forms always evaluate to the same value. The exception occurs when evaluating floating-point expressions where one or both expressions evaluate to NaN and the relational operator in the negation of an expression is <, >, <=, or >=. The a > b form evaluates to false, but the !(a<=b) evaluates to true. Here are some examples:
bool bresult; decimal debit = 1500.00m; decimal credit = 1395.50m; bresult = debit != credit; // bresult = true bresult = !(debit == credit); // bresult = true
The Less Than Operator
If it's necessary to find out if one value is smaller than another, use the less than operator (<). The expression on the left is being evaluated and the expression on the right is the basis of comparison. When the expression on the left is a lower value than the expression on the right, the result is true. Otherwise, the result is false. Here's an example:
short redBeads = 2; short whiteBeads = 23; bool bresult; bresult = redBeads < whiteBeads; // bresult=true, work harder
The Greater Than Operator
If it's necessary to know that a certain value is larger than another, use the greater than operator (>). It compares the expression on the left to the basis expression on the right. When the expression on the left is a higher value than the expression on the right, the result is true. Otherwise, the result is false. Here's an example:
short redBeads = 13; short whiteBeads = 12; bool bresult; bresult = redBeads > whiteBeads; // bresult=true, good job!
The Less Than or Equal Operator
Sometimes it's necessary to know if a number is either lower than or equal to another number. That's what the less than or equal operator (<=) is for. The expression on the left is compared to the expression on the right. When the expression on the left is either the same value as or less than the one on the right, less than or equal returns true. This operator is the opposite of the greater than operator, which means that !(a>b) would produce the same results. The exception is when there's a floating-point expression evaluating to NaN, in which case the result is always true. Here's an example of the less than or equal operator:
float limit = 4.0f; float currValue = 3.86724f; bool Bresult; bresult = currValue <= limit; // bresult = true
The Greater Than or Equal Operator
As its name implies, the greater than or equal operator (>=) checks a value to see if it's greater than or equal to another. When the expression to the left of the operator is the same as or more than the expression on the right, greater than or equal returns true. The greater than or equal operator is the opposite of the less than operator. Here's an example:
double rightAngle = 90.0d; double myAngle = 96.0d; bool isAbtuse; isAbtuse = myAngle >= rightAngle; // Yes, myAngle is abtuse
Logical Operators
Logical operators perform Boolean logic on two expressions. There are three types of logical operators in C#: bitwise, Boolean, and conditional.
The bitwise logical operators perform Boolean logic on corresponding bits of two integral expressions. Valid integral types are the signed and unsigned int and long types. They return a compatible integral result with each bit conforming to the Boolean evaluation.
Boolean logical operators perform Boolean logic upon two Boolean expressions. The expression on the left is evaluated, and then the expression on the right is evaluated. Finally, the two expressions are evaluated together in the context of the Boolean logical operator between them. They return a bool result corresponding to the type of operator used.
The conditional logical operators operate much the same way as the Boolean logical operators with one exception in behavior: Once the first expression is evaluated and found to satisfy the results of the entire expression, the second expression is not evaluated. This is efficient because it doesn't make sense to continue evaluating an expression when the result is already known.
The Bitwise AND Operator
The bitwise AND operator (&) compares corresponding bits of two integrals and returns a result with corresponding bits set to 1 when both integrals have 1 bits. When either or both integrals have a 0 bit, the corresponding result bit is 0. Here's an example:
byte oddMask = 1; // 00000001b byte someByte = 85; // 01010101b bool isEven; isEven = (oddMask & someByte) == 0; //(oddMask & someByte) = 1
The Bitwise Inclusive OR Operator
The bitwise inclusive OR operator (|) compares corresponding bits of two integrals and returns a result with corresponding bits set to 1 if either of the integrals have 1 bits in that position. When both integrals have a 0 in corresponding positions, the result is zero in that position. Here's an example:
byte option1 = 1; // 00000001b byte option2 = 2; // 00000010b byte totalOptions; totalOptions = (byte) (option1 | option2); // 00000011b
The Bitwise Exclusive OR Operator
The bitwise exclusive OR operator (^) compares corresponding bits of two integrals and returns a result with corresponding bits set to 1 if only one of the integrals has a 1 bit and the other integral has a 0 bit in that position. When both integral bits are 1 or when both are 0, the result's corresponding bit is 0. Here's an example:
byte invertMask = 255; // 11111111b byte someByte = 240; // 11110000b byte inverse; inverse = (byte)(someByte ^ invertMask); //inversion=00001111b
The Boolean AND Operator
The Boolean AND operator (&) evaluates two Boolean expressions and returns true when both expressions evaluate to true. Otherwise, the result is false. The result of each expression evaluated must return a bool result. Here's an example:
bool inStock = false; decimal price = 18.95m; bool buy; buy = inStock & (price < 20.00m); // buy = false
The Boolean Inclusive OR Operator
The Boolean inclusive OR operator (|) evaluates the results of two Boolean expressions and returns true if either of the expressions returns true. When both expressions are false, the result of the Boolean inclusive OR evaluation is false. Both expressions evaluated must return a bool type value. Here's an example:
int mileage = 2305; int months = 4; bool changeOil; changeOil = mileage > 3000 | months > 3; // changeOil = true
The Boolean Exclusive OR Operator
The Boolean exclusive OR operator (^) evaluates the results of two Boolean expressions and returns true if only one of the expressions returns true. When both expressions are true or both expressions are false, the result of the Boolean exclusive OR expression is false. In other words, the expressions must be different. Here's an example:
bool availFlag = false; bool toggle = true; bool available; available = availFlag ^ toggle; // available = true
The Conditional AND Operator
The conditional AND operator (&&) is similar to the Boolean AND operator in that it evaluates two expressions and returns true when both expressions are true. It is different when the first expression evaluates to false. Since both expressions must be true, it's automatically assumed that if the first expression evaluates to false, the entire expression is false. Therefore, the conditional AND operator returns false and does not evaluate the second expression. When the first expression is true, the conditional AND operator goes ahead and evaluates the second expression. Here's an example:
bool inStock = false; decimal price = 18.95m; bool buy; buy = inStock && (price < 20.00m); // buy = false
Notice that price < 20 will never be evaluated.
The Conditional OR Operator
The conditional OR operator (||) is similar to the Boolean inclusive OR operator (|) in that it evaluates two expressions and returns true when either expression is true. The difference is when the first expression evaluates to true. Since either expression can be true to prove that the overall expression is true, the operator automatically assumes that the entire expression is true when it finds the first expression is true. Therefore, the conditional OR operator returns true without evaluating the second expression. When the first expression is false, the conditional OR operator goes ahead and evaluates the second expression. Here's an example:
int mileage = 4305; int months = 4; bool changeOil; changeOil = mileage > 3000 || months > 3; // changeOil = true
Notice that because mileage > 3000 is true, months > 3 will never be evaluated.
Side Effects
Watch out for side effects with conditional Boolean operations. Side effects occur when your program depends on the expression on the right of the conditional logical operator being evaluated. If the expression on the right is not evaluated, this could cause a hard-to-find bug. The conditional logical operators are also called short circuit operators. Take a look at this example:
decimal totalSpending = 3692.48m; decimal avgSpending; bool onBudget = totalSpending > 4000.00m && totalSpending < calcAvg();
Notice that the second half of the expression was not evaluated. If calcAvg() was supposed to change the value of a class field for later processing, there would be an error.
Warning
When using conditional AND and conditional OR operators, make sure a program does not depend upon evaluation of the right-hand side of the expression, because it may not be evaluated. Such side effects are likely to cause bugs.
Assignment Operators
This chapter has already demonstrated plenty of examples of the simple assignment operator in action. This section explains the compound operators and what can be expected from them. Basically, the concept is simple. A compound operator is a combination of the assignment operator and an arithmetic operator, bitwise logical operator, or Boolean logical operator. Here's an example:
int total = 7; total += 3; // total = 10
This is the same as saying: total = total + 3. Table 3.1 shows a list of the available compound assignment operators.
Table 3.1 Compound Assignment Operators
Operator |
Function |
---|---|
*= |
Multiplication |
/= |
Division |
%= |
Remainder |
+= |
Addition |
-= |
Subtraction |
<<= |
Left Shift |
>>= |
Right Shift |
&= |
AND |
^= |
Exclusive OR |
|= |
Inclusive OR |