我们有 2 个字符 a
和 b,共 8
位,我们希望将其编码为 10 位集。我们想要做的是将字符 a
的前 8
位放入 10 位集的前 8 位中。然后仅取字符 b
的前 2
位并填充其余部分。
问题:我是否需要移动 8 位才能连接其他 2 位?
// Online C++ compiler to run C++ program online
#include <iostream>
#include <bitset>
struct uint10_t {
uint16_t value : 10;
uint16_t _ : 6;
};
uint10_t hash(char a, char b){
uint10_t hashed;
// Concatenate 2 bits to the other 8
hashed.value = (a << 8) + (b & 11000000);
return hashed;
}
int main() {
uint10_t hashed = hash('a', 'b');
std::bitset<10> newVal = hashed.value;
std::cout << newVal << " "<<hashed .value << std::endl;
return 0;
}
最佳答案
Do I need to shift the 8 bits in order to concatenate the other 2?
是的。
a
的位必须向左移动,为 b
的两位腾出空间。由于需要两位的空间,因此左移 2 是合适的。 (在我最近的更新之前,有一个错误的左移 8,我没有注意到。我真丢脸。)
b
的位必须向右移动。原因是OP想要组合b
的两个最高有效位。和他们一起a
。由于这两个位必须在结果中显示为最低有效位,因此它们必须移动到该位置。
应该是:
hashed.value = (a << 2) + ((b & 0xc0) >> 6);
或
hashed.value = (a << 2) + ((b & 0b11000000) >> 6);
如b
类型为char
(有符号或无符号取决于编译器),最好交换 &
的顺序。和>>
:
hashed.value = (a << 2) + ((b >> 6) & 0x03);
或
hashed.value = (a << 2) + ((b >> 6) & 0b11);
这可以确保消除任何可能的符号位扩展,如果类型char
可能会发生这种情况。是特定编译器中的有符号类型,并且 b
具有负值(即设置最高有效位并将在转换为 int
时复制)。
#include <iostream>
#include <bitset>
struct uint10_t {
uint16_t value : 10;
uint16_t _ : 6;
};
uint10_t hash(char a, char b){
uint10_t hashed;
// Concatenate 2 bits to the other 8
hashed.value = (a << 2) + ((b >> 6) & 0b11);
return hashed;
}
int main() {
uint10_t hashed = hash('a', 'b');
std::cout << "a: " << std::bitset<8>('a') << '\n';
std::cout << "b: " << std::bitset<8>('b') << '\n';
std::bitset<10> newVal = hashed.value;
std::cout << " " << newVal << " " << hashed.value << std::endl;
}
输出:
a: 01100001
b: 01100010
0110000101 389
有人可能想知道为什么 a
的两个高位虽然a
并没有丢失类型为char
通常是 8 位类型。原因是积分算术运算至少在 int
上有效。类型。因此,a << 2
涉及 a
的隐式转换至int
至少有 16 位。
关于c++ - 从两个 8 位字符创建并填充 10 位集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71885147/