Matrix initialization not working from a given line

Asked

Viewed 60 times

0

I need to initialize a matrix that contains the binary values from 0 to the input value, which in this case is 15. The base conversion and the storage of these values works well until the number 8. However, from the 9 line, where the last digit should be 1, only zero is printed and this remains until the end of execution. Here’s the code I’m using:

    int conversor(entrada)
{
    aux1=entrada;
    do
    {
        /*
        Na função usei o modelo da divisão continua para converter um número, que se dá da seguinte maneira:
        Usando um inteiro na base decimal, é divido constantemente até que o divisor de zero
        O resto de cada uma dessas divisões é apenas 0 ou 1, e ordendando da direita para a esquerda,
         o resultado é em binario
        */
        for (i=entrada; i>=0; i--)
        {
            do
            {
                if (aux==0)
                {
                    saida[i][aux]=entrada%2;
                    divisor=entrada/2; //Primeira iteração, usa o valor de entrada ainda
                }
                else
                {
                    saida[i][aux]=divisor%2;
                    divisor=divisor/2; //Termina de dividir o numero
                }
                aux++; //Proxima coluna
            }
            while (divisor>0); //Faz a conta enquanto o divisor for maior que zero
        }
        entrada--; //Passa para proxima linha
        aux=0; //Zera auxiliar
    }
    while (entrada>0);

    for (j=0; j<=aux1; j++)
    {
        for (i=3; i>=0; i--)
        {
            printf ("%d ",saida[j][i]);
        }
        printf("\n");
    }
}

And here is the result:

Resultado do Código

I have tried to test array initialization only to contain the binary value of 9, 1001, separately but when I run this function this error happens. What I’m doing wrong?

2 answers

2


Since C is a relatively low-level language, the simplest way to solve this problem is through bit manipulation.
This problem, although easy, is not trivial. So to create a solution it is necessary to follow an organized reasoning. That’s what I documented in the code.

#include <stdio.h>

int main()
{
  // numero que vai ser analisado
  int n;

  // numero de bits em uma variavel int (normalmente 32)
  int n_max_bits = 8 * sizeof(int);

  // numero de bits em um valor, desconsiderando bits zero 'a esquerda
  int n_bits_in_number = n_max_bits;

  // exemplo:
  // 0  -->  n_bits_number=0  000..000000
  // 1  -->  n_bits_number=1  000..000001
  // 2  -->  n_bits_number=2  000..000010
  // 3  -->  n_bits_number=2  000..000011
  // 4  -->  n_bits_number=3  000..000100
  // 5  -->  n_bits_number=3  000..000101
  // 6  -->  n_bits_number=3  000..000110
  // 7  -->  n_bits_number=3  000..000111
  // 8  -->  n_bits_number=4  000..001000
  // etc

  // uso geral em loops, etc
  int i, j;

  // uso como mascara de bits
  unsigned int bitmask;

  printf("*\n");
  printf("* n_max_bits=%d\n", n_max_bits);
  printf("*\n");
  printf("* digite valor: ");
  scanf("%d", &n);

  // conta numero de bits a considerar no  valor
  // bitmask e' inicializado como 100000...000
  // a cada iteracao bitmask vai ser deslocado a direita
  // 100000...000 --> 010000...000 --> 001000...000 --> etc
  bitmask = 1 << (n_max_bits - 1);
  for (i = 0; i < n_max_bits; i++)
  {
    // printf("* bitmask=%08X\n", bitmask);
    if (n & bitmask)
      break;
    n_bits_in_number--;
    bitmask >>= 1;
  }

  printf("* numero de bits a considerar no valor: %d\n", n_bits_in_number);

  // ok, agora vamos mostrar a sequencia
  // 000...000
  // 000...001
  // 000...010
  // etc
  // ate' chegarmos no numero que foi digitado
  // (nao vou colocar em "matriz", raramente isso e' utilizado em C na vida real)
  for (i = 0; i <= n; i++)
  {
    printf("* ");
    bitmask = 1 << (n_bits_in_number - 1);
    for (j = 0; j < n_bits_in_number; j++)
    {
      // printf("(bitmask=%08X)", bitmask);
      printf("%c", (i & bitmask) ? '1' : '0');
      bitmask >>= 1;
    } // for j
    printf("\n");
  } // for i

}

Now, some examples of usage. Note that the value 0 shows nothing because it has no bit in 1.

[~/Projects/testes/so]
$./376830
*
* n_max_bits=32
*
* digite valor: 0
* numero de bits a considerar no valor: 0
* 

[~/Projects/testes/so]
$./376830
*
* n_max_bits=32
*
* digite valor: 1
* numero de bits a considerar no valor: 1
* 0
* 1

[~/Projects/testes/so]
$./376830
*
* n_max_bits=32
*
* digite valor: 2
* numero de bits a considerar no valor: 2
* 00
* 01
* 10

[~/Projects/testes/so]
$./376830
*
* n_max_bits=32
*
* digite valor: 3
* numero de bits a considerar no valor: 2
* 00
* 01
* 10
* 11

[~/Projects/testes/so]
$./376830
*
* n_max_bits=32
*
* digite valor: 4
* numero de bits a considerar no valor: 3
* 000
* 001
* 010
* 011
* 100

[~/Projects/testes/so]
$./376830
*
* n_max_bits=32
*
* digite valor: 5
* numero de bits a considerar no valor: 3
* 000
* 001
* 010
* 011
* 100
* 101

[~/Projects/testes/so]
$
  • I liked the way you show only the required bits, and still not using -lm

  • 1

    in Linux, -lm is only when using certain mathematical functions, the code you showed does not need -lm

0

Dude, your code is really hard to read and analyze, because in the sample no variable is initialized except for the entrada and aux1 so I had to assume the behavior of the code. That said, I did a function using the same strategy and compared it to your code:

void conversor(int entrada) {

   int m,n;// número de linhas e colunas repectivamente
   m = entrada + 1;
   /*
   *   essa fórmula encontra a quatidade de bits necessarias para
   *   armazenar a entrada, que nesse caso é sempre maior número,
   *   que será o número máximo de colunas que precisaremos
   */
   n = (int)floor(log(entrada)/log(2)) + 1;
   int M[m][n], i, j, atual;
   for(i = 0; i < m; i++) {
      atual = i;// atual será o número que estaremos convertendo
      for(j = n-1; j >= 0; j--) {
         /*
         *   está percorrendo a linha da direita para a esquerda
         *   por que após a divisão continua devemos usar essa ordem
         */
         M[i][j] = atual%2;
         atual /= 2;
      }
   }
   for(i = 0; i < m; i++) {
      for(j = 0; j < n; j++) {
         printf("%d ", M[i][j]);
      }
      printf("\n");
   }
}

and I’ve come to the conclusion that the mistake is in do while external and in use of the variables aux and entrada in that loop. Could not reach the exact conclusion, because as I said I had to assume the behavior of the code without knowing the value of some of the variables.

  • 1

    liked the formula, Voce could use too n = (int)floor( log2( entrada ) ) + 1;

Browser other questions tagged

You are not signed in. Login or sign up in order to post.