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

Przeliczanie liczby binarnej na dziesiętną, operując na tablicach.

Object Storage Arubacloud
0 głosów
2,830 wizyt
pytanie zadane 22 czerwca 2017 w Algorytmy przez Dash Nałogowiec (29,650 p.)
edycja 22 czerwca 2017 przez Dash
Muszę zamienić w programie pewną funkcję, przeliczającą wartość binarną na dziesiętną. Argument funkcji to tablica zawierająca liczbę w postaci tablicy, np. liczba 1011 jest podawana jako tablica czteroelementowa* [1,0,1,1]. Obecnie funkcja zwraca liczbę w postaci liczby całkowitej (integer), a muszę przerobić to tak, aby zwracała liczbę w postaci tablicy (czyli analogicznie do tego jak argument który przyjmuje).
Przykład:

Wejście: tablica liczb całkowitych [1,0,1,1]  Wyjście: tablica liczb całkowitych [1,1]

Przeliczanie na liczbę a następnie przekładanie liczby na tablice nie wchodzi w grę, ponieważ operuję na wartościach które nie mogą zostać zapisane pod postacią jednej zmiennej. Znacie odpowiedni algorytm? Dzięki z góry :).

# Edit: cztero a nie trzyelementowa. Liczyć nie umiem a się za algorytmy biorę :P.
1
komentarz 22 czerwca 2017 przez Eryk Andrzejewski Mędrzec (164,260 p.)

tablica trzyelementowa [1,0,1,1].

laugh

komentarz 22 czerwca 2017 przez X3h Dyskutant (9,540 p.)
Jaki język?
komentarz 22 czerwca 2017 przez Dash Nałogowiec (29,650 p.)
Docelowo Lua albo C/C++, zależnie od wydajności. Ale zasadniczo mogę dostać algorytm w czymkolwiek popularnym , miałem do czynienia z wieloma językami (rodzina C, Lua, JS, Fortran, Python,Java itd.),  dam radę sobie przepisać :).

1 odpowiedź

+2 głosów
odpowiedź 23 czerwca 2017 przez Buby Pasjonat (19,590 p.)
wybrane 23 czerwca 2017 przez Dash
 
Najlepsza

Hej smiley Wykonałem algorytm o który prosiłeś - a przynajmniej tak mi się wydaję. Rozumiem, że piszesz jakąś klasę typu VLI [Very Large Integer]?

Aby wykonać to zadanie spróbowałem odwrócić algorytm, którym można zamienić dowolną liczbę dziesiętną na binarną, tj. wykorzystujący modulo i odwracanie wyników. Aby zamienić 11 na system binarny wykonujemy następujące kroki:

11 mod 2 = 1

5 mod 2 = 1

2 mod 2 = 0

1 mod 2 = 1

Przepisujemy od dołu i uzyskujemy 11_dec = 1011_bin

 

Aby odwrocić to działanie początkowo posłużyłem się czymś takim. Mam dwie tablice, bin[] zawierającą cyfry binarne i dec[], w której zapiszę cyfry dziesiętne. Poczyniłem założenie dla uproszczenia, że ich rozmiary są jednakowe. Zauwazmy, że pozycja binarna k, może modyfikować maksymalnie pozycję (zaokrągl.w.dół(log_10 z 2^k)), co korzystajac z wzorów na logarytmy mogę zapisać jako zaokrągl.w.dół(k * log_10 z (2)). Lista kroków:

1. Przemnóż wszystkie pola tablicy dec[] od (n-1) do (n-k) przez 2.

2. Jeśli cyfra binarna to 1, dodaj 1 do ostatniej pozycji w tablicy [najmniej znaczący bit liczby]

3. Sprawdz czy któreś pole jest większe bądź równe 10, jeśli tak, to pole %= 10, a poprzedzająca ją cyfra zostaje zwiększona o 1. [tez dla zakresu dec[n-1] do dec[n-k].

Zauważmy, że co obrót pętli wystarczy dodawać do k wartość logarytmu zapisaną jako stałą, bo wynika to z wzorów dla logarytmów.

A teraz kod - może on objaśni więcej:

#include <iostream>
#include <cstdint> //wybralem int8_t, bo wystarczy, aby przechowac cyfre od 0 do 9

constexpr long double LOG_10_OF_2 = 0.301029996;

int8_t* convertBinToDec(int8_t bin[], int8_t dec[], size_t n) {
    long double k = 0; //ogranicznik iteracji, bo chcemy oszczedzac pozycje
    for (size_t i = 0; i < n; ++i) { //dla tablicy liczb binarnych
        for (size_t j = 0; j <= k; ++j) { //dla indexow od n-1 do n-(floor(k))
            dec[n-j-1] *= 2; //przemnoz wynik * 2
        }
        if (bin[i]) { //jesli binarna cyfra to 1, to zwieksz ostatnia cyfre o 1
            dec[n-1]++;
        }
        for (size_t j = 0; j <= k; ++j) {
            if (dec[n-j-1] >= 10) { //sprawdz, czy ktoras cyfra nie wychodzi poza zakres
                dec[n-j-1] %= 10; //obsluz ten przypadek
                dec[n-j-2]++; //zwieksz poprzedzajaca cyfre o 1
            }
        }
        k += LOG_10_OF_2; //korzystajac z prawa logarytmow zwiekszam max zassieg na jaki wplywa cyfra binarna
    }
    return dec; //wg konwencji zwracam tablice ktora modyfikuje
}


int main() {
    constexpr size_t BITS = 4;
    int8_t src[BITS] = {1, 0, 1, 1};
    int8_t dest[BITS] = {}; //inicjalizacja zerami przy pomocy domyslnego konstruktora typu numerycznego

    for (auto& b : src) {
        std::cout << (int)b;
    }
    std::cout << "_bin = ";
    convertBinToDec(src, dest, BITS);
    for (auto& d : dest) {
        std::cout << (int)d;
    }
    std::cout << "_dec" << std::endl;
    return 0;
}

W razie pytań pisz - być może trochę zagmatwałem tłumaczenie. Ale jeśli coś jest niejasne, to postaram się to bardziej uprościć. Pozdrawiam i powodzenia! laugh

1
komentarz 23 czerwca 2017 przez Dash Nałogowiec (29,650 p.)
Jestem pod naprawdę dużym wrażeniem, piękna robota :D. Algorytm działa perfekcyjnie, samemu dopisałem tylko funkcję działającą w drugą stronę (dec -> bin). Nie VLI, a mały system kryptograficzny, który w pierwszej kolejności zamienia ciąg liczb na zapis binarny, który to następnie jest przekształcany. Chociaż prawdopodobnie będzie to trzeba kiedyś napisać od nowa, jak sam widzisz przeliczanie długich ciągów cyfr (30-50 elementów) jest dosyć czasochłonne, szczególnie dla urządzeń mobilnych.

Podobne pytania

0 głosów
1 odpowiedź 691 wizyt
0 głosów
0 odpowiedzi 295 wizyt
0 głosów
2 odpowiedzi 454 wizyt
pytanie zadane 15 maja 2020 w JavaScript przez Kubunio Początkujący (270 p.)

92,555 zapytań

141,403 odpowiedzi

319,559 komentarzy

61,940 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!

...