Skip to content

Set Maximum

Level: 201 · for anyone with a hex editor open

One line: Set Maximum lowers every value above the operand to the operand — a ceiling, which in code is min() — so Set Maximum 0x7F as Unsigned Byte replaces every UTF-8 byte outside ASCII with DEL, and as Signed Byte changes nothing at all, because 7F is already the largest Signed Byte there is.

What the dialog does

The manual defines it in words: if X[i] is greater than the operand, X[i] is set to the operand (Hex Operations). It is Set Minimum turned over, with the same dependency: "greater than" compares numbers, and whether C3 is 195 or −61 is Treat Data As's decision.

In Python

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

1. SET MAXIMUM 7F ON café
------------------------------------------------------------------------
   café is 63 61 66 c3 a9. Set Maximum 0x7F:

     Unsigned Byte  63 61 66 7f 7f   'caf\x7f\x7f'
     Signed Byte    63 61 66 c3 a9   'café'

   As Unsigned Byte, C3 and A9 are 195 and 169, both above 127, and
   both became 7F -- DEL, twice. As Signed Byte they are -61 and -87,
   nowhere near the ceiling, and nothing changed.

2. HOW MANY BYTE VALUES IT CHANGES
------------------------------------------------------------------------
     Unsigned Byte  128 of 256
     Signed Byte      0 of 256

   0x7F is the largest Signed Byte there is. A ceiling at the top of
   the type catches nothing.

3. TWO SEVEN-BIT CLAMPS THAT DISAGREE
------------------------------------------------------------------------
   Binary And 7F also forces every byte into 00-7F. It gets there by
   dropping the top bit instead of by capping the value:

     Set Maximum 7F   63 61 66 7f 7f   'caf\x7f\x7f'
     Binary And 7F    63 61 66 43 29   'cafC)'

   Bytes the two write differently: 127 of 256 -- every byte from
   80 up except FF, whose low seven bits are already 7F.

4. A FLOOR AND A CEILING MAKE A RANGE
------------------------------------------------------------------------
   Set Minimum 0x30, then Set Maximum 0x39, pins every byte into the
   ASCII digits:

     b'Hi 42!' -> b'990420'
     the other order, b'990420'; the same for all 256 bytes: True

   Get the operands the wrong way round and the order starts to matter,
   because then there is no byte both limits allow -- the second
   operation wins:

     Set Minimum 39, then Set Maximum 30   b'000000'
     Set Maximum 30, then Set Minimum 39   b'999999'

A ceiling at 7F catches everything or nothing

Section 1 puts a ceiling of 0x7F over café. As Unsigned Byte, C3 and A9 are 195 and 169, both above 127, and both become 7F, the DEL control character. As Signed Byte they are −61 and −87, and nothing changes. Section 2 counts all 256 values: 128 change as Unsigned Byte and none as Signed Byte. That zero is not about text: 7F is the top of the signed type, so a ceiling there is a ceiling on nothing.

Two seven-bit clamps that disagree

Binary And 7F also forces every byte into 007F, and section 3 puts the two side by side: Set Maximum gives caf and two DELs, Binary And gives cafC). They write different bytes for 127 of the 256 values — every byte from 80 up except FF, whose low seven bits already are 7F. A seven-bit channel that strips the top bit behaves like the second; a validator that caps out-of-range values behaves like the first. Neither gives you the é back.

A floor and a ceiling make a range

Section 4 applies Set Minimum 0x30 and then Set Maximum 0x39, which pins every byte into the ASCII digits: Hi 42! becomes 990420. When the floor is below the ceiling, the order of the two does not matter, and the program checks all 256 bytes to show it. Swap the operands and no byte satisfies both limits, so whichever runs second wins everywhere — 000000 one way, 999999 the other — and neither run gives any sign that the range was empty.

What the manual does not say

  • Whether an operand the type cannot hold is compared as typed or after conversion to the type.
  • What Set Maximum does with a NaN on Float or Double.

If you are coming from Python or ABAP

Python. bytes(min(b, 0x7F) for b in data) is section 1's unsigned row, and bytes(b & 0x7F for b in data) is the other clamp from section 3. A range is min(max(b, lo), hi), and it inherits section 4's order question whenever lo is greater than hi.

ABAP. (Not machine-checked — CI cannot run ABAP.) The ceiling is nmin( ), and a range is the two nested: nmin( val1 = nmax( val1 = value val2 = lo ) val2 = hi ). A byte field compares only after conversion to i, which reads a one-byte field as 0 to 255 — the Unsigned Byte reading, the one in which a ceiling of 127 catches every UTF-8 byte outside ASCII.

Try it

  1. Take a copy of a UTF-8 file, select all, Set Maximum 0x7F as Unsigned Byte, and search for 7F. Every hit was a byte of a character outside ASCII.
  2. Repeat on another copy as Signed Byte and confirm nothing changed, then read one of the accented bytes in the Inspector's signed column to see why.
  3. On a third copy apply Binary And 7F instead, and compare it with the first using Tools > Compare.
  4. Pin a run of bytes to the digits with Set Minimum 0x30 then Set Maximum 0x39, then again with the operands swapped, and check which of section 4's outputs each gave.

See also