【发布时间】:2021-09-24 09:44:19
【问题描述】:
我有一个 32 位字数组,需要以不同方式连接它们。
uint32_t data[144];
在一种情况下,我需要将 36 位放在一起并用它做一些有用的事情。为此,我有以下工作代码:
// data is filled with useful bits
int lower_remainder = 0;
int upper_remainder;
uint64_t result[2];
int idx = 144;
for(int i=127; i>=0; i--) {
upper_remainder = 32-lower_remainder;
result[i%2] = (((uint64_t)data[idx-1] << upper_remainder) | (data[idx] >> lower_remainder)) & 0xFFFFFFFFF; // Note mask 0xFFFFFFFFF has 9! F's to get 36 bits
idx--;
lower_remainder += 4;
if(lower_remainder == 32) {
lower_remainder = 0;
idx--;
}
if(i%2 == 0) {
// Do something with result
}
}
同样,上面的代码运行良好。
在另一种情况下,我需要将 39 位放在一起。所以我尝试了许多不同的方法来使上面的代码通用,但我在这里失败了。主要是因为我得到:
(data[143] << 32 | data[144] >> 0) | 0x7FFFFFFFFF; // 0x7FFFFFFFFF mask for 39 bits
(data[142] << 25 | data[143] >> 7) | 0x7FFFFFFFFF;
(data[141] << 18 | data[142] >> 14) | 0x7FFFFFFFFF;
(data[140] << 11 | data[141] >> 21) | 0x7FFFFFFFFF;
下一个一定是这样的
// 3 bits 32 bits 4bits
(data[138] << 36 | data[139] << 4 | data[140] >> 28) | 0x7FFFFFFFFF;
所以现在必须从 3 个字段中获取数据。我能够为一个案例开发代码,但每次尝试使其通用化都行不通。我还有其他情况,例如需要 72 位(为此我需要 uint64_t 以外的其他东西来存储每个数据......)。
感谢任何帮助/提示/链接。
谢谢, 阿米尔
PS> 我对 data[0] 不感兴趣,因此像上面的代码一样跳过它。
【问题讨论】:
-
是否准确描述了问题的要点:“一般提取打包到 32 位 uint 数组中的 X 位值?,其中 X 可以是 36、39 或 72”?
-
如果
diag(如data)是uint32_t的数组,那么像diag[143] << 32和diag[138] << 36这样的表达式可能会失败。您需要对uint64_t进行初步转换(实际上您在工作代码中已经有了):(uint64_t)diag[143] << 32等。 -
我的意思是写数据而不是诊断,我的错,我把它改成了数据。但是,是的,我正在为 64 岁做演员。
-
您想一次从数组 36 中获取,或者您想访问数组,就好像它是一个元素数组,每个元素都有 36 位?即你想要
give_me_next_n_bits(void *data, unsigned bitcount)还是你想要access(void *data, size_t elemidx)?你打算写一个比特流式的库吗?你是从 LSB 还是 MSB 开始计算位?
标签: c algorithm bitwise-operators