Recipe 1.4. Using the Bitwise
Complement Operator with Various Data Types
Problem
The bitwise complement operator (~) is
overloaded to work directly with
int, uint, long, ulong
,
and enumeration data types consisting of the underlying types
int, uint, long
, and
ulong
. However, you need to
perform a bitwise complement operation on a different numeric data
type.
Solution
To use the bitwise complement operator with any
data type, you must cast the resultant value of the bitwise
operation to the type you wish to work with. The following code
demonstrates
this technique with the
byte
data type:
byte y = 1;
byte result = (byte)~y;
The value assigned to
result
is
254
.
Discussion
The following code shows incorrect use of the
bitwise complement operator on the
byte
data type:
byte y = 1;
Console.WriteLine("~y = " + ~y);
This code outputs the following surprising
value:
-2
Clearly, the result from performing the bitwise
complement of the
byte
variable is incorrect; it should be
254
. In fact,
byte
is an unsigned data type, so
it cannot be equal to a negative number. If you rewrite the code as
follows
:
byte y = 1;
byte result = ~y;
you get a compile-time error: "Cannot implicitly
convert type 'int' to 'byte.'" This error message gives some
insight into why this operation does not work as expected. To fix
this problem, you must explicitly cast this value to a
byte
before you assign it to the
result
variable,
as shown here:
byte y = 1;
byte result = (byte)~y;
This cast is required because the bitwise
operators are overloaded to
operate
on only six specific data
types:
int, uint, long, ulong, bool
, and enumeration data
types. When one of the bitwise operators is used on another data
type, that data type is converted to the supported data type that
matches it most closely. Therefore, a
byte
data type is
converted to an
int
before the bitwise complement operator
is evaluated:
0x01 // byte y = 1;
0xFFFFFFFE // The value 01h is converted to an int and its
// bitwise complement is taken.
// This bit pattern equals -2 as an int.
0xFE // The resultant int value is cast to its original byte data type.
Notice that the
int
data type is a
signed data type, unlike the
byte
data type. This is why
you receive
-2
for a result instead of the expected value
254
. This conversion of the
byte
data type to its
nearest
equivalent is called
numeric
promotion
. Numeric promotion also comes into play when you
use differing data types with binary operators, including the
bitwise binary operators.
|
Numeric promotion is discussed in detail in the
C# Language Specification document in section 7.2.6 (this document
is available at
http://msdn.microsoft.com/vcsharp/programming/language).
Understanding how numeric promotion works is essential when using
operators on differing data types and when using operators with a
data type that is not overloaded to handle them. Knowing this can
save you hours of debugging time.
|
|
|