• C

# How to find individual bytes in an integer

Hi there,

I need to get the individual bytes in an integer.  I need to write a macro to convert an integer to Big endian format and another that would change it back to the native platform byte ordering.

Thanks,
LVL 1
###### Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Commented:
Hi thanesh,

int i = 0x12345678;
int j;

j = (int)( ((i & 0xff000000) >> 24) | ((i & 0xff0000) >> 16) | ((i & 0xff00) << 16) | ((i & 0xff) << 24));
0
Author Commented:
Thanks ddunela,

But, what I need exaclty is follows:
A word( 2 bytes) or integer (4 bytes ) can be converted into big endian format in the following way[ Note, the native platform is not relevant here].  To use this, I need a way to tell individual bytes[ byte[0], byte[1] ... etc ]

value = (byte[0] << 8*(n-1)) | (byte[1] << 8*(n-2)) |
... | byte[n-1];

What is the process to get them.  After the arragements I would have
MSB....LSB, where byte[0] is the MSB.

0
Software ArchitectCommented:
Just you need a casting trick like this:

int value = 4957553;
unsigned char *byte = (unsigned char *)&value;

value = (byte[0] << 8*(n-1)) | (byte[1] << 8*(n-2)) |
... | byte[n-1];
0
Commented:
Do you mean that you want a means of findling the bytes without actually knowing the byte ordering of the underlying system?
0
Commented:
>>I need to write a macro to convert an integer to Big endian format and another that would change it back to the
>>native platform byte ordering

Why reinvent the wheel? There are already 'htonl()' and 'ntohl()' that serve this purpose.
0
Author Commented:
Yes, I need to find the bytes without knowing the architecture of the underlying system.  Is dividing it by FF, FFFF, etc work?  This should give the actual byte right?

jkr:  I need it for 16, 32 bit data types. I don't know if I can use htonl(), ntohl().  Is there is a link that have more infor about htonl()....

Tahnks,
0
Commented:
For 16bit integers, there's 'htons()' and 'ntohs()'.  Check out e.g. http://www.rt.com/man/ntohl.3.html

BYTEORDER(3)        Linux Programmer's Manual        BYTEORDER(3)

NAME
htonl,  htons,  ntohl, ntohs - convert values between host
and network byte order

SYNOPSIS
#include <netinet/in.h>

unsigned long int htonl(unsigned long int hostlong);

unsigned short int htons(unsigned short int hostshort);

unsigned long int ntohl(unsigned long int netlong);

unsigned short int ntohs(unsigned short int netshort);

DESCRIPTION
The htonl() function converts the  long  integer  hostlong
from host byte order to network byte order.

The  htons() function converts the short integer hostshort
from host byte order to network byte order.

The ntohl() function converts  the  long  integer  netlong
from network byte order to host byte order.

The  ntohs()  function converts the short integer netshort
from network byte order to host byte order.

On the i80x86 the host byte  order  is  Least  Significant
Byte first, whereas the network byte order, as used on the
Internet, is Most Significant Byte first.

Even though the above is a Linux manpage, these functions are available on every platform that allows networking.
0

Experts Exchange Solution brought to you by

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Commented:
htonl() et al are not really relevant to the question:
htonl() et al deal with converting between network & host representations - that wasn't the question.

The question was, how to access the individual bytes of multi-byte data types.
The only portable way to do this (ie, without relying upon the underlying implementation) is to use shifts & masks:

(anything & 0xFF) will always give the least-significant byte of 'anything' - irrespective of the underlying byte order;
(anything & 0xFF00) >> 8  will always give the next least-significant byte of 'anything' - irrespective of the underlying byte order, etc, etc.

If you do know the underlying byte order, it _may_ be more efficient to use pointers or unions to access the individual bytes...
0
Commented:
Hi,

I think that << and >> operators would work only if you know the native byte ordering. If you don't know them, %, / and * have to be used. They may seem bit slower, but good optimizing compiler should handle.

16bit:
LSB = x % 256 ;
MSB = x / 256 ;

32bit
B0 = x % 256 ;
B1 = x / 256 % 256 ;
B2 = x / 65536 % 256 ;
B3 = x / 16777216 ;

#define BYTE(x,n) (x / pow (256, n) % 256 ;

and back

x = B0 + (B1 + (B2 + B3 * 256) * 256) * 256 ;

S.
0
Commented:
sorry .. of course << and >> will work on any system. the macro can be rewritten to use them this way:

#define BYTE(x,n) (x >> 8*n & 0xff)

but as I allready said .. good optimizing compiler should handle

S.
0
Commented:
> htonl() et al are not really relevant to the question:
> htonl() et al deal with converting between network & host representations - that wasn't the question.

"I need to write a macro to convert an integer to Big endian format and another that would change it back to the native platform byte ordering."

Which is what htonl  and ntohl  do.

Big Endian is another name for the Network byte order.

Host byte order is another name for Native platform byte ordering.
0
Commented:
but 8*n is just   n << 3...
so  i.e.    ((x >> (n << 3)) & 0xff)
0
Commented:
Good optimising compiler should handle what?

A good compiler should be able to spot that multiplication/division by powers of two is equivalent to shifting, a choose the most efficient implementation.

However, I'm not so sure that a compiler will necessary deduce _why_ you're trying to do it;
ie, I'm not sure that the compiler will realise that all you really want is to get at the individual bytes - so that it can throw away all the data manipulation (shifts/multiplies/diivides) and just go straight to the individual bytes.

Using a union will never generate any code at all - it simply tells the compiler directly that you want to access the memory in different ways (eg, as longs, and as individual bytes)

As always, if this _really_ matters to you, you will have to inspect the generated code!
0
Commented:
embtech,

i don'get the point of using union in this case. assume you have following code

////////////////////////////////////////////////////
union ints {
long l ;
short s[2] ;
char b[4] ;
} ;

int main (int argc, char **argv) {

union ints i, j ;

i.l = 1234567 ;

j.b[3] = i.b[0] ;
j.b[2] = i.b[1] ;
j.b[1] = i.b[2] ;
j.b[0] = i.b[3] ;

// here j.l is opposite endian as i.l

return 0 ;

}
////////////////////////////////////////////////////

it just changes the endianiness (what a word :)) of the long. but it really doesn't make it big-endian. running on Motorola processor it would change it to little-endian instead.

S.
0
Commented:
You are right, the union doesn't _change_ the "endiannes"

The union answers the specific quesion in the title of this thread - "How to find individual bytes in an integer"
The union is the most efficient (but non-portable) way to access the individual bytes in an integer.

To actually _change_ the order of the bytes, the htons() etc functions should be used - as they will be defined by the implementation as appropriate.

0
###### It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.