通过数组移动比特流 [英] move bits stream through an array

查看:76
本文介绍了通过数组移动比特流的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好,


联盟UC32 {

unsigned int L;

unsigned short S [2];

unsigned char C [4];

} UC32;


具有上述结构,我能够移位C [ 0],进入C [1],

和C [1]进入C [2]等等,直到C [3],因为它们是联合编辑

with unsigned int L.


然而,问题来自于我需要的原始数据类型

可以处理,让我们说10个字节。


我的尝试是:


unsigned char ar [10];

unsigned temp;


签名char i,j;


for(i = 9; i> 0; i - )

{


if(ar [i-1]& 0x80)

{

ar [i] = ar [i]<< 1 | 0x01;

}

else

ar [i] = ar [i]<< 1;


}


ar [0] = ar [0]<< 1;


我不太喜欢这种方法。所有评论和建议都是

欢迎。


谢谢

vib

Hi there,

union UC32 {
unsigned int L;
unsigned short S[2];
unsigned char C[4];
} UC32;

with the above structure, I am able to shift bits of C[0], into C[1],
and C[1] into C[2] so on and so forth till C[3] as they are "union"ed
with unsigned int L.

However, the problem comes when I need more than the primitive datatype
can handle, let''s say as 10 bytes.

my attempt is:

unsigned char ar[10];
unsigned temp;

signed char i, j;

for (i = 9; i > 0; i --)
{

if ( ar[i-1] & 0x80)
{
ar[i] = ar[i] << 1 | 0x01;
}
else
ar[i] = ar[i] << 1;

}

ar[0] = ar[0] << 1;

i don''t quite like this approach. All comments and suggests are
welcome.

Thanks
vib

推荐答案

在文章< 11 ********************* @ z14g2000cwz.googlegroups中。 com>,

vib< vi ***** @ gmail.com>写道:
In article <11*********************@z14g2000cwz.googlegroups. com>,
vib <vi*****@gmail.com> wrote:
我的尝试是:
unsigned char ar [10];
unsigned temp;
签名char i,j;
for(i = 9; i> 0; i - )
{
if(ar [i-1]& 0x80)

ar [i] = ar [i]<< 1 | 0x01;
}
其他
ar [i] = ar [i]<< 1;

}
ar [0] = ar [0]<< 1;
my attempt is: unsigned char ar[10];
unsigned temp; signed char i, j; for (i = 9; i > 0; i --)
{ if ( ar[i-1] & 0x80)
{
ar[i] = ar[i] << 1 | 0x01;
}
else
ar[i] = ar[i] << 1;

} ar[0] = ar[0] << 1;




这可以缩短一点:而且,你正在改错方式

并将错误的位移到错误位置地方。

你显示的循环更接近于向另一个方向移动

(但仍然是错误的......对于左移,你必须开始你的

循环为0,你必须看ar [i + 1]而不是ar [i-1]。)

循环可以是:


for(i = sizeof(ar) - 1; i> 0; i--)

ar [i] =(ar [i]>> 1 )| ((ar [i-1]& 1)<<(CHAR_BIT-1));

ar [0]>> = 1;

它也可以稍微优化一下:


#define ARagTYPE long / *如果你的编译器支持* /

#define ARSIZE 10

#define ARLSIZE((ARSIZE + sizeof ARagTYPE - 1)/ sizeof ARagTYPE)

typedef union {

unsigned char ar_c [ARSIZE];

无符号ARagTYPE ar_l [ARLSIZE];

} ar_u;


ar_u ar;


unsigned char i;


initialize_ar(& ar); / *初始化ar为某些东西* /


for(i = ARLSIZE - 1; i> 0; i--)

ar_l [i] = (ar_l [i]>> 1)| ((ar_l [i-1]& 1)<<(CHAR_BIT-1));

ar_l [0]>> 1;


现在你要问自己的问题是:当你转换为

a时,你确定你正在将正确的位移到

正确的地方?假设长时间内字节顺序是3412 ...


-

研究表明普通读者忽略了所有统计数据的106%
他们在.signatures中看到



This can be shortened a bit: also, you are shifting the wrong way
and shifting in the wrong bit into the wrong place.
The loop you show is much closer to shifting in the other direction
(but still wrong for that.. for a left shift, you have to start your
loop at 0 and you have to look at ar[i+1] not at ar[i-1] .)
The loop can be:

for (i = sizeof(ar) - 1; i > 0; i-- )
ar[i] = (ar[i] >> 1) | ((ar[i-1] & 1) << (CHAR_BIT-1));
ar[0] >>= 1;
It can also be optimized a bit:

#define ARagTYPE long /* could be long long if your compiler supports that */
#define ARSIZE 10
#define ARLSIZE ((ARSIZE + sizeof ARagTYPE - 1) / sizeof ARagTYPE)
typedef union {
unsigned char ar_c[ARSIZE];
unsigned ARagTYPE ar_l[ARLSIZE];
} ar_u;

ar_u ar;

unsigned char i;

initialize_ar(&ar); /* initialize ar to something */

for (i = ARLSIZE - 1; i > 0; i-- )
ar_l[i] = (ar_l[i] >> 1) | ((ar_l[i-1] & 1) << (CHAR_BIT-1));
ar_l[0] >> 1;

Now the question you have to ask yourself is: when you shift as
a long, are you certain you are shifting the right bits into the
right place? Suppose the byte order is 3412 within a long...

--
Studies show that the average reader ignores 106% of all statistics
they see in .signatures.




" vib" < 6 ***** @ gmail.com>写了

"vib" <vi*****@gmail.com> wrote
union UC32 {
unsigned int L;
unsigned short S [2];
unsigned char C [4];
} UC32; <用上面的结构,我能够将C [0]的位,C [1],
和C [1]转换成C [2]等等,直到C [3]因为它们是联合,而且是带有unsigned int L。
union UC32 {
unsigned int L;
unsigned short S[2];
unsigned char C[4];
} UC32;

with the above structure, I am able to shift bits of C[0], into C[1],
and C[1] into C[2] so on and so forth till C[3] as they are "union"ed
with unsigned int L.



不要使用工会来玩具有位表示的游戏。如果编译器使用一个有趣的

策略来分配成员,那么它不是可移植的,并且可能无法正常工作。它也严格地说是未定义的

将数据写入一个联盟成员并从另一个联盟成员读取的行为。


尝试此策略(未经测试的代码)


typedef struct

{

unsigned char * data;

int pos;

int mask;

} BITSTREAM;


BITSTREAM * bitstream(void * ptr)

{

BITSTREAM * answer = malloc(sizeof(BITSTREAM));

if(answer)

{

answer-> data = ptr;

answer-> pos = 0;

answer-> mask = 1;

}

返回答案;

}


int getbit(BITSTREAM * bs)

{

int answer =(bs-> data [bs-> pos]& bs-> mask)? 1:0;

bs-> mask<< = 1;

if(bs-> mask == 0x0100)

{

bs-> mask = 1;

bs-> pos ++;

}

return回答;

}


/ *

这个可以通过一次访问几个位来优化。

可能不值得。

* /

unsigned long getbits(BISTREAM * bs,int N)

{

unsigned long answer = 0;

while(N--)

{

answer<< = 1 ;

回答| = getbit(bs);

}


返回答案;

}


Don''t use unions for playing games with bit representations. It isn''t
portable and may not work as you expect if the compiler uses a funny
strategy for allocating members. It is also strictly speaking undefined
behaviour to write data to one union member and read it from another.

Try this strategy (untested code)

typedef struct
{
unsigned char *data;
int pos;
int mask;
} BITSTREAM;

BITSTREAM *bitstream(void *ptr)
{
BITSTREAM *answer = malloc(sizeof(BITSTREAM));
if(answer)
{
answer->data = ptr;
answer->pos = 0;
answer->mask = 1;
}
return answer;
}

int getbit(BITSTREAM *bs)
{
int answer = (bs->data[bs->pos] & bs->mask) ? 1 : 0;
bs->mask <<= 1;
if(bs->mask == 0x0100)
{
bs->mask = 1;
bs->pos++;
}
return answer;
}

/*
this one can be optimised by accessing several bits at a time.
May not be worth while.
*/
unsigned long getbits(BISTREAM *bs, int N)
{
unsigned long answer = 0;
while(N--)
{
answer <<= 1;
answer |= getbit(bs);
}

return answer;
}


感谢Walter,


获取新数据并附加到ar [0],通过移位到了剩下的

,并且在数组中的特定

位置进行了模式匹配操作,ar [],我能够扫描传入的位

很容易流。这就像从右到左运行

位一样观察和匹配模式。


测试你的代码,很棒。然而,因为我在嵌入式

系统中使用它,哪些资源始终是一个问题。我决定不使用OR

(CHAR_BIT-1)。相反,我使用if确定最重要的

位右边的字节是非零或零,并采取相应的行动。


另外你的第二个建议,它也很棒。我一直想着

。但是,任何大于byte的内容都必须使用数据类型的字节顺序处理

。对于性能敏感的嵌入式系统来说,这太令人头疼了,而且b $ b。因此,我选择使用字节数组来支付



非常感谢。

Thanks Walter,

The new data is obtained and append at the ar[0], By shifting to the
left , and having a pattern matching operation at the specific
locations in the array, ar[], I am able to scan the incoming bits
stream easily. It is like watching and matching a pattern at a running
bits from right to left.

Tested your code, it is great. However as i am using it in embedded
system which resources are always a concern. I decide not to use OR
with (CHAR_BIT-1). Instead, I use if to determine the most signficant
bit of the byte on the right is nonzero or zero and act accordingly.

Also ur on second suggestion, it is great too. I was thinking along
that as well. However, having anything larger than byte has to deal
with the byte order of the datatype. It is too much a headache, as well
as for the performance sensitive embedded system. Hence, I chose to
stay by using the byte array.

Many thanks.

这篇关于通过数组移动比特流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆