I tried left-shifting a 32-bit integer by 24:
char *int_to_bin(int num) {
int i = 0;
static char bin[64];
while (num != 0) {
bin[i] = num % 2 48;
num /= 2;
i ;
}
bin[i] = '\0';
return (bin);
}
int main() {
int number = 255;
printf("number: %s\n", int_to_bin(number));
printf("shifted number: %s\n", int_to_bin(number << 24));
return 0;
}
OUTPUT:
number: 11111111
shifted number: 000000000000000000000000/
and i left-shift with 23-bit it yields this result:
0000000000000000000000011111111
Well Why is it like that and what's the matter with '/' at the end of the wrong result?
CodePudding user response:
Two things:
If
number
has the value 255 thennumber << 24
has the numerical value 4278190080, which overflows a 32-bit signed integer whose largest possible value is 2147483647. Signed integer overflow is undefined behavior in C, so the result could be anything at all.What probably happens in this case is that the result of the shift is negative. When
num
is negative thennum % 2
may take the value-1
, so you store character 47 in the string, which is/
.Bit shifting math is usually better to do with
unsigned
types, where overflow is well-defined (it wraps around and bits just shift off the left and vanish) andnum % 2
can only be 0 or 1. (Or writenum & 1
instead.)Your
int_to_bin
routine puts the least-significant bits at the beginning of the string (on the left), so the result is backwards from the way people usually write numbers (with the least-significant bits on the right). You may want to rewrite it.
CodePudding user response:
Shift works fine, you simply print it from the wrong direction.
char *int_to_bin(char *buff, int num)
{
unsigned mask = 1U << (CHAR_BIT * sizeof(num) - 1);
char *wrk = buff;
for(; mask; mask >>= 1)
{
*wrk = '0' !!((unsigned)num & mask);
}
*wrk = 0;
return buff;
}
int main()
{
char buff[CHAR_BIT * sizeof(int) 1];
int number = 255;
printf("number: %s\n", int_to_bin(buff, number));
printf("shifted number: %s\n", int_to_bin(buff, number << 24));
return 0;
}
Shifting signed integers left is OK, but the right shift is implementation-defined. Many systems use arithmetic shift right and the result is not the same as using the bitwise one: