I am trying to print out binary number in c however t开发者_运维百科he dilemma i have is that its printing out in the reverse order. I have defined a function to tell me how many bits there are, this way i can work from the last bit back
to get the nth bit i can use
(value >> totalNumberOfBits) & 1;
in a while loop i can run this until the totalNumberOfBits == 0;
as such
while(totalNumberOfBits!= 0){
putchar(n >> totalNumberOfBits)&1;
totalNumberOfBits--;
}
any pointers would be welcome - i think i may be massivley off, i have an approach that prints them number fine backwards but iam trying to find a way of avoiding this
thanks
Your putchar(n >> totalNumberOfBits)&1
is an error (notice where the right paren is).
Your current code outputs seemingly random values (based on the 'current' and more significant bits in your number), and if you just move the right parent to where you meant to put it, then you'll be writing '\0'
and '\1'
(which are null and another control code). Instead, you want to write '0'
and '1'
(digits zero and one).
This is one of those things best shown with an example:
void f() {
// hardcode total_bits values for this example
// in reality you'd call your function
int num = 42; // 101010 in binary
for (int total_bits = 6; total_bits;) {
putchar("01"[(num >> --total_bits) & 1]);
}
num = 5; // 101 in binary
// loop written verbosely, but does exactly the same:
for (int total_bits = 3; total_bits;) {
--total_bits; // decrement after condition is checked, before used
int bit = (num >> total_bits) & 1; // bit is always 0 or 1
char c = "01"[bit]; // c is always '0' or '1'
putchar(c);
}
}
Note where the decrement is (can be moved if you want, but not to the 3rd part of the for loop—that would change the computation order), and this loop doesn't handle the case when num is zero.
Would this do, by using the itoa
function to convert the number and store it into a buffer and use the string's custom reverse
function which returns back a pointer to char and convert the pointer to char to an int
again using the atoi
function. This is an easy way of doing it.
#include <stdio.h> #include <stdlib.h> #include <string.h> #define STRMAX 50 char *reverse(const char *); int main(int argc, char **argv){ static char inpBuf[25]; char *ptr = NULL; int num = 1234; /* Convert num to a string */ itoa(num, inpBuf, 10); /* Reverse the string */ ptr = reverse(inpBuf); /* Convert the reversed string back to num */ num = atoi(ptr); /* num is reversed! i.e. 4321 */ /* Free the pointer */ if (ptr) free(ptr); } char *reverse(const char* sInput) { char* sOutput; int iCnt = 0, iCntRev; sOutput = (char *)malloc((STRMAX * sizeof(char)) + 1); if (sOutput){ for (iCntRev = strlen(sInput); iCntRev >= 0; iCntRev--) { *sOutput++ = sInput[iCntRev]; iCnt++; } *sOutput++ = '\0'; } return (sOutput - iCnt); }
Hope this helps, Best regards, Tom.
while (totalNumberOfBits != 0) {
putchar(n >> totalNumberOfBits) & 1;
totalNumberOfBits--;
}
Okay, you're code was pretty close (and was in fact already printing out the bits in the correct order), however there were 3 small errors. Firstly, when compiling Visual Studio gives me the following warning:
warning C4552: '&' : operator has no effect; expected operator with side-effect
It is complaining about the & 1
part of your code, which you seem to have accidentally placed outside the parentheses of your putchar
function call.
while (totalNumberOfBits != 0) {
putchar((n >> totalNumberOfBits) & 1);
totalNumberOfBits--;
}
The second error is that, while it is now correctly printing bits, you are printing \0 and \1 characters. \0 will not show in the console, and \1 will most likely look like a smiley, so let's fix that as well.
while (totalNumberOfBits != 0) {
putchar(((n >> totalNumberOfBits) & 1) ? '1' : '0');
totalNumberOfBits--;
}
This is very close now, there is just one small mistake remaining. Because of the check your while loop performs, and the place where you decrement totalNumberOfBits
, you never check the bit for 2^0, while you do check 2^8 even if your n
is only 8 bits (and thus out of range). So we move the decrement, and substitute the !=
:
while (--totalNumberOfBits >= 0) {
putchar(((n >> totalNumberOfBits) & 1) ? '1' : '0');
}
Instead of right shifting, try left shifting and end at the WORD size. Or use WORD size minus the number of bits and remove those leading 0's first.
Also don't forget to change your &
to match the highest bit.
static void
print_binary(int value, int numBits)
{
/* postfix decrement, so the loop will run numBits times */
while (0 < numBits--) {
/*
* Since numBits was decremented it now is an index to the next bit from
* the left. So, we shift a one to the left that number of bits, do a
* bitwise-AND with the value and test whether it is not equal to 0. If
* so, print a 1. Otherwise, print a 0!
*/
putchar((value & (1 << numBits)) ? '1' : '0');
}
}
void printbin(int input) { int i; int mask = 0x80000000; //assuming 32 bit integer for(i=0;i<32;i++) { if(mask & input) putchar('1') else putchar('0'); mask >>= 1; } }
精彩评论