1

for example, if I enter 12, I want to get 81 41 as the set bits in 12 are 1100

This is what I have for now, I do not think I am implementing the for loop correctly

#include <stdio.h>
void bin(unsigned n)
{
    char list[6]; 
    int x = 0, y = 1;
    /* step 1 */
    if (n > 1)
        bin(n / 2);
 
    /* step 2 */
    list[x] = n % 2;
    x++;
    /*for(int i = 0; i < x; i++) {
        printf("%d\n",list[i]);
    }*/
    for(int i = 0; i < 5; i++) {
          if(list[i] == 1 && i == 5) {
           printf("32%i",y);
          }
          if(list[i] == 1 && i == 4) {
             printf("16%i",y);
          }
          if(list[i] == 1 && i == 3) {
             printf("8%i",y);
          }
          if(list[i] == 1 && i == 2) {
             printf("4%i",y);
          }
          if(list[i] == 1 && i == 1) {
             printf("2%i",y);
          }
          if(list[i] == 1 && i == 0) {
             printf("1%i",y);
          }
}
}

I checked that I was correctly storing the bytes in the array, and it outputted correctly, but when I try to look for them one at a time in a loop, it seems to get stuck on the 32 bit integer, so for 12, it would print 321 321

  • Are you sure about `list[i] = 1` as a condition? Doesn't your compiler complain about that? And due to [operator precedence](https://en.cppreference.com/w/c/language/operator_precedence) `list[i] = 1 && i == 5` is actually `list[i] = (1 && i == 5)` which is unlikely what you want. – Some programmer dude Nov 01 '22 at 01:58
  • I fixed that... now, for instance, when I enter 12, I get 11 11. seems like it didnt fix the issue – Abyss Auction Nov 01 '22 at 02:01
  • I recommend that you use a [*debugger*](https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems) to step through your code line by line while monitoring variables and their values. – Some programmer dude Nov 01 '22 at 02:11

1 Answers1

0

This program has Undefined Behaviour from accessing uninitialized values of list. I'm going to refactor this code so its easier to talk about, but know this refactored code is still incorrect.

x is always 0. y is always 1. x++ has no effect. This function can be rewritten as:

void bin(unsigned n)
{
    char list[6];

    if (n > 1)
        bin(n / 2);

    list[0] = n % 2;

    for (int i = 0; i < 5; i++) {
        if (list[i] == 1) {
            switch (i) {
                case 5: printf("321"); break;
                case 4: printf("161"); break;
                case 3: printf("81"); break;
                case 2: printf("41"); break;
                case 1: printf("21"); break;
                case 0: printf("11"); break;
            }
        }
    }
}

There are some problems here.

Firstly, list is not shared between calls to bin, nor are any other variables.

In every call to bin, only list[0] is assigned a value - all others indices contain uninitialized values. You are (un)lucky in that these values are seemingly never 1.

With your example of 12 as the starting value:

When you initially call bin(12), what happens is:

bin(12) calls bin(6), bin(6) calls bin(3), bin(3) calls bin(1).

Starting from the end and working backwards, in bin(1):

n = 1, so list[0] = n % 2; assigns 1. The loop checks each element of list for the value 1, finds it when the index (i) equals 0, and prints 11.

This is repeated in bin(3), as 3 % 2 is also 1, and again this result is assigned to the first element of list. Again, we print 11.

In bin(6), 6 % 2 is 0. The loop finds no elements of list that equal 1. Nothing is printed.

And again, this is repeated in bin(12), as 12 % 2 is 0. Nothing is printed.

To reiterate, it is pure luck that this program appears to work. Accessing list[1] through list[4] (i < 5 ensures you never access the last element) in each function call is Undefined Behaviour. It is generally not worth reasoning about a program once UB has been invoked.


When dealing with bits, it would be a good time to use some bitwise operators.

Here is a program that more-or-less does what you have described.

It assumes 32-bit unsigned (consider using fixed width types from <stdint.h> to be more precise).

This program works by repeatedly shifting the bits of our initial value to the right b number of places and testing if the rightmost bit is set.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    unsigned num = argc > 1 ? atoi(argv[1]) : 42;
    unsigned b = 32;

    while (b--)
        if ((num >> b) & 1)
            printf("%u1 ", 1 << b);

    putchar('\n');
}
$ ./a.out 12
81 41
Oka
  • 23,367
  • 6
  • 42
  • 53