5

所以我有3个数字。一个是 a char,另外两个是int16_t(也称为shorts,但根据表格我发现短裤不会可靠地为 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;

这里发生了什么?我怀疑它与 a 的大小有关long long,但我无法完全理解它,我希望以后有更多的数字空间。

4

4 回答 4

12

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

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

这将产生您请求的确切位模式,在 lsb 端左 0 的 24 位:

1001000111111111111111011001011010110101000000000000000000000000
于 2012-11-04T21:16:10.573 回答
3

对于最后一个移位,您应该只移位 16,而不是 24。24 是二进制字符串的当前长度,在 num1 和 num2 的组合之后。您需要为 16 位的 num3 腾出空间,因此左移 16。

编辑:

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

于 2012-11-04T20:13:20.890 回答
1

是的,您溢出了可以长存储的值。您可以使用任意精度库来存储大数字,例如GMP

于 2012-11-04T20:13:51.533 回答
1

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

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

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

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

我已经测试了上面的代码。long long 对于 g++ 编译器的这项任务来说已经足够宽了,我相信还有很多其他的。

于 2012-11-04T20:41:21.000 回答