in reply to Making all nibble zero lower than the offset

If this is to be done repeatedly, I'd go with a lookup table. The table could be built dynamically (e.g. by using the code from the other answers in a loop), but it's probably not worth the effort.

my @mask_by_offset = ( ( ~0x0000_000F ) x 4, ( ~0x0000_00FF ) x 4, ( ~0x0000_0FFF ) x 4, ( ~0x0000_FFFF ) x 4, ( ~0x000F_FFFF ) x 4, ( ~0x00FF_FFFF ) x 4, ( ~0x0FFF_FFFF ) x 4, ( ~0xFFFF_FFFF ) x 4, ); $val &= $mask_by_offset[$offset];

The mask are defined in terms of the bits to keep to work with 32-bit ints and 64-bit ints.