Hendra Saputra bio photo

Hendra Saputra

Insatiable knowledge seeker, code monkey, movie addict.

Email Twitter Facebook Google+ Instagram Tumblr Github Flickr

Getting short int and long int from a byte character on C can make you shoot your feet sometimes. Especially if you’re coding it in Little Endian machine and processing them on Big Endian machine. Suddenly you get a different result. For example take a look at this code

get_int32(unsigned int *dest, char *src)
{
    unsigned char dummy[4];
    memcpy(&dummy[0],&src[0],1);
    memcpy(&dummy[1],&src[1],1);
    memcpy(&dummy[2],&src[2],1);
    memcpy(&dummy[3],&src[3],1);
    memcpy(dest,&dummy,4);
}

get_int16(unsigned int *dest, char *src)
{
    unsigned char dummy[2];
    bzero(dummy,2);
    memcpy(&dummy[0],&src[0],1);
    memcpy(&dummy[1],&src[1],1);
    memcpy(dest,&dummy,2);
}

This code when processed in Big Endian machine can correctly translate a byte character to Long and Short. What it did is it assume that the Most Significant Bit is stored on the lowest address. but if we run this code on the Little Endian machine (such as your ordinary Intel machine) it will produce a different result because on Little Endian the Least Significant Bit is stored in the lowest address, and that can cause a bug in you application. To fix things lets change the code to the following

unsigned long int get_int32(char *src)
{
    unsigned char dummy[4];
    bzero(dummy,4);
    dummy[0]=*src;
    dummy[1]=*(src+1);
    dummy[2]=*(src+2);
    dummy[3]=*(src+3);
    return (dummy[0]<<24) | (dummy[1]<<16) | (dummy[2]<<8) | dummy[3];
}

unsigned short int get_int16(char *src)
{
    unsigned char dummy[2];
    bzero(dummy,2);
    dummy[0]=*src;
    dummy[1]=*(src+1);
    return (dummy[0] << 8) | dummy[1];
}

This code is better because it doesn’t assume that MSB is stored in the lowest address, it just bit shifting and ‘OR’ing memory address value.