Expressions
Integer operators
Shifts, xor, remainder and complement on every integer width, the width at which they compute, and the exception thrown by an out-of-range shift.
since 0.1.0-alpha.1linuxwindowswasm
Description
These operators are defined on every integer type, not only int: int, byte, int8, int16, int32 and uint.
| operator | meaning |
|---|---|
<< |
shift left |
>> |
shift right, arithmetic: the sign bit is copied in on the left |
^ |
bitwise exclusive or |
% |
remainder |
~ (prefix) |
bitwise complement |
There is no shift, xor or complement on float or on any narrow float type, and no ^ or ~ on bool (use != and !) or on string.
When the two operands are different integer types, they are first joined to a common working type, and the operation is computed and reduced at that type's width. An integer literal operand takes the type of the other operand before the join. The result wraps at that width.
Operators at the width of the operands
console.writeln(1 << 4);
console.writeln(256 >> 4);
console.writeln(-16 >> 2);
console.writeln(5 ^ 3);
console.writeln(~0);
console.writeln(17 % 5);
byte b = 255;
console.writeln(b << 1);
console.writeln(~b);
byte hundred = 200;
console.writeln(hundred ^ 100);
16
16
-4
6
-1
2
254
0
172
Rules
- The shift count must fit the width of the joined result type. A count outside
0towidth - 1throws aRuntimeExceptionwith the messageshift count out of range. It does not silently wrap or mask the count. - The width that bounds the count is the one of the joined result type, not of the left operand alone. With
byte one = 1;, the expressionone << 4is computed at 8 bits and the valid counts are0to7, butone << shiftwith anintvariableshiftjoins tointand the valid counts are0to63. - A negative shift count is also out of range.
>>keeps the sign:-16 >> 2is-4.~gives a result of the operand's own type, reduced to its own width, so~bfor abyteholding255is0and the complement of abyteholding0is255, never-1.- When the left operand is an object,
<<and>>call the class's own(<<)and(>>)operators instead. That is how stream transfer operators are written, and it is the same rule that lets+be both integer addition and a user-defined(+).
Examples
A shift count outside the width throws
byte one = 1;
console.writeln(one << 7);
try {
console.writeln(one << 8);
} catch (RuntimeException e) {
console.writeln("caught: ${e.message}");
}
int count = 64;
try {
console.writeln(1 << count);
} catch (RuntimeException e) {
console.writeln("caught: ${e.message}");
}
console.writeln(1 << 63);
int shift = 8;
console.writeln(one << shift);
128
caught: shift count out of range
caught: shift count out of range
-9223372036854775808
256
console.writeln(1.5 << 1);
// error: no operator '<<' on promoted numeric type 'float'
console.writeln(true ^ false);
// error: no operator '^' between 'bool' and 'bool'
Notes
The widths are 8 bits for byte and int8, 16 for int16, 32 for int32 and uint, and 64 for int.
See also
- int — The signed 64-bit integer type, the default type of whole numbers.