Skip to content

Rotate Right

Level: 201 · for anyone with a hex editor open

One line: Rotate Right feeds the bits that fall off the bottom of a value back in at the top, so Rotate Right 1 turns 01 into 80 — +1 into −128 without any arithmetic — Rotate Right n is Rotate Left by the width minus n, and the Endian toggle cannot change a Short's rotation but can change an Int's.

What the dialog does

The manual describes it by comparison: like Shift Right, except that what is shifted off X[i] is added back on its left side (Hex Operations). It is Rotate Left going the other way round the same circle, and everything that page says about nothing being lost holds here.

In Python

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

1. THE BIT THAT FALLS OFF THE BOTTOM LANDS ON TOP
------------------------------------------------------------------------
     01 rotated right by 1   80   10000000

   Read back, that is 128 as an Unsigned Byte and -128 as a Signed
   one. The only 1 in the byte became the sign bit, and a value that
   was +1 is now the most negative the type can hold, without any
   arithmetic having happened.

2. ROTATE RIGHT N IS ROTATE LEFT BY THE WIDTH MINUS N
------------------------------------------------------------------------
     all 256 bytes, every count 0-7                  True
     all 65,536 Unsigned Shorts, counts 1, 4, 8, 12  True

   So a dialog needs only one of the two. Rotate Right 4 on a byte is
   Rotate Left 4, the swap of its hex digits, from the other side.

3. ON A SHORT THE ENDIAN TOGGLE CANNOT CHANGE A ROTATION, ON AN INT IT CAN
------------------------------------------------------------------------
     every Unsigned Short, every count 0-15, little == big   True
     12 34 56 78 as an Unsigned Int, Rotate Right 8:
       little   34 56 78 12
       big      78 12 34 56

   Reading a Short the other way round swaps its two bytes, and that is
   itself a rotation by 8. Rotations of the same width can be done in
   either order, so the toggle cannot change the result. Reversing four
   bytes is not a rotation of 32 bits, so on an Int it can.

The bottom bit becomes the sign

Section 1 rotates 01 right by 1. The only 1 in the byte falls off the bottom and lands on top, and 80 is 128 as an Unsigned Byte and −128 as a Signed one. The value went from +1 to the most negative number the type can hold and nothing was added, subtracted or multiplied: the top bit of a signed value is its sign, and a rotation will put any bit there.

One rotation is enough

Section 2 checks that Rotate Right n writes what Rotate Left by the width minus n writes — all 256 bytes for every count, and all 65,536 Unsigned Shorts for four counts. Going round a circle of eight positions by 3 one way is going round it by 5 the other. That is also why Rotate Right 4 on a byte is the same hex-digit swap as Rotate Left 4.

The Endian toggle and a rotation

Section 3 is the finding the chapter table flagged. On an Unsigned Short, Little and Big Endian write the same bytes for every value and every count from 0 to 15. On an Unsigned Int they do not: 12 34 56 78 rotated right by 8 is 34 56 78 12 read little-endian and 78 12 34 56 read big-endian.

The reason is short. Reading a Short in the other byte order swaps its two bytes, and swapping a Short's bytes is itself a rotation by 8, which is why Swap Bytes and Rotate Left 8 agree. Two rotations of the same width give the same result in either order, so a rotation cannot tell which way the Short was read. Reversing four bytes is not a rotation of 32 bits — no amount of rotating 12 34 56 78 gives 78 56 34 12 — so an Int's rotation can tell, and the toggle matters again.

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.
  • Whether Rotate Right 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 Right as Unsigned Byte; section 3's Short check uses the same expression with 16. Python's integers have no width, so the & 0xFF is not tidiness — without it the bits shifted up by 8 - n are never dropped.

ABAP. (Not machine-checked — CI cannot run ABAP.) With no bit operator that moves a bit ↗, a rotation is a loop of GET BIT and SET BIT over a byte field, whose positions run from the start of the field ↗. On an x field there is no Endian toggle to worry about; the toggle only enters once the field is converted to an integer, and that conversion is always big-endian ↗.

Try it

  1. Type 01, Rotate Right 1 as Signed Byte, and read the Inspector's signed value before and after.
  2. On two copies of a range, Rotate Right 3 one and Rotate Left 5 the other, and compare them with Tools > Compare.
  3. Type 12 34 56 78, Rotate Right 8 as Unsigned Int under each Endian setting, and compare with section 3.
  4. Type 12 34, Rotate Right by any count as Unsigned Short under each Endian setting, and confirm the toggle changes nothing.

See also