Skip to content

Rotate Left

Level: 201 · for anyone with a hex editor open

One line: Rotate Left is Shift Left with the bits that pass the top fed back in at the bottom, so nothing is lost and every rotation can be undone — Rotate Left 4 swaps a byte's two hex digits, C3 becoming 3C, and Rotate Left 8 on an Unsigned Short is Swap Bytes.

What the dialog does

The manual describes it by comparison: like Shift Left, except that what is shifted off X[i] is added back on its right side (Hex Operations). The bits of each value move in a circle of the value's width. Shift Left drops what leaves; Block Shift Left hands it to the neighbouring value; Rotate Left keeps it.

In Python

Verified output of rotate_left_py.py — regenerated by tools/run_examples.py, never hand-typed.

1. THE BIT THAT FALLS OFF COMES BACK
------------------------------------------------------------------------
   81 is 1000 0001. Shift and rotate it left by 1:

     Shift Left 1    02   00000010
     Rotate Left 1   03   00000011

2. ROTATE LEFT 4 SWAPS A BYTE'S TWO HEX DIGITS
------------------------------------------------------------------------
     é   c3 a9 -> 3c 9a
     the same as swapping the digits, all 256 bytes   True

   Four is half of eight, so the top digit comes round to the bottom
   and the bottom digit is pushed up to the top.

3. NOTHING IS LOST
------------------------------------------------------------------------
     Rotate Left 1, eight times, gives every byte back   True
     different bytes Rotate Left 1 can write             256 of 256
     Rotate Left 3, then Rotate Left 5, is no change     True

   Every byte in, a different byte out, and all 256 of them reachable:
   a rotation only reorders bits, so it can always be turned back.

4. ROTATE LEFT 8 ON AN UNSIGNED SHORT IS SWAP BYTES
------------------------------------------------------------------------
     all 65,536 Unsigned Shorts   True

   Half of sixteen is eight, and a byte is eight bits: rotating a Short
   by half its width trades its two bytes.

5. SIGNED OR UNSIGNED, THE SAME BITS
------------------------------------------------------------------------
     all 256 bytes, counts 0-7   True

   A rotation moves bits and never looks at what they mean. The number
   read back can change sign -- 40 rotated left by 1 is 80, which is
   +64 becoming -128 -- but the bytes do not depend on the dropdown.

Nothing is lost

Section 1 is the difference in one byte: 81, which is 1000 0001, shifted left by 1 is 02, and rotated left by 1 is 03, because the high 1 came round to the bottom. Section 3 checks what that buys. Eight Rotate Left 1s give every byte back; Rotate Left 1 writes all 256 byte values, each from exactly one input; and Rotate Left 3 followed by Rotate Left 5 is no change at all. A rotation only reorders a value's bits, so there is always a rotation that puts them back — which is not true of any shift.

Rotate Left 4 swaps the hex digits

Half of eight is four, so rotating a byte left by 4 carries the top digit round to the bottom and pushes the bottom one up: section 2 turns é's C3 A9 into 3C 9A, and checks the rule against a digit swap for all 256 bytes. The same argument one size up is section 4: half of sixteen is eight, and a byte is eight bits, so Rotate Left 8 on an Unsigned Short trades its two bytes, and the program finds it identical to Swap Bytes on all 65,536 values.

The sign is not consulted

Section 5 rotates every byte under both Signed and Unsigned Byte, for every count, and the bytes never differ: a rotation moves bits and never looks at what they mean. The number read back can still change sign. 40 rotated left by 1 is 80, which is +64 becoming −128, with no arithmetic involved.

What the manual does not say

  • What a count of the width of the type or more does. The program takes the count modulo the width, as Rust's rotate_left does.
  • Whether Rotate Left is offered for Float and Double.

If you are coming from Python or ABAP

Python. For a count n between 1 and 7, ((b << n) | (b >> (8 - n))) & 0xFF is Rotate Left as Unsigned Byte; for a general count, reduce it with n % 8 first, since b >> 8 and beyond is always 0. The width is part of the formula — 8 in two places — which is Treat Data As written into the expression.

ABAP. (Not machine-checked — CI cannot run ABAP.) ABAP's bit expressions have four operators and none of them moves a bit ↗, but SHIFT … CIRCULAR IN BYTE MODE puts what is shifted off one end back in at the other ↗: a rotation of the whole field by whole bytes. On a two-byte field, SHIFT hex BY 1 PLACES LEFT CIRCULAR IN BYTE MODE is section 4's Rotate Left 8, which is Swap Bytes. A rotation within each byte, or by a count that is not a multiple of eight, is GET BIT and SET BIT over positions counted from the beginning of the field ↗.

Try it

  1. Rotate Left 4 a copy of a text file as Unsigned Byte and read the hex column: every byte's two digits have changed places.
  2. Rotate Left 1 a scratch byte eight times, reading it in binary in the Inspector after each, and watch it come back.
  3. On two copies of a file, Rotate Left 8 as Unsigned Short on one and Swap Bytes on the other, and compare them with Tools > Compare.
  4. Type 40, Rotate Left 1 as Signed Byte, and read the Inspector's signed value before and after.

See also

  • Rotate Right — the same circle, the other way, and what the Endian toggle cannot change about it
  • Swap Bytes — Rotate Left 8 on a Short
  • Shift Left — the same move, with the bits dropped
  • Block Shift Left — the same move, with the bits handed to the next value