【发布时间】:2015-09-11 12:41:55
【问题描述】:
我正在尝试创建一个函数,该函数将返回给定内存块的N 位数,并可选择跳过M 位。
例子:
unsigned char *data = malloc(3);
data[0] = 'A'; data[1] = 'B'; data[2] = 'C';
read(data, 8, 4);
会跳过 12 位,然后从数据块“ABC”中读取 8 位。
“跳过”位意味着它实际上会对整个数组进行位移,从右到左携带位。
在这个例子中ABC是
01000001 01000010 01000011
函数需要返回
0001 0100
这个问题是my previous question的后续问题
#include <ios>
#include <cmath>
#include <bitset>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
using namespace std;
typedef unsigned char byte;
typedef struct bit_data {
byte *data;
size_t length;
} bit_data;
/*
Asume skip_n_bits will be 0 >= skip_n_bits <= 8
*/
bit_data *read(size_t n_bits, size_t skip_n_bits) {
bit_data *bits = (bit_data *) malloc(sizeof(struct bit_data));
size_t bytes_to_read = ceil(n_bits / 8.0);
size_t bytes_to_read_with_skip = ceil(n_bits / 8.0) + ceil(skip_n_bits / 8.0);
bits->data = (byte *) calloc(1, bytes_to_read);
bits->length = n_bits;
/* Hardcoded for the sake of this example*/
byte *tmp = (byte *) malloc(3);
tmp[0] = 'A'; tmp[1] = 'B'; tmp[2] = 'C';
/*not working*/
if(skip_n_bits > 0){
unsigned char *tmp2 = (unsigned char *) calloc(1, bytes_to_read_with_skip);
size_t i;
for(i = bytes_to_read_with_skip - 1; i > 0; i--) {
tmp2[i] = tmp[i] << skip_n_bits;
tmp2[i - 1] = (tmp[i - 1] << skip_n_bits) | (tmp[i] >> (8 - skip_n_bits));
}
memcpy(bits->data, tmp2, bytes_to_read);
free(tmp2);
}else{
memcpy(bits->data, tmp, bytes_to_read);
}
free(tmp);
return bits;
}
int main(void) {
//Reading "ABC"
//01000001 01000010 01000011
bit_data *res = read(8, 4);
cout << bitset<8>(*res->data);
cout << " -> Should be '00010100'";
return 0;
}
当前代码返回00000000 而不是00010100。
我觉得错误很小,但我错过了。问题出在哪里?
【问题讨论】:
-
很难猜出你认为你正在完成将一个字节左移 12 位(以存储在另一个字节中)或右移负 4 位。对于任何类型的一般性,您应该将要跳过的位数划分为要跳过的多个完整字节,然后是要跳过的其他位数(零到七)。
-
另外,
size_t bytes_to_read_with_skip = ceil(n_bits / 8.0) + ceil(skip_n_bits / 8.0);中的单独 ceil 可以让您“读取”比实际需要的多一个字节。 -
@JSF 哎呀,我把问题搞砸了。我的实际代码处理
skip_n_bits > 8。让我更新一下问题。 -
@JSF 这很有趣。现在它起作用了。我想我会删除这个问题并尝试进一步调试我的代码,因为事实证明我什至不知道它在哪里失败。