[ANSI C] Zamiana z systemu binarnego na dziesiętny


(Daniel K.) #1

Mógłby mi ktoś podpowiedzieć jak zapisać liczbę w systemie binarnym podawaną z klawiatury przez użytkownika, tak aby później poszczególne cyfry (z których składa się liczba binarna) mogły być mnożone przed podstawę do dopowiedniej potęgi?


(Bionicman) #2

Robiłem coś takiego w C++, ale za pomocą operatora przesunięcia binarnego bodajże.


(Airborn) #3

na początku sczytujesz sobie po prostu liczbę do zmiennej (można też od razu do tabeli ale jakoś tak mi bardziej pasuje osobiście). możesz sobie rozbić liczbę na poszczególne bity:

liczba=101101010;

i=0;

while(liczba!=0){

tab[i]=liczba%2;

liczba/=2;

i++;

}

po czymś takim masz tablicę która zawiera wszystkie bity w osobnych komórkach (w komórce indeksowanej przez 0 masz najmniej znaczący bit) teraz wystarczy każdą taką komórkę wymnożyć przez dwójkę z odpowiednim wykładnikiem (podpowiedź: zobacz jaka jest zależność pomiędzy wykładnikiem a indeksem tabeli)


(Ryan) #4

Airborn: co Ty za herezje wypisujesz? O_o liczba=101101010; przecież podstawi wartość sto jeden milionów sto jeden tysięcy dziesięć do zmiennej (Bóg wie jakiej, bo nie określiłeś typu). I po co tabela?

Konwersja jest prosta, tylko trochę nieprecyzyjnie napisałeś o co chodzi (sugeruję podawć przykłady następnym razem).

Zakładam, że używasz gets (którego nie powinieneś używać). Postawię też komentarze gdzie piszę używając złych praktyk.

Zakładam, że użytkownik wpisuje z klawiatury wartość, którą odczytujesz jako string.

Zakładam, że pozwalasz na znaki inne niż 1 czy 0 w ciągu i pierwszy napotkany kończy analizę ciągu znaków.

#include 


// zdefiniuję dużo za duzy bufor - zła praktyka

#define SIZE 64


#define VALID_BINARY_CHAR(c) ( (c == '0') || (c == '1') )

#define WHITE_CHAR(c) ( (c == '\t') || (c == '\r') || (c == '\n') || (c == ' ') )


int main(int argc, char *argv[])

{

  int i = 0;

  int result = 0;

  char buf[SIZE];


  gets(buf); // potencjalne przepełnienie bufora i iniekcja kodu - zła praktyka

  buf[SIZE - 1] = '\0';


  for (i = 0; (i < SIZE) && (VALID_BINARY_CHAR(buf[i])) && (!WHITE_CHAR(buf[i])); ++i)

  {

    if ((result << 1) < result)

    {

      // przepełnienie arytmetyczne - obsłuż błąd

      printf("Przepełnienie arytmetyczne\n");

      return 1; // więcej niż dwa punkty w których opuszcza się funkcję - zły nawyk

    }

    result <<= 1; // pomnóż przez dwa

    result += (buf[i] == '1' ? 1 : 0);

  }


  // zmienna result zawiera wynik

  printf("%d\n", result);


  return 0;

}

(Airborn) #5

durne przyzwyczajenie z php ;/


(Ryan) #6

Ok, ja rozumiem do czego Tobie służy, ale po co w ogóle w algorytmie posługiwać się tabelą? Takie operacje można wykonywać in-place i nie trzeba tworzyć tabel.