Bitwise operators#
The boolean operators applied to each pair of bits in parallel, plus the two shifts. A 32- or 64-bit integer is, from these operators« point of view, a vector of independent one-bit values.
Operator | Operation | Per-bit rule |
|---|---|---|
| bitwise AND | each output bit = |
| bitwise OR | each output bit = |
| bitwise XOR | each output bit = |
| bitwise NOT | each output bit = |
| left shift | shift bits left, zero-fill from right |
| right shift | shift bits right |
Operands are coerced to integers (the floor toward zero, with warnings if a non-integer string is supplied under use warnings).
0xFF & 0x0F # 0x0F -- mask to low nibble
0x10 | 0x01 # 0x11 -- combine flag bits
0xFF ^ 0xAA # 0x55 -- toggle alternating bits
~0 # -1 (or all-ones, depending on integer width)
1 << 4 # 16
32 >> 2 # 8
Setting, clearing, toggling, testing a flag#
The four basic flag operations on a single bit:
use constant FLAG_VERBOSE => 0x01;
use constant FLAG_DRY_RUN => 0x02;
use constant FLAG_RECURSE => 0x04;
use constant FLAG_FORCE => 0x08;
my $flags = 0;
$flags |= FLAG_VERBOSE; # SET -- OR with the bit
$flags |= FLAG_DRY_RUN; # SET another
$flags &= ~FLAG_DRY_RUN; # CLEAR -- AND with the inverted bit
$flags ^= FLAG_VERBOSE; # TOGGLE -- XOR with the bit
my $on = $flags & FLAG_RECURSE;# TEST -- AND, then test truthiness
Each is a one-bit application of a boolean operator: set is bit ∨ flag, clear is bit ∧ ¬flag, toggle is bit ⊕ flag, test is bit ∧ flag.
Compound assignment#
All six binary bitwise operators have compound forms:
$bits &= $mask; # AND-assign
$flags |= 0x01; # OR-assign (set bit)
$x ^= $y; # XOR-assign (toggle bits where $y is 1)
$x <<= 1; # multiply-by-2 (with overflow caveats)
$x >>= 1; # divide-by-2 (toward -∞ for signed values)
Shifts#
<< shifts left; >> shifts right. The number of bit positions to shift is the right operand. Shifting by a negative amount, or by an amount equal to or greater than the integer’s bit width, is implementation-defined — don’t rely on it.
For unsigned arithmetic, left-shift is multiplication by 2 ** $n (modulo overflow):
$x << 1 # like $x * 2
$x << 8 # like $x * 256
For unsigned arithmetic, right-shift is integer division by 2 ** $n:
$x >> 1 # like int($x / 2) (for non-negative $x)
$x >> 8 # like int($x / 256)
For signed values, >> is implementation-defined — Perl does not guarantee arithmetic vs logical shift. Mask explicitly when sign matters:
($x >> 8) & 0xFF # extract a byte at offset 8, regardless of sign
Numeric vs bytewise mode#
Perl’s bitwise operators act on integers by default. With use feature 'bitwise' (or use v5.22+), the suffixed forms &., |., ^., ~. act on strings byte-by-byte:
use feature 'bitwise';
"\x80" |. "\x01" # "\x81" -- single-byte string OR
"abc" ^. "abc" # "\0\0\0" -- bytewise XOR
The undecorated &, |, ^, ~ operators always do integer math, and string operands are coerced to numbers first. The suffixed .-forms are the way to ask for byte-string operations explicitly.
XOR-swap#
XOR has two properties — a ⊕ a = 0 and a ⊕ b ⊕ b = a — that combine into the famous swap-without-temporary trick:
my ($a, $b) = (0xFEED, 0xBEEF);
$a ^= $b; # a := a ⊕ b
$b ^= $a; # b := b ⊕ (a ⊕ b) = a
$a ^= $b; # a := (a ⊕ b) ⊕ a = b
# $a == 0xBEEF, $b == 0xFEED
Not faster than ($a, $b) = ($b, $a) in Perl. Worth knowing because it appears in interview folklore and embedded code, and because it is a clean illustration of the XOR identity.
Common bit tricks#
Patterns you will see in performance-sensitive code:
$x & ($x - 1) # $x with its lowest set bit cleared
($x & ($x - 1)) == 0 # true when $x is a power of two (and non-zero)
1 << $n # the integer with only bit $n set
$x & (1 << $n) # is bit $n set in $x?
$x | (1 << $n) # set bit $n
$x & ~(1 << $n) # clear bit $n
$x ^ (1 << $n) # toggle bit $n
($x >> $n) & 0xFF # extract a byte at offset $n
Each is an exercise in tracking what each bit does — pure boolean reasoning applied 32 (or 64) times in parallel.
Tutorial cross-reference#
The boolean-logic tutorial has a longer treatment of the bitwise-as-parallel-boolean model and the application patterns above:
Boolean Logic — Applications — bitwise operators as parallel boolean, flag manipulation, XOR-swap, common bit tricks.
Boolean Logic — Operators — the boolean foundations the bitwise operators inherit.
See also#
Logical — the same boolean operators on whole values.
Precedence —
&,|,^sit between comparison and&&/||. Almost always parenthesise around them.pack,unpack,vec— perlfunc tools for bit-level work beyond what raw operators offer.