C – Conversia unui număr întreg în tablou binar (Programare, C, Array-Uri, C Dinamic)

Fei Hap Lee a intrebat.

Sunt foarte nou în limbajul C. Voi avea nevoie de un mic program pentru a converti int în binar, iar binarul să fie de preferință stocat într-un array, astfel încât să le pot despărți în continuare pentru decodare.Am următoarele:

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

int main()
{
    int arr[20];
    int dec = 40;
    int i = 0, ArrLen;

    if(dec > 0)
    {
        while(dec > 0)
        {
            arr[i] = dec % 2;
            i++;
            dec = dec / 2;
        }
    }
    else
    {
        printf("Invalid Number");
    }
}

Din codul de mai sus, pot stoca binarul în arr.dar în loc să obțin echivalentul binar: 101000, , matricea este acum ca {0, 0, 0, 1, 0, 1}, , care este inversat a răspunsului corect.Așadar, întrebarea este cum să obținem un array în ordinea corectă sau, eventual, să îl întoarcem?Am un lucru sigur, și anume că lungimea maximă a array-ului nu va depăși 8 elemente.

Această conversie va fi folosită în mod repetat.Așa că plănuiesc să o pun într-o funcție, astfel încât să pot apela funcția, să trec un număr întreg și apoi să obțin matricea ca valoare de retur. Deci, o altă întrebare este: este fezabil să obțin un array ca valoare de retur?

Comentarii

  • Începeți prin a vă gândi cum ați face acest lucru manual. Apoi treceți-o în cod. Apropo, valoarea dintr-un int este deja binară. Există multe moduri diferite de a face acest lucru, mai ales dacă vă aplecați asupra a ceea ce știți despre modul în care calculatoarele stochează datele. Dar bănuiesc că aceasta este o temă pentru un curs, deoarece este ceva ce majoritatea școlilor te pun să faci devreme. –  > Por ydobonebi.
  • HI Quinn, aceasta nu este o temă oricum. Sunt mult după școală. Doar că de fapt fac mai mult pe C#, PHP & JAVA. Nu orice limbaj C. Tipărirea ca BINARY este ușor de la un int, dar pentru a le stoca, nu pot prinde nici o minge încă. –  > Por Fei Hap Lee.
  • Nu puteți trece un array în C. Trebuie să malloc în funcție și să returnezi un pointer la adresă. –  > Por M. Shaw.
  • ideone.com/Woyw8H –  > Por Kaustav Ray.
  • @M.Shaw struct R { unsigned char ar[8]; }; struct R func(int value) { struct R r; .... return r; } – Dacă îngropați o matrice fixă într-o struct, , veți poate să îl returnezi prin valoare. Compilatorul va genera codul corespunzător pentru a face acest lucru dacă este întrebat. Dacă acest lucru este necesar sau de dorit pentru această sarcină este o altă problemă. –  > Por WhozCraig.
8 răspunsuri
Johnny Cage

Puteți parametriza matricea folosind un pointer la int. Poate fi util să parametrizezi și numărul de cifre.

void int_to_bin_digit(unsigned int in, int count, int* out)
{
    /* assert: count <= sizeof(int)*CHAR_BIT */
    unsigned int mask = 1U << (count-1);
    int i;
    for (i = 0; i < count; i++) {
        out[i] = (in & mask) ? 1 : 0;
        in <<= 1;
    }
}

int main(int argc, char* argv[])
{
    int digit[8];
    int_to_bin_digit(40, 8, digit);
    return 0;
}

Comentarii

  • Minor: /* assert: count <= sizeof(unsigned)*CHAR_BIT && count > 0 */.  > Por chux – Reintroduceți Monica.
  • @chux Am fost pe muchie de cuțit în legătură cu sizeof(?), , deoarece evaluează un tip cu semn și face doar casting la unsigned pentru a folosi un shift logic. A count de zero nu ar trebui să fie semnalată ca o eroare, dar mai puțin de zero este probabil o greșeală. În practică count ar trebui să fie fără semn. –  > Por Johnny Cage.
  • Asserting count>0 ajută la ca count == 0 este o problemă cu 1U << (count-1);. Notă count nu este transformat în unsigned în ` 1U << (count-1)`. –  > Por chux – Reintroduceți-o pe Monica.
Martin James

sau recursivă V2.0:

#include <stdio.h>

char *binaryToAbits(unsigned int answer, char *result) {
  if(answer==0) return result;
  else {
    result=binaryToAbits(answer>>1,result);
    *result='0'+(answer & 0x01);
    return result+1;
  }
}

int main(void) {
    unsigned int numToConvert=0x1234ABCD;
    char ascResult[64];
    *binaryToAbits(numToConvert,ascResult)='';
    printf("%s",ascResult);
    return 0;
}

Notă, mulțumită lui @chux, iată o funcție recursivă mai bună care se ocupă de cazul conversiei 0 – scoate „0” în loc de „”:

char *binaryToAbits(unsigned int answer, char *result) {
  if(answer>1) {
    result=binaryToAbits(answer>>1,result);
  }
  *result='0'+(answer & 0x01);
  return result+1;
};

Comentarii

  • 1) numToConvert=0 –> "" în loc de "0". 2) Cu siguranță 64 suficient pentru 0x1234ABCD, , dar m-aș aștepta la 65 sau 33. –  > Por chux – Reinstaurați-o pe Monica.
  • @chux – sigur, dar asta ar necesita o altă funcție pentru a verifica dacă există 0. Destul de ușor, doar că nu m-am deranjat cu asta. Dimensiunea bufferului: M-am gândit la 32, apoi la 33 pentru nul, apoi am rotunjit la 64:) –  > Por Martin James.
  • „necesită o altă funcție pentru a verifica dacă există 0”. Hmmm, poate o mică rescriere în schimb: if (answer > 1) {result=binaryToAbits(answer>>1,result); } *result='0'+(answer & 1); return result+1; Oarecum simplu și totuși, se ocupă 0 bine. –  > Por chux – Reintroduceți-o pe Monica.
  • @chux bună idee! Cu permisiunea ta, aș edita-o și aș adăuga o atribuție. –  > Por Martin James.
  • De fapt, la naiba, o voi adăuga oricum. Dacă te opui, o voi șterge, sau o poți face tu:) –  > Por Martin James.
Marcelo de Mattos Nascimento

Același răspuns ca și Johnny Cage, cu adăugarea unei funcții pentru a obține lungimea unei cifre.

#include <math.h>

int bit_len(unsigned int n){
   return floor(log(n)/log(2))+1;
}
void int_to_bin_digit(unsigned int in, int len_digitis,int* out_digit){

  unsigned int mask = 1U << (len_digitis-1);
  int i;
  for (i = 0; i < len_digitis; i++) {
    out_digit[i] = (in & mask) ? 1 : 0;
    in <<= 1;
  }
}

int main(int argc, char* argv[]){
   int number = 30;
   int len = bit_len(number);
   int digits[len];
   int_to_bin_digit(number,len, digits);
   for( int i =0;i<len;i++){
       printf("%d",digits[i]);
   }
  return 0;
 }

ydobonebi

Folosind logica bitwise :

for(int i = 0 ; i < 8 ; i++)
{
    bytearray[i] = inputint & pow(2,7-i);
}

Comentarii

  • Ați putea face mai repede cu exploatarea uniunilor și structurilor C btw. –  > Por ydobonebi.
  • sizeof(int) este 4, nu 8. –  > Por M. Shaw.
  • Și ar trebui să fie pow(2, 7-i) pentru ca matricea să nu fie inversată. –  > Por M. Shaw.
  • @M.Shaw Oops, am fost entuziasmat de biți și am uitat că sizeof este mai mult în bytes –  > Por ydobonebi.
  • sizeof(int) * 8 este de 32. OP a spus the maximum array length will not exceed 8 elements. –  > Por M. Shaw.
TryinHard

Acest lucru poate fi util:

void binary(unsigned n)
{
    unsigned i;
    for (i = 1 << 31; i > 0; i = i / 2)
        (n & i)?`/*STORE 1*/` : `/*STORE 0*/` ;
}

Comentarii

  • Notă: Este mai bine să folosiți 1u << 31 ca 1 << 31 este un comportament nedefinit cu 32 de biți int. –  > Por chux – Reintroduceți-o pe Monica.
M. Shaw

Încercați ceva de genul acesta:

uint8_t * intToBin(int x) {
    uint8_t *bin = (int *) malloc(8);
    uint8_t i = 0;
    int mask = 0x80;
    for (i = 0; i < 8; i++) {
        bin[i] = (x & mask) >> (7-i);
        mask >>= 1;
    }
    return bin;
}

Includeți <stdint.h> pentru declarația de uint8_t.Remember pentru free malloc-ed de memorie dacă nu doriți scurgeri de memorie.

Comentarii

  • Nu este suficientă memorie int *bin = (int * ) malloc(8); –> int *bin = malloc(8 * sizeof *bin); –  > Por chux – Reintroduceți-o pe Monica.
  • @chux OP are nevoie de 8 biți stocați într-o matrice. Probabil că ar trebui să schimb tipul de bin în unsigned char sau uint8_t în schimb. OP are nevoie de 8 biți, iar eu aloc deja 64. Nu există niciun motiv pentru care aș avea nevoie de 256 de biți de memorie pentru a stoca 8 biți de date. –  > Por M. Shaw.
  • „OP are nevoie de 8 biți, iar eu aloc deja 64” nu este corect. Codul aloca 8 ca în malloc(8), , ceea ce cu siguranță era o memorie insuficientă pentru 8 int – de unde și comentariul. IAC, compania malloc(8) acum este suficientă memorie pentru 8 uint8_t. Dar acum are o nouă problemă: returnarea unui uint8_t * care este transformat în int *. Cu 4 octeți int, codul de apelare ar putea face referire la primii 2 din int* array, dar cu siguranță OP se aștepta la 8. –  > Por chux – Reintroduceți-o pe Monica.
takasoft

Acest lucru ar trebui să funcționeze.

#include <stdio.h>

void intToBin(int dec, int bin[], int numBits){
    for(int i = 0; i < numBits; i++){
        bin[i] = 1 & (dec >> i);
    }
}

void printArr(int arr[], int arrSize){
    for(int i = 0; i < arrSize; i++) {
        printf("%d ", arr[i]);
    }
}

int main(int argc, char* argv[]){
    int bin[32];
    intToBin(-15, bin, 32); 
    printArr(bin, 32);
}

Kaustav Ray

Implementare recursivă:

(Deoarece nu puteți avea o idee prealabilă a numărului de cifre (0/1) în formatul binar al numărului dat).

int arr[200]; //for storing the binary representation of num
int i=0; // to keep the count of the no of digits in the binary representation

void calBinary(int n) // function to recalculate
{
   if(n>1)
      calBinary(n/2);
   arr[i++]=n%2;
}

Comentarii

  • Matricea dvs. va fi în continuare inversată. –  > Por M. Shaw.
  • @KaustavRay posibil pentru că recursivitatea vine de obicei cu lipsa efectelor secundare, dar aceasta nu este lipsită de efecte secundare –  > Por DanZimm.
  • Da, este adevărat! Este întotdeauna mai puțin eficient, dar nu a fost nicăieri greșit! Oricum, am învățat! 🙂 –  > Por Kaustav Ray.