I just discovered that C# will not let you perform bitwise operations on a ulong and an int. Every other combination of int, uint, long, and ulong will work, but that one pairing doesn't.
However, if instead of an int, I have a const int, everything is fine.
What's going on here? Why is int & ulong invalid, but const int & ulong valid?
Broken:
int mask = 0x1110;
ulong value = 0x1010;
var result = mask & value; // Compilation error: "Operator '&' cannot be applied to operands of type 'int' and 'ulong'"
Working:
const int mask = 0x1110;
ulong value = 0x1010;
var result = mask & value; // Works just fine.
This behavior is not specific to bitwise operations. According to C# Language Specification, it applies to all binary operations requiring numeric promotions.
Section 7.6.3.2 describes binary numeric promotions. I emphasized the section that specifies the behavior that you see:
Binary numeric promotion consists of applying the following rules, in the order they appear here:
- If either operand is of type
decimal, the other operand is converted to typedecimal, or a binding-time error occurs if the other operand is of typefloatordouble.- Otherwise, if either operand is of type
double, the other operand is converted to typedouble.- Otherwise, if either operand is of type
float, the other operand is converted to typefloat.- Otherwise, if either operand is of type
ulong, the other operand is converted to typeulong, or a binding-time error occurs if the other operand is of typesbyte,short,int, orlong.- Otherwise, if either operand is of type
long, the other operand is converted to typelong.- Otherwise, if either operand is of type
uintand the other operand is of typesbyte,short, or int, both operands are converted to typelong.- Otherwise, if either operand is of type
uint, the other operand is converted to typeuint.- Otherwise, both operands are converted to type
int.
The reason the problem does not happen when you use const is that the compiler is allowed to convert const int expression to other types, as described in section 7.19:
An implicit constant expression conversion (§6.1.9) permits a constant expression of type
intto be converted tosbyte,byte,short,ushort,uint, orulong, provided the value of the constant expression is within the range of the destination type.
Since the value of mask, i.e. 0x1110, fits within ulong, the compiler performs the promotion instead of triggering the error.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With