• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

zamiana liczby dziesiętnej na binarną

Object Storage Arubacloud
0 głosów
3,503 wizyt
pytanie zadane 14 maja 2016 w C i C++ przez Evelek Nałogowiec (28,960 p.)
edycja 14 maja 2016 przez Evelek

Zamieniam liczbę w systemie dziesiętnym na liczbę w systemie binarnym.

Mam taki oto działający program:

#include <iostream>
#include <cstdlib>
using namespace std;
void dec_to_bin(int liczba)
{
    int i = 0, tab[31];

    while(liczba)
    {
        tab[i++] = liczba % 2;
        liczba = liczba / 2;
    }
    for(int j = i-1; j >= 0; j--)
        cout << tab[j];
}
int main()
{
    int liczba;
    cin >> liczba;
    dec_to_bin(liczba);

    return 0;
}

Moje pytanie: dlaczego program ten nie działa, gdy 20 linijkę kodu zapiszę w taki sposób:

cout << dec_to_bin(liczba) << endl;

Czy związane jest to z tym, że nazwa funkcji nazywa się void i nie można jej wywoływać w cout ? Poprosiłym o wyjaśnienie.

5 odpowiedzi

+3 głosów
odpowiedź 14 maja 2016 przez Sebastian Fojcik Nałogowiec (43,020 p.)
 
Najlepsza

Bardzo dobrze to wydedukowałeś. Ostatni akapit Twojego pytania jest prawidłową odpowiedzią :-)
Pozostało mi więc już tylko udzielić Ci wyjaśnienia dlaczego.

Strumień cout służy do wypisywania na ekran konsoli różnych rzeczy. A dokładniej rzeczy, które mu tam prześlesz. cout  działa tak jak funkcja. Czyli przyjmuje argumenty typu: int, float, double, string, char itd.
void nie możesz przesłać do strumienia, bo to nie jest typ argumentu. To jest zapis stosowany przy funkcjach, które nie zwracają żadnej wartości.

Dlaczego więc taki zapis nie działa?
Strumień cout oczekuje jakiegoś argumentu. A Ty mu nic tam nie przesyłasz. Funkcja nie zwraca żadnej wartości. Spróbuj w swoim programie zrobić taki zapis:

cout <<     << endl;

Tak też nie można. Jeśli cout ma wypisać rezultat funkcji na ekranie, to owa funkcja musi coś zwracać :-)

komentarz 14 maja 2016 przez Evelek Nałogowiec (28,960 p.)
super, dzięki. :)
0 głosów
odpowiedź 14 maja 2016 przez konrad99 Gaduła (4,090 p.)
edycja 14 maja 2016 przez konrad99

Funkcja nie nazywa się void tylko zwraca voida a powinna coś co strumień umie zinterpretować np string.

#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
string dec_to_bin(int liczba)
{
    string k;
    int i = 0, tab[31];

    while(liczba)
    {
        tab[i++] = liczba % 2;
        liczba = liczba / 2;
    }
    for(int j = i-1; j >= 0; j--)
    {

        cout << tab[j];
        k=tab[j];
    }
        return k;

}
int liczba;
int main()
{
    cout<<"podaj_liczbe_do_obliczen"<<endl;
    cin>>liczba;

cout << dec_to_bin(liczba) << endl;

    return 0;
}

 

komentarz 14 maja 2016 przez Evelek Nałogowiec (28,960 p.)
Dzięki za uzupełnienie kodu. Też ciekawy sposób na wywołanie tego w cout jako string.
0 głosów
odpowiedź 18 czerwca 2016 przez niezalogowany

Znalazłem takie oto rekurencyjne rozwiązanie konwersji liczby dziesiętnej na  binarną

#include <cstdlib>
#include <iostream>
using namespace std;

void dec_to_bin(int liczba)
{
  if(liczba>0)
  {
    dec_to_bin(liczba/2); //przekazanie argumentu skróconego o jeden bit
    //zapisanie tej instrukcji jako drugiej, pozwoli na
    //wyswietlenie cyfr binarnych w prawidlowej kolejnosci
    cout<<liczba%2; //wyświetlenie cyfry binarnej
  }
}

int main()
{
  int liczba;
  cout<<"Podaj liczbe: ";
  cin>>liczba;
  cout<<"Postac binarna liczby "<<liczba<<": ";
  dec_to_bin(liczba);
  cout<<endl;
  system("pause");
  return 0;
}

Nie rozumiem tylko jak to ma działać. Dla mnie wygląda to tak:

liczba jest większa od 0 więc wywołujemy funkcję z nowym argumentem, który jest liczbą podzieloną całkowicie przez dwa i wypisujemy resztę z dzielenia (tylko nie wiem czy liczby, czy może jednak zmniejszonej liczby). Tak czy inaczej, w ten sposób powinny być wypisywane 0 i 1 od góry do dołu, a nie w odwróconej kolejności. Może ktoś łopatologicznie wytłumaczyć mi jak działa przedstawiony kod? (najlepiej podać przykładowe liczby i wyjaśnić krok po kroku co się dzieje).

 

I przy okazji systemów liczbowych, ktoś wytłumaczyłby dlaczego moja funkcja zamieniająca postać dziesiętną liczby na piątkową(lub jakąkolwiek inną, wystarczy tylko zmienić dwie linijki kodu) nie działa tak jak trzeba i zwraca najczęściej wartość o 1 lub nawet o 2 mniejszą niż powinna? Próbowałem sam do tego dojść analizując kod krok po kroku, ale nic nie wymyśliłem.

#include <iostream>
#include <cmath>

using namespace std;

int na_piatkowy(int l)
{
    int cyfry[100],j=0,piatkowo=0;

    while (l>0)
        {
        cyfry[j] = l%5;
        l = l/5;
        j++;
        }

    for (int i=0; i<j; i++)
        {
        piatkowo = piatkowo + (cyfry[i] * pow(10,i));
        }
    return piatkowo;
}

int main()
{
    int liczba;
    cin >> liczba;
    cout<<na_piatkowy(liczba);
    return 0;
}

 

0 głosów
odpowiedź 18 czerwca 2016 przez obl Maniak (51,280 p.)

Po co funkcję pisać, jak jest już gotowa systemowa?

/* itoa example */
#include <stdio.h>
#include <stdlib.h>

int main ()
{
  int i;
  char buffer [33];
  printf ("Enter a number: ");
  scanf ("%d",&i);
  itoa (i,buffer,10);
  printf ("decimal: %s\n",buffer);
  itoa (i,buffer,16);
  printf ("hexadecimal: %s\n",buffer);
  itoa (i,buffer,2);
  printf ("binary: %s\n",buffer);
  return 0;
}

 

komentarz 18 czerwca 2016 przez Evelek Nałogowiec (28,960 p.)
Ja piszę w C++ a ty napisałeś w C.
0 głosów
odpowiedź 18 czerwca 2016 przez CharlieGG Użytkownik (900 p.)
edycja 18 czerwca 2016 przez CharlieGG

Źródłem problemu przez który Twoja funkcja nie zwraca poprawnych wartości jest funkcja "pow()", ponieważ zwraca ona wartość w typie zmiennoprzecinkowym (double), co dalej czasem prowadzi do problemów w dalszym rzutowaniu na inta, ponieważ nasz kochany C++ miewa problemy z zaokrąglaniem liczb zmiennoprzecinkowych. Aby naprawić ten problem, można albo ztablicować kolejne potęgi 10, albo użyć myku, którego ja osobiście używam i moim zdaniem jest o wiele wygodniejszy od używania pow(). Używając mojego podejścia Twoja funkcja wygląda tak:

int na_piatkowy(int l)
{
    int cyfry[100],j=0,piatkowo=0;
 
    while (l>0)
        {
        cyfry[j] = l%5;
        l = l/5;
        j++;
        }
 
    for (int i = j - 1; i >= 0; i--)
        {
        piatkowo = (piatkowo * 10) + cyfry[i];
        }
    return piatkowo;
}

W skrócie "tworzymy" końcową liczbę od lewej do prawej, czyli od największych rzędów wielkości do najmniejszych.

Co do pierwszego to kluczem do zrozumienia tego podejścia do zamiany systemu liczbowego, jest zrozumienie reprezentacji liczby w danym systemie liczbowym oraz tego jak "działa" dzielenie liczby przez podstawę danego systemu liczbowego. Weźmy pod lupę liczbę 13 i jej reprezentacje binarną czyli 1101. Na początku ustalmy jedną dosyć oczywistą rzecz, a mianowicie, aby pozyskać wartość ostatniego bitu danej reprezentacji wystarczy użyć działania modulo (liczba modulo podstawa systemu). Wiemy już jak "wyciągnąć" ostatni bit danej liczby, ale teraz chcielibyśmy umieć to robić dla dowolnego bitu liczby. Na ratunek przychodzi nam dzielenie przez podstawę systemu! Gdy podzielimy te przykładowe 13 przez 2 otrzymamy 6, które to w binarnym jest równe 110. Co możemy zauważyć to, to iż dzielenie niejako "ucięło" nam ostatni bit, i jest to prawidłowa obserwacja, gdyż dzielenie liczby (bez reszty) przez podstawę systemu jest adekwatne do usunięcia ostatniego bitu i przesunięciu wszystkich pozostałych na wcześniejsze miejsce (tłumacząc mocno łopatologicznie). No ale co daje nam takie "ucinanie" kolejnych bitów? To raczej oczywiste, skoro ucinamy kolejne bity, to "odsłaniamy" te "głębsze" dzięki czemu możemy je "wyciągnąć" używając działania modulo. Tak więc w wielkim skrócie używając modulo poznajemy wartość ostatniego bitu liczby, a dzielenie umożliwia nam usuwanie ostatniego bitu, bez zmiany kolejnych. Tak więc to co robi znaleziony przez ciebie kod to po prostu "ucinanie" wszystkich możliwych bitów, aż dojdziemy do końca (liczba będzie zerem), a następnie "wyciągamy" wartości bitów dzięki modulo.

Podobne pytania

0 głosów
1 odpowiedź 960 wizyt
0 głosów
2 odpowiedzi 667 wizyt
pytanie zadane 21 kwietnia 2020 w C i C++ przez tomes235 Początkujący (320 p.)
0 głosów
1 odpowiedź 9,104 wizyt
pytanie zadane 17 października 2016 w C i C++ przez kakola3 Początkujący (270 p.)

92,551 zapytań

141,393 odpowiedzi

319,523 komentarzy

61,936 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...