3

I have to make my own printf(for an exercise) and I have to add a %b flag which prints an unsigned number in a binary base. I've created the function but I'm still getting the unsigned number at the output. There you have my code. Thanks in advance!

int unsignednbr(unsigned int nb)
{
    if (nb < 0)
    {
        putchar('-');
        nb = nb * -1;
    }
    if (nb >= 10)
    {
        putnumber(nb / 10);
        putnumber(nb % 10);
    }
    else
        putchar(nb + '0');
}

int unsigned_to_binary(int nb)
{
    long long binary_nbr = 0;
    int remainder;
    int i = 0;

    unsignednbr(nb);
    while (nb != 0)
    {
        remainder = nb % 2;
        nb /= 2;
        binary_nbr += remainder * i;
        i *= 10;
    }
}

void own_printf(char* format, ...)
{
    int i = 0;
    va_list args;

    va_start(args, format);
    while (format[i])
    {
        if (format[i] == '%')
        {
            switch (format[i + 1])
            {
            case 'b':
                unsigned_to_binary (va_arg( args, int));
                break;
            }
            i++;
        }
    }
    va_end(args);
}

int main()
{
    own_printf("%b", -42);
    return 0;
}
mch
  • 9,424
  • 2
  • 28
  • 42
Asez
  • 159
  • 1
  • 3
  • 13
  • 1
    You're calling your *decimal* output function before actually doing anything. Apart from that, the idea is very bad, just iterate over the bits and output a `0` or `1`. –  Nov 16 '17 at 10:02
  • 2
    Besides what @Felix noted, both conversion functions don't return anything while declared as `int`, and in the unsigned print function you check whether an *unsigned* number is negative. – Mattenii Nov 16 '17 at 10:08
  • [example how to print bits](https://ideone.com/eGtfSn) –  Nov 16 '17 at 10:14
  • Thanks mate! It works. Now I have to read the code in order to understand exactly how it works. Because the code you made is too hardcore for me. :D – Asez Nov 16 '17 at 10:53
  • @Asez added some comments –  Nov 16 '17 at 11:03
  • Oh, great. Really helpful! – Asez Nov 16 '17 at 11:09

2 Answers2

0

I bet you are from Epitech, did you try asking a teaching assistant ? :p

Anyway, if you only want to print a binary representation of a number, you could use a combination of the >> and & operators in a loop. You will iterate on each of the 32 bits of your int, determine if it's a 1 or a 0 and print it.

unsigned int number = 42;
for (int i = 0; i < 32; ++i) {
  if (number >> i & 0x1) putchar('1');
  else putchar('0');
}

putchar('\n');

This method has many downsides (no buffering, slow, assuming an int is 32 bits...) but it should work.

Aside from that, a few things you may want to take a look at in your code :

  • In function unsignednbr you check if the unsigned int you recieve as a paremeter is less that 0. This is an always false condiftion.
  • You do not print anything after the while loop in the unsigned_to_binary function. So what is the purpose of this loop ? Keep in mind that the parameters passed by values are acutally copies and that the modifications you make to these copies are local to the function that recieved the copy. The call to the unsignednbr function right before the loop seems useless.
  • If you have time, re-write your main loop using an array of function pointers. That will make the assistants happy ! :p

Good luck ! :D

Geo
  • 155
  • 9
  • This only prints the least significant 8 bits. (if you add the missing `<`, right now it won't compile) –  Nov 16 '17 at 10:36
  • Hahah. You got me! Btw, I'm a bit lost right now but I'll try to make what you said. :D – Asez Nov 16 '17 at 10:38
  • 1
    @Geographer and now, it's non-portable, assuming `unsigned` has exactly 32 value bits. [see here](https://ideone.com/eGtfSn) for how to apply a [kind of "magic" macro](https://stackoverflow.com/a/4589384/2371524) that portably determines the number of value bits. –  Nov 16 '17 at 10:42
  • 2
    Why rewrite the code using function pointers? This would only complicate the code. Both real programmers and assistants would dislike that; or am I missing something? – anatolyg Nov 16 '17 at 10:45
0

You can use following(Using Recursion):

void printBinaryValue(unsigned int num)
{
    if(!num) return;

    printBinaryValue(num>>1);
    putchar(((num&1 == 1) ? '1' : '0'));
}

See it working here

UPDATED
Following code will provide desired output for all inputs including 0(Using while-loop).

 void printBinaryValue2(unsigned int num)
 {
    char result[sizeof(num)*8]; 
    int count = 0;
    while(num)
    {
        result[count++] = ((num&1 == 1) ? '1' : '0'); 
        num>>=1;
    }
    if(count)
    {
        count--;
        while(count>=0)
        {
            putchar(result[count--]);
        }   
    }
    else
    {
        putchar('0');   
    }
 }
cse
  • 4,066
  • 2
  • 20
  • 37