Home > Back-end >  Split multiple bytes according to bit masks
Split multiple bytes according to bit masks

Time:12-15

I'm trying to split bytes according to bit masks.

Consider these two bytes (1000 in binary as short int):

11101000

00000011

and these three masks:

00000011

11111111

00111111

What I want to do is to split the two original bytes in three bytes according to the masks provided.

The result should be:

00000000 for the first byte

11111010 for the second (original byte 1 and 2 are merged because of the mask)

00000000 for the third (remaining bits are filled with zeros)

What is the easiest way to do it in Java or C?

CodePudding user response:

In C if using x86, this is a single pdep operation.

#include <immintrin.h>

int msk(int num) {
    int src =  0b0000001111101000;
    int mask = 0b001111111111111100000011;

    int result = _pdep_u32(src,mask);

    int expected_result = 0b000000001111101000000000;

    if (result == expected_result) {
        return 1; // returns this
    } else {
        return 0;
    }
}

See _pdep_u32 in Intel Intrinsic Guide.

https://godbolt.org/z/b6E6M8518


If your inputs/output are arrays of exactly 4 bytes, you can just memcpy from array to int and back.

If you're targeting not only x86, targeting older x86 that don't have BMI2, or want Java solution, you'll have to implement this algorithm from PDEP documentation:

tmp := a
dst := 0
m := 0
k := 0
DO WHILE m < 32
    IF mask[m] == 1
        dst[m] := tmp[k]
        k := k   1
    FI
    m := m   1
OD

dst[m] or tmp[k] can be accomplished with array indexing and bit shifts, specifically dst[m] := tmp[k] is (assuming 8-bit byte):

unsigned char bit = (dst[k/8] >> (k%8)) & 1;
dst[m/8] |= bit << (m%8)

Note that the direct implementation is not only a bit more complex, it is also less efficient, as pdep is a single CPU instruction. But I'm not sure if Java exposes it, and if not, then if using JNI to call C implementation is worth doing.

  • Related