About sign extending

The examples below show the problem in sign extending:

And this is the code:

// Code for sign extending
// CG – 24102008

#include <stdio.h>

void int_to_bin(unsigned x){
unsigned char b[32];
unsigned char i;

for (i=0; i<32; i++){
b[i] = 0;
}

i = 31;
while (x > 0){
b[i] = x % 2;

i–;
}

for (i=0; i<32; i++){
printf(“%d”, b[i]);
if ( ( ( i+1 ) % 8 ) == 0 ){
printf(” “);
}
}
}

typedef unsigned packed_t;

//this is the wrong implementation
int xbyteincorrect(packed_t word, int bytenum){
return (word >> (bytenum << 3)) & 0xFF;
}

//this is the correct implementation with sign extending
int xbytecorrect(packed_t word, int bytenum){
return (((word<<((3-bytenum)<<3))>>24)-(((word<<((3-bytenum)<<3))>>31)<<8));
}

int main () {
int x, y;

printf(“Enter an integer: “);
scanf(“%d”, &x);
printf(“Enter byte number: “);
scanf(“%d”, &y);

printf(“\nword \t\t\t\t\t\t\t\t\t\t\t\t\t\t:\t”);
int_to_bin(x);

printf(“\n\nThe incorrect result: “);
printf(“\n——————– “);
printf(“\nbytenum \t\t\t\t\t\t\t\t\t\t\t\t:\t%d”, y);
printf(“\nbytenum \t\t\t\t\t\t\t\t\t\t\t\t:\t”);
int_to_bin(y);
printf(“\nbytenum<<3 \t\t\t\t\t\t\t\t\t\t\t:\t%d”, y<<3);
printf(“\nbytenum<<3 \t\t\t\t\t\t\t\t\t\t\t:\t”);
int_to_bin((y)<<3);
printf(“\nword>>(bytenum<<3) \t\t\t\t\t\t\t\t:\t0x%x”, x>>(y<<3));
printf(“\nword>>(bytenum<<3) \t\t\t\t\t\t\t\t:\t”);
int_to_bin(x>>(y<<3));
printf(“\n0xFF \t\t\t\t\t\t\t\t\t\t\t\t\t\t:\t0x%x”, 0xFF);
printf(“\n0xFF \t\t\t\t\t\t\t\t\t\t\t\t\t\t:\t”);
int_to_bin(0xFF);
printf(“\n((word>>(bytenum<<3)) & 0xFF \t\t\t\t:\t0x%x”, (x>>(y<<3))&0xFF);
printf(“\n((word>>(bytenum<<3)) & 0xFF \t\t\t\t:\t”);
int_to_bin((x>>(y<<3))&0xFF);
printf(“\nIncorrect result \t\t\t\t\t\t\t\t\t:\t0x%x\n”, xbyteincorrect(x, y));

printf(“\n\nThe correct result: “);
printf(“\n—————— “);
printf(“\nbytenum \t\t\t\t\t\t\t\t\t\t\t\t:\t%d”, y);
printf(“\nbytenum \t\t\t\t\t\t\t\t\t\t\t\t:\t”);
int_to_bin(y);
printf(“\n3-bytenum \t\t\t\t\t\t\t\t\t\t\t\t:\t%d”, 3-y);
printf(“\n3-bytenum \t\t\t\t\t\t\t\t\t\t\t\t:\t”);
int_to_bin(3-y);
printf(“\n(3-bytenum)<<3 \t\t\t\t\t\t\t\t\t\t:\t%d”, (3-y)<<3);
printf(“\n(3-bytenum)<<3 \t\t\t\t\t\t\t\t\t\t:\t”);
int_to_bin((3-y)<<3);
printf(“\nword<<((3-bytenum)<<3) \t\t\t\t\t\t\t:\t0x%x”, x<<((3-y)<<3));
printf(“\nword<<((3-bytenum)<<3) \t\t\t\t\t\t\t:\t”);
int_to_bin(x<<((3-y)<<3));
printf(“\n(((word<<((3-bytenum)<<3))>>24)  \t\t\t:\t0x%x”, (x<<((3-y)<<3))>>24);
printf(“\n(((word<<((3-bytenum)<<3))>>24)  \t\t\t:\t”);
int_to_bin((x<<((3-y)<<3))>>24);
printf(“\n(((word<<((3-bytenum)<<3))>>31)  \t\t\t:\t0x%x”, (x<<((3-y)<<3))>>31);
printf(“\n(((word<<((3-bytenum)<<3))>>31)  \t\t\t:\t”);
int_to_bin((x<<((3-y)<<3))>>31);
printf(“\n((((word<<((3-bytenum)<<3))>>31)<<8) \t:\t0x%x”, ((x<<((3-y)<<3))>>31)<<8);
printf(“\n((((word<<((3-bytenum)<<3))>>31)<<8) \t:\t”);
int_to_bin(((x<<((3-y)<<3))>>31)<<8);
printf(“\n(((word<<((3-bytenum)<<3))>>24)-(((word<<((3-bytenum)<<3))>>31)<<8)) \t:\t0x%x”, (((x<<((3-y)<<3))>>24)-(((x<<((3-y)<<3))>>31)<<8)));
printf(“\n(((word<<((3-bytenum)<<3))>>24)-(((word<<((3-bytenum)<<3))>>31)<<8)) \t:\t”);
int_to_bin((((x<<((3-y)<<3))>>24)-(((x<<((3-y)<<3))>>31)<<8)));
printf(“\nCorrect result \t\t\t\t\t\t\t\t\t\t:\t0x%x\n”, xbytecorrect(x, y));

getchar();
return 0;
}

Advertisements