Скачиваний:
64
Добавлен:
15.03.2015
Размер:
4.31 Mб
Скачать
NEW TERM
NEW TERM

Working with Operators

99

Answer = 4 * ( 5 + 6 ) / ( 2 – 1 );

Now what will Answer be? Because the parentheses are evaluated first, the compiler first resolves the code to

Answer = 4 * 11 / 1;

The final result is 44. You can also have parentheses within parentheses. For example, the code could be written as

Answer = 4 * ( ( 5 + 6 ) / ( 2 – 1 ) );

The compiler would resolve this as

Answer = 4 * ( 11 / 1 );

Then it would resolve it as

Answer = 4 * 11;

and finally as the Answer of 44. In this case, the parentheses didn’t cause a difference in the final answer; however, there are times when they do.

Converting Data Types

4

When you move a value from one variable type to another, a conversion must occur. Additionally, if you want to perform an operation on two different data types, a conversion might also need to occur. There are two types of conversions that can occur: implicit and explicit.

Implicit conversions happen automatically without error. You’ve read about many of these within today’s lesson. What happens when an implicit conversion is not

available? For example, what if you want to put the value stored in a variable of type long into a variable of type int?

Explicit conversions are conversions of data that are forced. For the value data types that you learned about today, the easiest way to do an explicit conversion is

with a cast. A cast is the forcing of a data value to another data type. The format of a cast is

ToVariable = (datatype) FromVariable;

where datatype is the data type you want the FromVariable converted to. Using the example of converting a long variable to an int, you enter the following statement:

int IntVariable = 0; long LongVariable = 1234;

IntVariable = (int) LongVariable;

NEW TERM

100

Day 4

In doing casts, you take responsibility for making sure that the variable can hold the value being converted. If the receiving variable cannot store the received value, truncation or other changes can occur. There are a number of times when you are going to need to do explicit conversions. Table 4.4 contains a list of those times.

Note

Explicit conversions as a group also encompass all the implicit conversions. It is possible to use a cast even if an implicit conversion is available.

Table 4.4. Required Explicit Conversions

From Type

To Type(s)

 

sbyte

byte, ushort, uint,

ulong, or char

byte

sbyte or char

 

short

sbyte, byte, ushort, uint, ulong, or char

ushort

sbyte, byte, short,

or char

int

sbyte, byte, short,

ushort, uint, ulong, or char

uint

sbyte, byte, short,

ushort, int, or char

long

sbyte, byte, short,

ushort, int, uint, ulong, or char

ulong

sbyte, byte, short,

ushort, int, uint, long, or char

char

sbyte, byte, short

 

float

sbyte, byte, short,

ushort, int, uint, long, ulong, char,

 

or decimal

 

double

sbyte, byte, short,

ushort, int, uint, long, ulong, char,

 

float, or decimal

 

decimal

sbyte, byte, short,

ushort, int, uint, long, ulong, char,

 

float, double

 

 

 

 

Understanding Operator Promotion

Implicit conversions are also associated with operator promotion, which is the automatic conversion of an operator from one type to another. When you do

basic arithmetic operations on two variables, they are converted to the same time before doing the math. For example, if you add a byte variable to an int variable, the byte variable is promoted to an integer before being added.

NEW TERM

Working with Operators

101

A numeric variable smaller than an int will be promoted to an int. The order of promotion after an int is

int

uint

long

ulong

float

double

decimal

For Those Brave Enough

For those brave enough, the following sections explain using the bitwise operators. This includes using the shift operators and the logical bitwise operators. Before understanding how these operators work, you need to understand how variables are truly stored.

Tip

4

It is valuable to understand the bitwise operators and how memory works; however, it is not critical to your understanding C#. This is considered an advanced topic by a lot of people.

Storing Variables in Memory

To understand the bitwise operators, you must first understand bits. In yesterday’s lesson on data types, you learned that the different data types take different numbers of bits to store. For example, a char data type takes 2 bytes. An integer takes 4 bytes. You also learned that there were maximum and minimum values that could be stored in these different data types.

Recall that a byte is 8 bits of memory. Two bytes is 16 bits of memory—two times eight. Four bytes is therefore 32 bits of memory. So the key to all of this is to understand what a bit is.

A bit is simply a single storage unit of memory that can be either turned on or turned off just like a light bulb. If storing information on a magnetic medium, a

bit can be stored as either a positive charge or a negative charge. If working with something such as a CD-ROM, this can be stored as a bump or as an indent. In all these cases, one value is equated to 0 and the other is equated to 1.

102

Day 4

If a bit can store only a 0 or a 1, you are obviously very limited in what can be stored. To be able to store larger values, you use bits in groups. For example, if you use 2 bits, you can actually store four numbers, 00, 01, 10, and 11. If you use three bits, you can store 8 numbers, 000, 001, 010, 011, 100, 101, 110, and 111. If you use four bits, you can store 16 numbers. In fact x bits can store 2x numbers, so a byte (8 bits), can store 28 or 256 numbers. Two bytes can store 216 or 65536 values.

Translating from these 1s and 0s is simply a matter of using the binary number system. Appendix D, “Understanding Different Number Systems” explains how you can work with the binary number system in detail. For now understand that the binary system is simply a number system.

You use the decimal number system to count. Where the decimal system uses 10 numbers (0 to 9) the binary system uses two numbers. When counting in the decimal system, you use 1s, 10s, 100s, 1000s, and so forth. For example, the number 13 is one 10 and three 1s. The number 25 is two 10s and five 1s.

The binary system works the same way except there are only two numbers, 0 and 1. Instead of 10s and 100s, you have 1s, 2s, 4s, 8s, and so on. In fact each group is based on taking 2 to the power of a number. The first group is 2 to the power of 0, the second is 2 to the power of 1, the third is 2 to the power of 3,and so on. Figure 4.2 illustrates this.

FIGURE 4.2

 

103

102

 

101

100

Decimal

Binary versus decimal.

… Thousands

Hundreds

Tens

Ones

 

 

 

 

 

 

 

 

 

 

24

23

22

21

20

Binary

 

Sixteens

Eights

Fours

Twos

Ones

 

 

Presenting numbers in the binary system works the same way it does in the decimal system. The first position on the right is 1s, the second position from the right is 2s, the third is 4s, and so on. Consider the following number:

1101

To convert this binary number to decimal, you can take each value in the number times its positional value. For example, the value in the right column (1s) is 1. The 2s column contains a 0, the 4s column contains a 1, and the 8s column contains a 1. The result is

1 + (0 * 2) + (1 * 4) + (1 * 8)

The final decimal result is

1 + 0 + 4 + 8

Working with Operators

103

which is 13. So 1101 in binary is equivalent to 13 in decimal. This same process can be applied to convert any binary number to decimal. As numbers get larger you need more bit positions. To keep things simpler, memory is actually separated into 8-bit units—bytes.

Shift Operators

C# has two shift operators that can be used to manipulate bits. These operators do exactly what their names imply—they shift the bits. The shift operators can shift the bits to the right using the >> operator or to the left using the << operator. These operators shift the bits within a variable by a specified number of positions. The format is

New_value = Value [shift-operator] number-of-positions;

where Value is a literal or variable, shift-operator is either the right (>>) or left (<<) shift operator, and number-of-positions is how many positions you want to shift the bits. For example, if you have the number 13 stored in a byte, you know its binary representation is

00001101

If you use the shift operator on this, you change the value. Consider the following:

00001101 >> 2

4

This shifts the bits in this number to the right two positions. The result is

00000011

This binary value is equivalent to the value of 3. In summary, 13 >> 2 equals 3. Consider another example:

00001101 << 8

This example shifts the bit values to the left 8 positions. Because this is a single byte value, the resulting number is 0.

Logical Operators

In addition to being able to shift bits, you can also combine the bits of two numbers. There are four bitwise logical operators, as shown in Table 4.5.

TABLE 4.5 Logical Bitwise Operators

Operator

Description

|

Logical OR bitwise operator

&

Logical AND bitwise operator

^

Logical XOR bitwise operator

~

Logical NOT bitwise operator

 

 

104

Day 4

Each of these operators is used to combine the bits of two binary values together. Each has a different result.

The Logical OR Bitwise Operator

When combining two values with the logical OR bitwise operator (|), you get the following results:

If both bits are0, the result is 0.

If either or both bits are 1, the result is 1.

Combining two byte values results in the following:

Value 1:

00001111

Value 2:

11001100

 

————

Result:

11001111

The Logical AND Bitwise Operator

When combining two values with the logical AND bitwise operator (&), you get the following result:

If both bits are 1, the result is 1.

If either bit is 0, the result is 0.

Combining two byte values results in the following:

Value 1:

00001111

Value 2:

11001100

 

————

Result:

00001100

The Logical NOT Operator

When combining two values with the logical NOT bitwise operator (^), you get the following result:

If both bits are the same, the result is 0.

If one bit is 0 and the other is 1, the result is 1.

Combining two byte values results in the following:

Value 1:

00001111

Value 2:

11001100

 

————

Result:

11000011

Working with Operators

Listing 4.7 illustrates the three logical bitwise operators.

LISTING 4.7 The Bitwise Operators

1:// bitwise.cs - Using the bitwise operators

2://----------------------------------------------------

4:class bitwise

5:{

6:static void Main()

7:{

8:int ValOne = 1;

9:int ValZero = 0;

10:int NewVal;

11:

12: // Bitwise NOT Operator 13:

14:NewVal = ValZero ^ ValZero;

15:System.Console.WriteLine(“\nThe NOT Operator: \n 0 ^ 0 = {0}”,

NewVal);

17:NewVal = ValZero ^ ValOne;

18:System.Console.WriteLine(“ 0 ^ 1 = {0}”, NewVal);

20:NewVal = ValOne ^ ValZero;

21:System.Console.WriteLine(“ 1 ^ 0 = {0}”, NewVal);

23:NewVal = ValOne ^ ValOne;

24:System.Console.WriteLine(“ 1 ^ 1 = {0}”, NewVal);

26: // Bitwise AND Operator 27:

28:NewVal = ValZero & ValZero;

29:System.Console.WriteLine(“\nThe AND Operator: \n 0 & 0 = {0}”,

NewVal);

31:NewVal = ValZero & ValOne;

32:System.Console.WriteLine(“ 0 & 1 = {0}”, NewVal);

34:NewVal = ValOne & ValZero;

35:System.Console.WriteLine(“ 1 & 0 = {0}”, NewVal);

37:NewVal = ValOne & ValOne;

38:System.Console.WriteLine(“ 1 & 1 = {0}”, NewVal);

40:// Bitwise OR Operator

105

4