Coercion By Bitwise Operators
The bitwise operators in this version of JScript are fully compatible with the bitwise operators in previous versions of JScript. In addition, the JScript operators can also be used on the new numeric data types. The behavior of the bitwise operators depends on the binary representation of the data, so it is important to understand how the operators coerce the types of the data.
Three types of arguments can be passed to bitwise operators: early-bound variables, late-bound variables, and literal data. Early-bound variables are variables defined with an explicit type annotation. Late-bound variables are variables of type Object that contain numeric data.
Bitwise AND (&), OR (|) and XOR (^) Operators
If either operand is late-bound or if both operands are literals, then both operands are coerced to int (System.Int32), the operation is performed, and the return value is an int.
If both operands are early-bound or if one operand is literal and the other is early-bound, more steps are performed. Both operands are coerced to a type determined by two conditions:
If neither operand is integral, both operands are coerced to int.
If only one operand is integral, the nonintegral operand is either coerced to the integral type or coerced to int, whichever type is longer.
If one operand is longer, then the type to which the operand is coerced has the same length as the longer operand.
If either operand is unsigned, then the type to which the operand is coerced is unsigned. Otherwise, the type coerced is signed.
The operands are then coerced to the appropriate type, the bitwise operation is performed, and the result is returned. The data type of the result is the same as the type of the coerced operands.
When using an integral literal with a bitwise operator and an early-bound variable, the literal will be interpreted as either an int, long, ulong, or double, depending on which is the smallest type that can represent the number. Literal decimal values are coerced to double. The data type of the literal may undergo further coercion according to the rules described above.
Bitwise NOT (~) Operator
If the operand is late-bound, floating-point, or a literal, it is coerced to int (System.Int32), the NOT operation is performed, and the return value is an int.
If the operand is early-bound integral data type, the NOT operation is performed, and the return type is the same as the type of the operand.
Bitwise Left Shift (<<), Right Shift (>>) Operators
If the left operand is late-bound, floating-point, or a literal, it is coerced to an int (System.Int32). Otherwise, the left operand is early-bound integral data type and no coercion is performed. The right operand is always coerced to an integral data type. The shift operation is then performed on the coerced values and the result returned has the same type as the left operand (if early-bound) or as type int.
Unsigned Right Shift (>>>) Operators
If the left operand is late-bound, floating-point, or a literal, it is coerced to a uint (System.UInt32). Otherwise, the left operand is early-bound integral data type and it is coerced to an unsigned type of the same size. For example, an int would be coerced to a uint. The right operand is always coerced to an integral data type. The shift operation is then performed on the coerced values, and the result returned has the same type as the coerced left operand (if early-bound) or as type uint.
The result of the unsigned right shift is always small enough to be stored in the signed version of the return type without overflow.