Reputation: 11
Background on what the code is supposed to do, vs what I am achieving. So the dec2bin function is supposed to get the values/numbers decimal from the array dec_nums[]={0, 1, 77, 159, 65530, 987654321};
the function is supposed to convert the value to binary numbers and print it out. the conversion is done correctly however, it prints the binary backward.
Can someone help me on figuring out what the problem is, or if there is another way to achieve the correct results?
int main() {
int dec_nums[] = {0, 1, 77, 159, 65530, 987654321};
int i;
printf("=== dec2bin ===\n");
for (i = 0; i < sizeof(dec_nums) / sizeof(int); i++)
dec2bin(dec_nums[i]);
return 0;
}
void dec2bin(int num) {
int saveNum = num;
if (saveNum == 0) {
printf("\nBinary Number of %d", saveNum);
printf(" = 0");
} else {
int number;
int i;
printf("\nBinary Number of %i", saveNum);
printf(" = ");
for (i = 0; num > 0; i++) {
number = num % 2;
num = num / 2;
printf("%i", number);
}
printf("\n");
}
}
Upvotes: 1
Views: 81
Reputation: 148890
A simple solution would be to write to bits into a char array, starting from the end of the array, the same way that we would do by hand.
Your dec2bin
function would become (only minimal changes, with comments for added or changed lines):
void dec2bin(int num)
{
// declare a char array of size number_of_bits_in_an_int + 1 for the terminating null
char bin[sizeof(int) * CHAR_BIT + 1];
char* ix = bin + sizeof(bin) - 1; // make ix point to the last char
*ix-- = '\0'; // and write the terminating null
int saveNum = num;
if (saveNum == 0)
{
printf("\nBinary Number of %d", saveNum);
printf(" = 0");
}
else
{
int number;
int i;
printf("\nBinary Number of %i", saveNum);
printf(" = ");
for (i = 0; num > 0; i++)
{
number = num % 2;
num = num / 2;
*ix-- = '0' + number; // just write the bit representatin
}
printf("%s\n", ix+1); //print the binary representation
}
}
That is enough to get the expected result.
Upvotes: 1
Reputation: 25516
For bit fiddling unsigned types are preferrable, you avoid any kinds of problems with undefined behaviour due to under-/overflow.
Apart from, you can operate on bit masks:
for(unsigned mask = 1u << sizeof(mask) * CHAR_BIT - 1; mask; mask >>= 1)
{
unsigned bit = (value & mask) != 0;
// print it
}
CHAR_BIT
is the value of bits within a char and comes from header limits.h
, typically (but not necessarily) it is 8, with typically four bytes for int
s you initialise the mask to 1 << 31
and further on shift it downwards until it reaches 1 << 0
, i. e. 1, which is the last value yet considered. Yet another shift moves the single bit set out of the mask
, so you get 0 and the loop aborts.
Above code will print leading zeros, you might prepend another loop that simply shifts down until the first 1-bit is met if you want to skip them.
This variant starts at most significant bit; by % 2
you always get the least significant bit instead – which is why you got the inverse order.
Side note: Getting length of an array is better done as sizeof(array)/sizeof(*array)
– this avoids errors if you need to change the underlying type of the array...
Upvotes: 2