根据位掩码拆分多个字节
Split multiple bytes according to bit masks
我正在尝试根据位掩码拆分字节。
考虑这两个字节(二进制中的 1000 为 short int):
11101000
00000011
以及这三个面具:
00000011
11111111
00111111
我想做的是把原来的两个字节按照提供的掩码拆分成三个字节
结果应该是:
00000000
第一个字节
11111010
第二个(原始字节1和2因为掩码而合并)
00000000
第三个(其余位用零填充)
用 Java 或 C 最简单的方法是什么?
在 C 中,如果使用 x86,这是单个 pdep
操作。
#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;
}
}
参见 _pdep_u32 in Intel Intrinsic Guide。
https://godbolt.org/z/b6E6M8518
如果您的 inputs/output 是恰好 4 个字节的数组,您可以 memcpy
从数组到 int
并返回。
如果您不仅针对 x86,还针对没有 BMI2 的旧 x86,或者想要 Java 解决方案,则必须从 PDEP 文档实施此算法:
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]
或 tmp[k]
可以通过数组索引和位移来完成,具体 dst[m] := tmp[k]
是(假设 8 位字节):
unsigned char bit = (dst[k/8] >> (k%8)) & 1;
dst[m/8] |= bit << (m%8)
请注意,直接实现不仅有点复杂,而且效率也较低,因为 pdep
是单个 CPU 指令。但是我不确定 Java 是否公开它,如果没有,那么使用 JNI 调用 C 实现是否值得。
我正在尝试根据位掩码拆分字节。
考虑这两个字节(二进制中的 1000 为 short int):
11101000
00000011
以及这三个面具:
00000011
11111111
00111111
我想做的是把原来的两个字节按照提供的掩码拆分成三个字节
结果应该是:
00000000
第一个字节
11111010
第二个(原始字节1和2因为掩码而合并)
00000000
第三个(其余位用零填充)
用 Java 或 C 最简单的方法是什么?
在 C 中,如果使用 x86,这是单个 pdep
操作。
#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;
}
}
参见 _pdep_u32 in Intel Intrinsic Guide。
https://godbolt.org/z/b6E6M8518
如果您的 inputs/output 是恰好 4 个字节的数组,您可以 memcpy
从数组到 int
并返回。
如果您不仅针对 x86,还针对没有 BMI2 的旧 x86,或者想要 Java 解决方案,则必须从 PDEP 文档实施此算法:
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]
或 tmp[k]
可以通过数组索引和位移来完成,具体 dst[m] := tmp[k]
是(假设 8 位字节):
unsigned char bit = (dst[k/8] >> (k%8)) & 1;
dst[m/8] |= bit << (m%8)
请注意,直接实现不仅有点复杂,而且效率也较低,因为 pdep
是单个 CPU 指令。但是我不确定 Java 是否公开它,如果没有,那么使用 JNI 调用 C 实现是否值得。