Page 1 of 1

Simplest solution for this problem

Posted: Wed Sep 14, 2005 12:43 am
by NOTNULL
Hi all,
I have one problem, which has different possible solutions. I just wanted to know the simplest solution. Here is the problem:
Print the binary equivalent of a decimal number, without using:
  • Bit-wise operators
  • Conditional operators
  • Format specifier in printf function

Re:Simplest solution for this problem

Posted: Wed Sep 14, 2005 3:09 am
by Solar
NOTNULL wrote: I have one problem...
I know how I would solve that, but it awfully sounds like a homework assignment...?!?

How goes the saying?

"If I would solve it for you, you would pass your test without knowing how to do it, graduate without knowing how to do it, get a job without knowing how to do it, end up in my team without knowing how to do it. And then I would have to apply serious bodily harm..."

;-)

Hint: Think '% 2'.

Re:Simplest solution for this problem

Posted: Wed Sep 14, 2005 4:52 am
by NOTNULL
Solar wrote:
NOTNULL wrote: I have one problem...
"If I would solve it for you, you would pass your test without knowing how to do it, graduate without knowing how to do it, get a job without knowing how to do it, end up in my team without knowing how to do it. And then I would have to apply serious bodily harm..."
This is not my homework assignment or any. My friend just asked me it. I gave him one solution using '%', but, that seemed like a big solution to me. Many guys here will have different solution. That's why I posted it here.

Re:Simplest solution for this problem

Posted: Wed Sep 14, 2005 5:08 am
by Solar
I'm not sure what "no conditional operators" means (trinary ?: operator?), but ad hoc I came up with this:

Code: Select all

#include <stdio.h>

print_binary( int x )
{
    if ( x )
    {
        print_binary( x / 2 );
        putchar( '0' + ( x % 2 ) );
    }
}

int main()
{
    print_binary( 192 );
    return 0;
}
I can't come up with a way to remove the "if", though, right now.

Edit: And there you are... of course I got the recursion backwards the first time 'round. :-D

Re:Simplest solution for this problem

Posted: Wed Sep 14, 2005 5:50 am
by Solar
If you want absolutely no conditionals, you could go for this:

Code: Select all

char * table[] = { "000", "001", "010", "011", "100", "101", "110", "111" };
puts( table[x] );
This quickly gets out of hand with support for bigger values, though. ;)

Re:Simplest solution for this problem

Posted: Wed Sep 14, 2005 8:35 am
by zloba
without using: ..Conditional operators
you will have to use some kind of iteration or recursion, and you will need a conditional (explicit or implicit (such as a loop)) to decide when to stop.
unless you use a map of all possible integers to their strings, which get out of hand, as Solar said.

i wonders, what is the point of this?
---
solar: it seems your version #1 does not handle zero.
---

Code: Select all

void print_bin(int val){
    int high=val/2;
    if(high) // if there are higher-order digits, print them first
        print_bin(high);
    putchar('0'+val%2); // and the lowest digit
};

Re:Simplest solution for this problem

Posted: Wed Sep 14, 2005 8:48 am
by Solar
zloba wrote: solar: it seems your version #1 does not handle zero.
It does handle zero. It just doesn't print anything for zero. 8)

OK, reworked version:

Code: Select all

void print_binary( int x )
{
    if ( x > 1 )
    {
        print_binary( x / 2 );
    }
    putchar( '0' + ( x % 2 ) );
}
Yes, I do avoid local variables like the plague. 8)

Re:Simplest solution for this problem

Posted: Wed Sep 14, 2005 1:25 pm
by NotTheCHEAT
lol

The simplest method that should work for virtually any number uses % 2, then converts the binary number into it's ASCII equivalent.

Re:Simplest solution for this problem

Posted: Wed Sep 14, 2005 11:14 pm
by NOTNULL
NotTheCHEAT wrote: lol

The simplest method that should work for virtually any number uses % 2, then converts the binary number into it's ASCII equivalent.
That was the solution given by me using '%' and converting the remainder to character. But, just one question. If I define two bits in a structure like,

Code: Select all

struct bit_array   {
    unsigned int a1:1;
    unsigned int a2:1;
}; 
Will the bits stored next to each other or they take up eight bytes of memory?

Re:Simplest solution for this problem

Posted: Wed Sep 14, 2005 11:38 pm
by Freanan
They will take up the size of the two integers...
If you want to have a real bitmap, that only needs a bit to store a bit, you will need 1 byte for 8 bits (wow ;) ) and set the individual bits using bitwise operations.

Re:Simplest solution for this problem

Posted: Thu Sep 15, 2005 1:33 am
by Solar
Freanan wrote: They will take up the size of the two integers...
Erm... sorry but that's wrong.

ISO/IEC 9899:1999 (C99) sais in 6.7.2.1 "Structure and union specifiers", paragraph 10:
An implementation may allocate any addressable storage unit large enough to hold a bit field. If enough space remains, a bit field that immediately follows another bit field in a structure shall be packed into adjacent bits of the same unit. If insuddicient space remains, whether a bit field that does not fit is put into the next unit or overlaps adjacent units is implementation defined. The order of allocation of bit fields within a unit (high order to low order or low order to high order) is implementation defined. The alignment of the addressable storage unit is unspecified.
Or, if you prefer code:

Code: Select all

#include <stdio.h>

struct bit_array
{
    unsigned int a1:1;
    unsigned int a2:1;
};

int main()
{
    printf( "%d %d\n", sizeof( unsigned int ), sizeof( struct bit_array ) );
    return 0;
}
yields "4 4".

Re:Simplest solution for this problem

Posted: Thu Sep 15, 2005 2:08 am
by Candy
just for fun:

Code: Select all

struct bit_array  {
    unsigned int b[32]:1;
}; 

void print(bit_array x) {
    for (int i=31; i>=0; i--) {
        printf("%c", x.b[i] + '0');
    }
}
Although this doesn't really help. All you do is ask the compiler to generate the shifts and masks for you.