连接不同长度的二进制数

时间:2012-11-04 20:07:39

标签: c++ bit-manipulation

所以我有3个号码。一个是char,另外两个是int16_t(也称为short s,但根据表格,我发现短路不会可靠地为16位)。

我想将它们连接在一起。所以说它们的价值是:

10010001

1111111111111101

1001011010110101

我想最终得到一个long long包含:

1001000111111111111111011001011010110101000000000000000000000000

使用我在网上找到的一些解决方案,我想出了这个:

long long result;
result = num1;
result = (result << 8) | num2;
result = (result << 24) | num3;

但它不起作用;当它被解码时,它给了我非常奇怪的数字。

如果我的解码代码有问题,请点击:

char num1 = num & 0xff;
int16_t num2 = num << 8 & 0xffff;
int16_t num3 = num << 24 & 0xffff;

这里发生了什么?我怀疑它与long long的大小有关,但我无法完全绕过它,我想在以后有更多数字的空间。

4 个答案:

答案 0 :(得分:9)

要根据您的要求获得正确的位模式,您应该使用:

result = num1;
result = (result << 16) | num2;
result = (result << 16) | num3; 
result<<=24;

这将产生您请求的确切位模式,在lsb处为24位 - 并且左侧为0:

1001000111111111111111011001011010110101000000000000000000000000

答案 1 :(得分:3)

对于最后一个班次,你应该只移动16而不是24. 24是num1和num2组合后二进制字符串的当前长度。你需要为num3腾出空间,这是16位,所以向左移动16。

修改

刚刚意识到第一个转变也是错误的。出于类似的原因,这也应该是16。

答案 2 :(得分:1)

是的,你正在溢出可以长期存储的值。您可以使用任意的精确库来存储像GMP这样的大号。

答案 3 :(得分:0)

如果我理解你在做什么,我会使用:

result = num1;
result = (result << 16) | num2;
result = (result << 16) | num3;

num1out = (result >> 32) & 0xff;
num2out = (result >> 16) & 0xffff;
num3out = result & 0xffff;

构建期间的左移是要插入的下一个数字的宽度。提取时的右移是指在建筑过程中场被移动的总位数。

我已经测试了上面的代码。使用g ++编译器,这个任务的长期足够宽,我相信很多其他人。