LEVIATHAN v962456e · 962456eee1

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 0 to width - 1 throws a RuntimeException with the message shift 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 expression one << 4 is computed at 8 bits and the valid counts are 0 to 7, but one << shift with an int variable shift joins to int and the valid counts are 0 to 63.
  • A negative shift count is also out of range.
  • >> keeps the sign: -16 >> 2 is -4.
  • ~ gives a result of the operand's own type, reduced to its own width, so ~b for a byte holding 255 is 0 and the complement of a byte holding 0 is 255, 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'
not run — shows a compile error

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.