473,324 Members | 1,856 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,324 software developers and data experts.

How to eliminate the bitmap difference in little endian and big endian?

Hi,

Such as I have following bitmap structure and assigned value:
struct bm
{
char high2bits:2;
char mid4bits:4;
char low2bits:2;
};
bm.high2bits = 3;
bm.mid4bits = 0;
bm.low2bits = 0;

The char value is 0x03 in little endian mode, and the char value is 0xc0 in
big endian mode. How to eliminate the bitmap difference?
Thanks,
Eric
Aug 29 '05 #1
7 2289
Eric J.Hu wrote:
<snip>
The char value is 0x03 in little endian mode, and the
char value is 0xc0 in big endian mode. How to eliminate
the bitmap difference?

<snip>

Do the bitshuffling yourself:

class bm {
unsigned char ch;
public:
void setHigh2Bits( unsigned char bits ) {
ch &= 0x3F;
ch |= (bits & 0x3) << 6;
}
unsigned char high2Bits() const {
return (ch >> 6) & 0x3;
}
// ...
unsigned char asUChar() const { return ch; }
};

Marc
Aug 29 '05 #2
Marc Mutz wrote:
Eric J.Hu wrote:
<snip>
The char value is 0x03 in little endian mode, and the
char value is 0xc0 in big endian mode. How to eliminate
the bitmap difference?

<snip>

Do the bitshuffling yourself:

class bm {
unsigned char ch;
public:
void setHigh2Bits( unsigned char bits ) {
ch &= 0x3F;
ch |= (bits & 0x3) << 6;
}
unsigned char high2Bits() const {
return (ch >> 6) & 0x3;
}
// ...
unsigned char asUChar() const { return ch; }
};

Marc

Presumably this routine has to reverse the bits for any value 0-255.
The code above does not do so.

The question is how to reverse the bits within a single byte
efficiently. One solution would be to calculate the value by reversing
the bits at runtime:

unsigned char ReverseByteSlowly(unsigned char inByte)
{
return ((inByte & 0x80) ? 0x01 : 0) +
((inByte & 0x40) ? 0x02 : 0) +
((inByte & 0x20) ? 0x04 : 0) +
((inByte & 0x10) ? 0x08 : 0) +
((inByte & 0x08) ? 0x10 : 0) +
((inByte & 0x04) ? 0x20 : 0) +
((inByte & 0x02) ? 0x40 : 0) +
((inByte & 0x01) ? 0x80 : 0);
}

This approach works but it is expensive. It requires eight if-then-else
clauses just to reverse the bits in a single byte.

A much faster method is illustrated by this routine:

unsigned char ReverseByteQuickly( unsigned char inByte)
{
static const char kReverseByteTable[256] = {
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff };

return kReverseByteTable[ inByte ];
}

Although ReverseByteQuickly uses 256 more bytes of memory than
ReverseByteSlowly, the payoff is a huge improvement in speed. It's a
classic memory-for-speed tradeoff, but in this case the 256 byte
overhead is a very good investment indeed.

Greg

Aug 29 '05 #3
Greg, I think your approach to solving Eric's question is excellent.
But I wonder suppose I want to convert a 32 bit or 64 bit struct from
little endian to big endian. Then , one would to have create a
humungous(sp?) lookup table. Is there an algorithm out there to handle
the 32 bit or 64 bit ..... cases. Thank you.

Aug 29 '05 #4
Eric J.Hu wrote:
Hi,

Such as I have following bitmap structure and assigned value:
struct bm
{
char high2bits:2;
char mid4bits:4;
char low2bits:2;
};
bm.high2bits = 3;
bm.mid4bits = 0;
bm.low2bits = 0;

The char value is 0x03 in little endian mode, and the char value is 0xc0 in
big endian mode. How to eliminate the bitmap difference?


See the other posts for possible solutions, but let me note that
bit-fields should be avoided if possible for two reasons:

1. They are non-portable, as you have learned the hard way. C++ARM says
that the layout of bit-fields "is highly implementation dependent, and
it is wise not to make any assumptions about it unless absolutely
necessary." On a previous project, we used bit-fields for mapping the
contents of hardware registers, but when we eventually ported the
project to another platform with the other endianness, we had to
manually reverse the order of our many bit-fields. If I had time and
was still working on that project, I might try to use template
metaprogramming (a la Boost and Modern C++ Design) to engineer a more
portable solution akin to the Boost Parameter library
(http://boost.org/libs/parameter/doc/html/index.html). (N.B., I haven't
looked to see if anything like that already exists, and you might want
to.)

2. Some programmers mistakenly see bit-fields as a good form of space
or speed optimization. Consult C++ARM section 9.6 and C++PL section
C.8.1 for reasons why these forms of premature optimization often have
the opposite effect. In your case, it sounds like you're trying to
communicate between two systems of differing endianness, and so
communication *may* be a bottleneck that can be eased by bit-packing.
Just remember not to prematurely optimize
(http://www.gotw.ca/publications/mill09.htm). :-)

Cheers! --M

Aug 29 '05 #5
"Greg" <gr****@pacbell.net> wrote in message
news:11**********************@g47g2000cwa.googlegr oups.com...
Marc Mutz wrote:
Eric J.Hu wrote:
<snip>
> The char value is 0x03 in little endian mode, and the
> char value is 0xc0 in big endian mode. How to eliminate
> the bitmap difference?

<snip>

Do the bitshuffling yourself:

class bm {
unsigned char ch;
public:
void setHigh2Bits( unsigned char bits ) {
ch &= 0x3F;
ch |= (bits & 0x3) << 6;
}
unsigned char high2Bits() const {
return (ch >> 6) & 0x3;
}
// ...
unsigned char asUChar() const { return ch; }
};

Marc

Presumably this routine has to reverse the bits for any value 0-255.
The code above does not do so.

The question is how to reverse the bits within a single byte
efficiently. One solution would be to calculate the value by reversing
the bits at runtime:

unsigned char ReverseByteSlowly(unsigned char inByte)
{
return ((inByte & 0x80) ? 0x01 : 0) +
((inByte & 0x40) ? 0x02 : 0) +
((inByte & 0x20) ? 0x04 : 0) +
((inByte & 0x10) ? 0x08 : 0) +
((inByte & 0x08) ? 0x10 : 0) +
((inByte & 0x04) ? 0x20 : 0) +
((inByte & 0x02) ? 0x40 : 0) +
((inByte & 0x01) ? 0x80 : 0);
}

This approach works but it is expensive. It requires eight if-then-else
clauses just to reverse the bits in a single byte.

A much faster method is illustrated by this routine:

unsigned char ReverseByteQuickly( unsigned char inByte)
{
static const char kReverseByteTable[256] = {
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff };

return kReverseByteTable[ inByte ];
}

Although ReverseByteQuickly uses 256 more bytes of memory than
ReverseByteSlowly, the payoff is a huge improvement in speed. It's a
classic memory-for-speed tradeoff, but in this case the 256 byte
overhead is a very good investment indeed.

Greg


Umm.. whats wrong with:
return 255 - inByte;
Sep 7 '05 #6

Jim Langston schreef:
Eric J.Hu wrote:
<snip>
> The char value is 0x03 in little endian mode, and the
> char value is 0xc0 in big endian mode. How to eliminate
> the bitmap difference?
Umm.. whats wrong with:
return 255 - inByte;


Well, 255-0xc0 isn't 0x03, so that's one bug.

HTH,
Michiel Salters

Sep 7 '05 #7

"msalters" <Mi*************@logicacmg.com> wrote in message
news:11**********************@g14g2000cwa.googlegr oups.com...

Jim Langston schreef:
>> Eric J.Hu wrote:
>> <snip>
>> > The char value is 0x03 in little endian mode, and the
>> > char value is 0xc0 in big endian mode. How to eliminate
>> > the bitmap difference?

Umm.. whats wrong with:
return 255 - inByte;


Well, 255-0xc0 isn't 0x03, so that's one bug.


Ahh, yes, my bad. I didn't understand the OP problem fully.
Sep 7 '05 #8

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

Similar topics

18
by: David Buchan | last post by:
Hi guys, This may be a dumb question; I'm just getting into C language here. I wrote a program to unpack a binary file and write out the contents to a new file as a list of unsigned integers....
3
by: ranjeet.gupta | last post by:
Dear All !! I am not sure the question which I am asking is correct or wrong, but I have heard that storing the data into the big endian helps in gting the more transfer rate, Means we can...
3
by: Eric J.Hu | last post by:
Hi, Such as I have following bitmap structure and assigned value: struct bm { char high2bits:2; char mid4bits:4; char low2bits:2; }; bm.high2bits = 3;
20
by: Aaron Graham | last post by:
/** * Sample usage: * unsigned long longvar = 0x12345678; * unsigned long be_longvar = endian::host_to_big(longvar); * unsigned short shortvar = 0x1234; * unsigned short le_shortvar =...
3
RRick
by: RRick | last post by:
This was a question that showed up in a job interview once. (And to answer your next question: No, I didn't :)) Write a subroutine that returns a bool on whether a system supports big endian...
6
by: Javier | last post by:
Hello people, I'm recoding a library that made a few months ago, and now that I'm reading what I wrote I have some questions. My program reads black and white images from a bitmap (BMP 24bpp...
5
by: Charles Sullivan | last post by:
Suppose I have this code: unsigned short svalue; unsigned char hibyte, lobyte; svalue = 0xABCD; hibyte = (svalue >8) & 0xFF; lobyte = svalue & 0xFF;
2
by: Ramesh | last post by:
Hi I have a structure as below on big endian based system typedef struct { unsigned long LedA:5; unsigned long LedB:4; unsigned long LedC:8;
23
by: Niranjan | last post by:
I have this program : void main() { int i=1; if((*(char*)&i)==1) printf("The machine is little endian."); else printf("The machine is big endian."); }
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will 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...

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.