tags:

views:

114

answers:

6

I am trying to print out binary number in c however the 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

A: 

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.

NickLarsen
+1  A: 
Roger Pate
A: 
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');
    }
}
Judge Maygarden
A: 

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.

tommieb75
There are so many WTFs in these few lines of code that it will crash when free() is called.
Secure
@Secure: What WTFs? Works under BCC 5.5, OpenWatcom 1.8...explain why it would crash if free is called? it's a pointer malloc'd on the heap...
tommieb75
Where do I begin? First, you increment sOutput when setting the termination, but do not increment iCnt, thus the returned string points to the second character of the malloc'ed memory. Then, it does not solve the problem (print binary), but reverses a number. Short: Reverses a number by string conversion with malloc instead of binary operations. No return for main. free accepts NULL, no point in testing. Using sizeof(char) and assuming it to be 1 by the +1 outside the multiplication. Using pointer arithmetic for malloc'ed sOutput and array operation for sInput.
Secure
Define STRMAX and hardcode inpBuf. And maybe some more.
Secure
@Secure: What makes you think that a NULL pointer is returned? ...don't assume until you have tried it and debugged the reverse operation with pointers...in your case you jumped to the wrong conclusions on this over-scrutinizing without actually trying it...I clearly stated that this was an easy way of doing it.
tommieb75
I did not say that a NULL pointer is returned. It returns a pointer that does not point to the beginning of the malloc'ed memory, where it better should point to when calling free().
Secure
@Secure: I appreciate your constructive criticisms, I typed it in in haste...you need to relax and enjoy and learn which is what this is about... and have a good laugh - laugh at my code..go on I dare you :) we're all humans, humans make mistakes...don't take this too seriously... Ok :)
tommieb75
I blame myself for misunderstanding the question! Dammit... :)
tommieb75
Well, you've said "Works under BCC 5.5, OpenWatcom 1.8"... There was no smily...
Secure
@Secure: Oh...did I leave out a smiley? :) sure, the same could be said about your first comment as well huh?
tommieb75
A: 

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; } }

Arthur Kalliokoski
A: 
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');
}
Aistina
thanks Aistina , wasn't to shabby my original attempt then :D
leo