Block Shift Left¶
Level: 201 · for anyone with a hex editor open
One line: Block Shift Left shifts the whole range as one long number, so the bits that pass the top of one value enter the value before it instead of falling off — which makes Block Shift Left 4 delete the first hex digit of an Unsigned Byte range and Block Shift Left 8 delete its first byte, without the range changing size.
What the dialog does¶
The manual describes it by comparison: like Shift Left, except that the data "is treated as one long block", with what is shifted off X[i+1] shifted onto X[i] (Hex Operations ↗). It is the one operation in the list where a value's neighbours matter: every other one could be done to each value on its own. Only the first value's top bits leave the range, and zeros enter at the end of the last value.
In Python¶
Verified output of block_shift_left_py.py — regenerated by tools/run_examples.py, never hand-typed.
1. ONE LONG NUMBER INSTEAD OF MANY SHORT ONES
------------------------------------------------------------------------
12 34 56 as Unsigned Byte, shifted left by 4:
Shift Left 4 20 40 60 each byte on its own
Block Shift Left 4 23 45 60 the three bytes as one number
Shift Left lost the top digit of every byte. Block Shift Left lost
only the first, and the others moved into the byte before theirs.
2. BLOCK SHIFT LEFT 4 DELETES A HEX DIGIT
------------------------------------------------------------------------
Block Shift Left 4 123456 -> 234560
Block Shift Left 8 123456 -> 345600
Block Shift Left 12 123456 -> 456000
Four bits is one hex digit, so each 4 deletes the first digit of the
range and appends a 0; eight deletes a whole byte. The range keeps
its size, which a real delete would not.
3. NOTHING COMES BACK
------------------------------------------------------------------------
12 34 56 Block Shift Left 4 -> 23 45 60
23 45 60 Block Shift Right 4 -> 02 34 56
The 1 that left the range is gone, and a 0 came in to replace it.
A Rotate would have kept it.
4. ON A LITTLE-ENDIAN SHORT, THE SENTENCE HAS TWO READINGS
------------------------------------------------------------------------
The manual says bytes shifted off X[i+1] are shifted onto X[i]. For
one-byte values that settles everything. For wider ones there are two
ways to lay the values end to end, and they agree only on big-endian:
Unsigned Short, big 12 34 56 78
the values in order, each high bit first 23 45 67 80
the file's bytes as they lie 23 45 67 80
Unsigned Short, little 34 12 78 56
the values in order, each high bit first 45 23 80 67
the file's bytes as they lie 41 27 85 60
The first reading follows the manual's X[i] wording, and it is the
one this program's Block Shift uses. Which one the dialog uses on a
little-endian Short has not been measured here.
One long number¶
Section 1 shifts 12 34 56 left by 4 as Unsigned Byte, both ways. Shift Left treats each byte on its own, drops the top digit of each, and writes 20 40 60. Block Shift Left treats the three bytes as the number 0x123456, drops only its first digit, and writes 23 45 60: each byte's top digit moved into the byte before it.
Block Shift Left 4 deletes a hex digit¶
Four bits is one hex digit, so section 2 is the operation as it looks in the hex column: each 4 deletes the first digit of the range and appends a 0, and 8 deletes a whole byte — 12 34 56 becomes 34 56 00. It is a delete that keeps the range's size, which a real delete would not, and it is a way to fix a range whose digits all sit one place too far to the right.
Section 3 shows the price. Block Shift Left 4 and then Block Shift Right 4 gives 02 34 56, not 12 34 56: the 1 that left the range is gone, and nothing can bring it back. Rotate Left is the operation that keeps it.
Two readings on a little-endian Short¶
For one-byte values the manual's sentence settles everything, because a byte has no internal order. For wider values there are two ways to lay the values end to end, and section 4 prints both. Reading the sentence literally — X[i+1]'s top bits shifted onto X[i] — the block is the values in order, each written high bit first, and the program uses that reading. The other is the file's bytes as they lie. The two agree on a big-endian Short, where the values' high bytes come first in the file anyway, and disagree on a little-endian one: 45 23 80 67 against 41 27 85 60 for the same 34 12 78 56. The page does not know which one the dialog uses; the third item under Try it does.
What the manual does not say¶
- Which reading of section 4 the dialog uses on a type wider than a byte in a little-endian file.
- What a count as large as the whole range, or larger, does.
If you are coming from Python or ABAP¶
Python. A block shift is the one operation here that Python's unbounded integers make easier: ((int.from_bytes(data, 'big') << n) & ((1 << 8 * len(data)) - 1)).to_bytes(len(data), 'big') is Block Shift Left over any range of Unsigned Bytes, in one expression, with the mask supplying the range's fixed size.
ABAP. (Not machine-checked — CI cannot run ABAP.) For whole bytes there is a statement: SHIFT hex BY n PLACES LEFT IN BYTE MODE moves a byte field's content left, and fills the places it frees in a field of fixed length with hexadecimal 0 ↗ — Block Shift Left by 8n on a range of Unsigned Bytes. An xstring is the exception: the same statement shortens it, which is a real delete. For a count that is not a multiple of eight there are GET BIT and SET BIT, whose positions run from the beginning of the field ↗ in the order this operation moves bits, and neither has a byte order to choose.
Try it¶
- Type
12 34 56, Block Shift Left 4 as Unsigned Byte, undo, and Shift Left 4. Compare both results with section 1. - In a copy of a file, select a range and Block Shift Left 8. Check that the first byte has gone, a
00has arrived at the end, and the file is still the same size. - Type
34 12 78 56, set Treat Data As to Unsigned Short and Endian to Little, Block Shift Left 4, and find out which of section 4's two readings the dialog wrote. - Block Shift Left 4 and then Block Shift Right 4, and find the digit that did not come back.
See also¶
- Block Shift Right — the same long number, moved the other way
- Shift Left — the bits that fall off each value on its own
- Rotate Left — the shift that keeps what falls off
- The bytes do not say which end — why a little-endian Short has two readings here