Thread: endian conversion...

  1. #1
    Registered User
    Join Date
    Jun 2009
    Location
    US of A
    Posts
    305

    endian conversion...

    I wrote this program for endian conversion and in my current machine which is little endian it works fine. Is there some better logic to do the same or is this okay (i find it pretty confusing though :-)).

    [insert]
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    void showbits(unsigned int i);
    
    int main(void){
    	
    	unsigned int i = 543295629, j, result = 0, temp,final = 0, k;
    	showbits(i);
    
    	for(j = 31; j > 0; j--){
    
    		temp = i;
    		k = temp >> j;
    		k = k & 1;
    		if (k == 1){
    
    			final = final;
    			result = result >> (31-j);
    			result = result | k;
    			result = result & 1;
    			result = result << (31-j);
    			final = final| result;
    			//showbits(result);
    
    		}
    		else{
    			
    			final = final;
    			result = result >> (31-j);
    			result = result | k;
    			result = result & 1;
    			result = result << (31-j);
    			final = final| result;
    			//showbits(result);
    		}
    	}
    
    		// do it for the last bit as well
    
    		final = final;
    		temp = i;
    		temp = temp & 1;
    		result = result >> 31;
    		result = result | temp;
    		result = result & 1;
    		result = result << 31;
    		final = final| result;
    		//showbits(result);
    
    
    	printf("\n After conversion is done Big endian to Little endian we have");
    	showbits(final);
    	
    	return 0;
    }
    
    void showbits(unsigned int i){
    	
    	unsigned int u;
    	printf("\n");
    	for(u = (~0U >> 1) + 1; u > 0; u = u>>1){
    	
    		putchar(i & u? '1' : '0');
    	}
    	putchar('\n');
    }

  2. #2
    {Jaxom,Imriel,Liam}'s Dad Kennedy's Avatar
    Join Date
    Aug 2006
    Location
    Alabama
    Posts
    1,065
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int end_swp(int *num)
    {
            int tmp, i;
            char *in, *out;
    
            in = (char *)num;
            out = (char *)&tmp;
            for (i = 3; i >= 0; i--){
                    out[i] = (*in++);
            }
            return tmp;
    }
    
    int main(void)
    {
            int num, converted;
    
            num = 0x86753090;
            converted = end_swp(&num);
            printf("ORIG: %08x, SWAP: %08x.\n", num, converted);
            return 0;
    }
    Don't know if it is _better_, but it is shorter.

  3. #3
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    The bits don't get reversed. Just the bytes.

    Code:
    unsigned int SwapEndian( unsigned int x )
    {
        return     ( ( x >> 24 ) & 0x000000FF )
               |   ( ( x >>  8 ) & 0x0000FF00 )
               |   ( ( x <<  8 ) & 0x00FF0000 )
               |   ( ( x << 24 ) & 0xFF000000 );
    }
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  4. #4
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    I just use the ntohl(), htonl(), ntohs(), htons() functions.
    Is there a reason you can't use them?
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  5. #5
    Registered User
    Join Date
    Jun 2009
    Location
    US of A
    Posts
    305
    Quote Originally Posted by cpjust View Post
    I just use the ntohl(), htonl(), ntohs(), htons() functions.
    Is there a reason you can't use them?
    No just acquainting myself with the bit operations so thati feel a bit comfortable. Also i havent yet gone through these functions so i dont know what do these functions do.

  6. #6
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    This is the code I use to go from big to little. Simple, simple. It'll work the other way too.

    Code:
    union  myunion {  // "myunion" is the type name. 
    	char data[8] ; 
    	int  myint ; 
    } ; 
    
    . . . 
    
    
    int fix_int(char * n, int len ) { 
    	unsigned char temp ; 
    	int i , j ; 
    	myunion mydata ; 
    
    	memcpy(mydata.data, n, len) ; // Copy data into my union 
    	
    	for (i = 0 , j = len-1 ; i < j ; ++i, --j ) {  // logic will work for any length value 
    	
    		// To get little endian frm Big endian, swap this: 0X01020304 into this: 0X04030201 
    	
    		temp = mydata.data[i] ; 
    		mydata.data[i] = mydata.data[j] ; 
    		mydata.data[j] = temp ; 
    	} 
    		
    	return mydata.myint ;  
    }
    Mainframe assembler programmer by trade. C coder when I can.

  7. #7
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by cpjust View Post
    I just use the ntohl(), htonl(), ntohs(), htons() functions.
    Is there a reason you can't use them?
    On a big-endian platform those functions are no-ops
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  8. #8
    Registered User
    Join Date
    Jun 2009
    Location
    US of A
    Posts
    305
    Quote Originally Posted by Kennedy View Post
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int end_swp(int *num)
    {
            int tmp, i;
            char *in, *out;
    
            in = (char *)num;
            out = (char *)&tmp;
            for (i = 3; i >= 0; i--){
                    out[i] = (*in++);
            }
            return tmp;
    }
    
    int main(void)
    {
            int num, converted;
    
            num = 0x86753090;
            converted = end_swp(&num);
            printf("ORIG: %08x, SWAP: %08x.\n", num, converted);
            return 0;
    }
    Don't know if it is _better_, but it is shorter.
    Are you sure that this does the little endian to big endian conversion. Because it doesnt seem to do that .

  9. #9
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by roaan View Post
    Are you sure that this does the little endian to big endian conversion. Because it doesnt seem to do that .
    It gives (0x)90307586, which is the correct answer.

  10. #10
    {Jaxom,Imriel,Liam}'s Dad Kennedy's Avatar
    Join Date
    Aug 2006
    Location
    Alabama
    Posts
    1,065
    here is the result that I get:
    Code:
    ORIG: 86753090, SWAP: 90307586.
    EDIT: Snot!! too slow on the mouse. . . stupid mouse.

  11. #11
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by brewbuck View Post
    On a big-endian platform those functions are no-ops
    Which is correct if you're planning to send stuff over a network.
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  12. #12
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by roaan View Post
    No just acquainting myself with the bit operations so thati feel a bit comfortable. Also i havent yet gone through these functions so i dont know what do these functions do.
    IMO that's good roaan, I have a tendency to write my own versions of standard library functions too, mostly in a quest for understanding, as you say.

    However, when you are writing "production" grade software you should probably stick to those standard function when available, since they carry a bit more of a "playtested" guarantee and may save you unforeseen maintenance headaches, altho, as brewbuck is about to point out, the ntoh and hton functions maybe have a slightly more specific purpose and are for unsigned types.
    Last edited by MK27; 08-11-2009 at 03:54 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  13. #13
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by cpjust View Post
    Which is correct if you're planning to send stuff over a network.
    Yes, my point was that they are not general endian conversion functions which is what you seemed to be implying.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  2. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  3. Header File Question(s)
    By AQWst in forum C++ Programming
    Replies: 10
    Last Post: 12-23-2004, 11:31 PM
  4. Do I have a scanf problem?
    By AQWst in forum C Programming
    Replies: 2
    Last Post: 11-26-2004, 06:18 PM
  5. Big endian/Little endian conversion
    By bonkey in forum Windows Programming
    Replies: 5
    Last Post: 09-25-2002, 02:29 PM