473,383 Members | 1,877 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,383 software developers and data experts.

move bits stream through an array

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

Nov 14 '05 #1
14 2557
In article <11*********************@z14g2000cwz.googlegroups. com>,
vib <vi*****@gmail.com> wrote:
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;


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.
Nov 14 '05 #2

"vib" <vi*****@gmail.com> wrote
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.

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;
}

Nov 14 '05 #3
vib
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.

Nov 14 '05 #4
vib
Hi Walter,
On second thought, I think right-shifting makes more sense as it would
be easier when doing memcmp.

Thanks

Nov 14 '05 #5
vib
Hi Malcom,

What is brilliant approach for replacing union. To make it advances to
next byte, I 've make the following changes:

if(bs->mask == 0x0100)
{
bs->mask = 1;
bs->pos++;
bs->data++;
}

Thanks

Nov 14 '05 #6
"vib" <vi*****@gmail.com> writes:
[...]
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.

[...]

I haven't been following this discussion closely, but based on your
description, I'm skeptical that what you describe is going to be more
efficient.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #7
vib
Are you refering to the statement, "I decide not to use OR with
(CHAR_BIT-1). "? Just think that shifting (CHAR_BIT -1) bits to the
left is less efficient comparing to an if instruction.

Nov 14 '05 #8
"vib" <vi*****@gmail.com> writes:
Are you refering to the statement, "I decide not to use OR with
(CHAR_BIT-1). "? Just think that shifting (CHAR_BIT -1) bits to the
left is less efficient comparing to an if instruction.


That depends on the system. The C language has nothing to say about
the relative efficiency of various constructs. On some systems,
conditonal branches can mess up pipelining; a shift might be executed
in a single clock cycle. The only way to be sure is to measure.

Remember the Rules of Optimization:

Rule 1: Don't do it.
Rule 2: Don't do it yet (experts only).

The best approach is usually to code as clearly as possible and use
good algorithms (don't bother fine-tuning a bubblesort). Once you've
done that, profile your code and find out where the bottlenecks are.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #9
vib
well noted. Thanks.

Nov 14 '05 #10
In article <11**********************@z14g2000cwz.googlegroups .com>,
vib <vi*****@gmail.com> wrote:
Are you refering to the statement, "I decide not to use OR with
(CHAR_BIT-1). "? Just think that shifting (CHAR_BIT -1) bits to the
left is less efficient comparing to an if instruction.


You can precalculate the value 1 << (CHAR_BIT-1)
and multiply (ar[i-1] & 1) by that precalulated value.

That would transform the code from a "shift by a known factor of
an unknown bit value" into a "multiply an unknown bit by a constant
value".

Your code needs CHAR_BIT if it is to be portable. You should not
be assuming 8 bits per unsigned char.

Another approach would be to | in (ar[i-1] & 1) ? 1 << (CHAR_BIT-1) : 0
The 1 << (CHAR_BIT-1) will be computed at compile time .
This trades the multiply (or shift) into a conditional computation.
On some systems a ?: construct with constants for both potential
results can be done -quite- efficiently, but on other systems it
requires a full conditional branch that messes up pipelining and
so on.
On systems (e.g., MIPS R10000 chips) that have the
"move conditional" instruction, the ?: approach would be most efficient.

On many systems, most efficient would be the shifting of the bit
by (CHAR_BIT-1) -- but there are some important CPUs that have no
"barrel shifter" that can do it in one step, and there are some
CPUs on which there is an effecient shift in one direction but not the
other, so the efficiency of shifts should not be taken for granted.

On systems without an efficient shift instruction, the version
using the integer multiply by a constant might be the most efficient,
but this is not certain either... some systems do integer multiplies
quite efficiently, others only do floating point multiplies efficiently.

On a fair number of CPUs, if/then/else is the least efficient choice.
But even that is quite variable, even within the same machine:
if the instructions are all in primary cache the if/then/else
might be pretty efficient, but if the instructions are not in
primary cache then the if/then/else might come out as the slowest...
Still, it's a good rule of thumb that a conditional
branch ( ?: or if/then/else ) will -likely- be slower than
using short code that can compute the value without using a branch.
--
Warning: potentially contains traces of nuts.
Nov 14 '05 #11
"vib" <vi*****@gmail.com> writes:
well noted. Thanks.


What is? Please provide some context when posting a followup.

If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #12
vib
Thanks Walter. Your explanations are indeed helpful.

Nov 14 '05 #13
vib
If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers.

thanks, this really solves my problems.

Nov 14 '05 #14
"vib" <vi*****@gmail.com> writes:
If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers.

thanks, this really solves my problems.


Glad to hear it. One more thing: please don't snip attributions (such
as the
"vib" <vi*****@gmail.com> writes:
line above). I think Google adds attribution lines if you use the
proper "Reply" button.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Ken | last post by:
I need to convert 32 bit Windows bitmaps to jpgs with PHP. I used the function from http://groups.google.com/groups? hl=en&lr=&ie=UTF-8&oe=UTF-8&safe=off&selm=a164f4b5.0311302128.40fb37f4%...
10
by: Danny Anderson | last post by:
Hola! I have an array of shorts that represents a stream of data. This data is packed in tight, so certain elements may actually contain data for more than one variable. I am to decipher this...
8
by: Sowen | last post by:
Hi, all I am wondering how to write bits by using ofstream? I have finished a huffman tree, but how can I write the bits to the file in order to gain compression? for example, 'A' returns a...
15
by: Yogi_Bear_79 | last post by:
Visual Studio .NET started complaing when the array was around 4000. I found that if I pasted the array in via notepad then opened Visual Studio it would work. Now my array is over 26,000 and...
4
by: Lance | last post by:
I have an array of bytes that I need to convert into an array of Integers. But, the number of bits per value in the Byte array is not necessarily divisible by 8 (although it will never exceed...
15
by: Sync_net | last post by:
I am not sure if this a valid topic to be asked in the groups. --Kindly suggest me a technique/algorithm by which i can convert a stream of data (we could take it to be characters -- stream of 8...
9
by: Alex Buell | last post by:
I just wrote the following and have a question: Why does my code gets it wrong with the class Simple? See last show_size<Simple> function call in main () as below: #include <iostream> #include...
35
by: Frederick Gotham | last post by:
(Before I begin, please don't suggest to me to use "std::vector" rather than actual arrays.) I understand that an object can have resources (e.g. dynamically allocated memory), and so we have to...
2
by: s gall | last post by:
Hi all I have a task to test a checksum algrorithum. This requires changing a string of 12 chr's to a stream of 96 bits and then manipulating these. Currently I work in vb (vb2008). Would it be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.