Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

How to find individual bytes in an integer

Posted on 2004-11-25
17
Medium Priority
?
468 Views
Last Modified: 2011-09-20
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,
0
Comment
Question by:thanesh
  • 3
  • 3
  • 2
  • +4
15 Comments
 
LVL 5

Expert Comment

by:ddunlea
ID: 12675493
Hi thanesh,

int i = 0x12345678;
int j;

j = (int)( ((i & 0xff000000) >> 24) | ((i & 0xff0000) >> 16) | ((i & 0xff00) << 16) | ((i & 0xff) << 24));
0
 
LVL 1

Author Comment

by:thanesh
ID: 12675650
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.


Thanks for your help in advance.
0
 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 12676010
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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 5

Expert Comment

by:ddunlea
ID: 12676030
Do you mean that you want a means of findling the bytes without actually knowing the byte ordering of the underlying system?
0
 
LVL 86

Expert Comment

by:jkr
ID: 12676034
>>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
 
LVL 1

Author Comment

by:thanesh
ID: 12676296
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
 
LVL 86

Accepted Solution

by:
jkr earned 500 total points
ID: 12676345
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
 

Expert Comment

by:embtech
ID: 12678154
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
 
LVL 4

Expert Comment

by:skypalae
ID: 12679002
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
 
LVL 4

Expert Comment

by:skypalae
ID: 12679011
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
 
LVL 23

Expert Comment

by:Mysidia
ID: 12679728
> 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
 
LVL 23

Expert Comment

by:Mysidia
ID: 12679790
but 8*n is just   n << 3...  
so  i.e.    ((x >> (n << 3)) & 0xff)
0
 

Assisted Solution

by:embtech
embtech earned 500 total points
ID: 12679796
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
 
LVL 4

Expert Comment

by:skypalae
ID: 12679897
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
 

Expert Comment

by:embtech
ID: 12686077
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

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use while-loops in the C programming language.
Suggested Courses

810 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question