Wątek przeniesiony 2016-11-15 11:11 z C/C++ przez ŁF.

Operacje bitowe - funkcja otrzymująca dwie liczby, a zwracająca jedną

0

Witam.
Mam pewien problem. Otóż mam napisać funkcję która z dwóch zmiennych zwróci mi jedną... - chodzi o to, że mam np. 2 zmienne typu int zainicjalizowane pewnymi wartościami... przekazuje je do funkcji która zwraca mi je w postaci jednego "inta" w którym zapisane są obie wartości które wcześniej były zapisane w tych 2 przekazanych zmiennych... Wiem, że chyba trzeba tu użyć jakiś operatorów bitowych ale jestem z tego b. zielony (zresztą w sumie z samego Cpp też nie jestem jakimś mistrzem).

Mam nadzieje, że ktoś mnie zrozumie i podpowie chociaż jak coś takiego wykonać.

Może napiszę jednak część polecenia, tak bym został dobrze zrozumiany:

Napisz funkcję, która na podstawie dwóch dat (każda podana za pomocą trzech liczb typu int-rok, miesiąc i dzień) tworzy i zwraca jedną wartość typu int z zakodowanymi tymi dwoma datami.

1

Poczytaj o przesunięciach bitowych oraz operacji OR, rozwiązanie nasunie się samo.

0

no dobra, czyli jak mam zapisać liczbę 127 31 i 12 w jednej zmiennej (będzie to typ int16_t) o ile się nie mylę... no to muszę np na początku dać 12 potem 31 a 127 i tak już jest "na końcu" (po "prawej"stronie) czyli muszę przesunąć "12" na "początek" (tam gdzie najbardziej znaczacy bit) a "31" jakby w "srodek" no i potem jakoś je "Połączyć" tak???

1

Standardowo: rozwiąż sobie to najpierw na kartce, zamieniając liczby na system binarny.

0

Taki kod jest ok? Słowem wyjaśnienia-przekazuje, co widać po parametrach, 2 w postaci rrrr m d tzn np. 2016 11 14 no i potem tam przekształcam, a no i dla ułatwienia daty lata mogą być tylko z przedziału [2000,2127].

int32_t pack(int32_t rr1, int32_t mm1, int32_t dd1, int32_t rr2, int32_t mm2, int32_t dd2)
{
    int32_t zwracamy;
    rr1-=2000;
    rr2-=2000;
    dd1=dd1<<28;
    mm1=mm1<<24;
    dd2=dd2<<2;
    mm2=mm2<<7;
    zwracamy=rr1|rr2|dd1|mm1|dd2|mm2|rr2;
    return zwracamy;
}

Pozdrawiam.

2

Zapomniałeś przesunąć rr1 albo rr2. dd1 << 28, gdzie dzień ma 5b, obetnie górne bity.
Nazwy zmiennych są beznadziejne.
Typy zmiennych są źle dobrane, skoro to dzień, to zmieści się w bajcie, rok zmieści się w word.
Skoro umieszczasz w 32b dwie daty, to logiczne, że w 16b umieścisz jedną, warto więc wyodrębnić funkcję pakującą jedną datę do int16_t, a potem złożyć dwa wywołania (coś w stylu return ((int32_t)pack16(y1, m1, d1)) << 16 | pack16(y2, m2, d2);). Dekodowanie identycznie.
Brak kontroli danych - jeśli któryś z argumentów wychodzi poza zakres, to powinien polecieć wyjątek.
Co do samego pytania - "czy jest ok" - przetestuj samodzielnie. I napisz funkcję dekodującą daty, to w miarę łatwo znajdziesz dziury.

Znacznie efektywniej upakujesz datę przeliczając ją na ilość dni od zadanego momentu. W ten sposób w 32 bitach zmieścisz ~12 milionów lat, w 16b wejdzie prawie 180.

0

Dzieki. Czyli poprawic typy parametrow plus dopisac komunikat jezeli rok, data albo miesiac wychodzi poza zakres? -jestem poczatkujacy :( A co do nazw, moge zmienic :D no ale w sumie rr1-rok 1 mm1-miesiac 1 no ale moga byc z angielskiego :D i bez dublowania liter.

Pozdrawiam.

1

Czy za rok będziesz pamiętać, czym różni się rr1 od rr2? Czy poprawa na year1 i year2 cokolwiek poprawi?
Nie "dopisać komunikat", tylko rzucić wyjątek. Wklep do google cpp wyjatki, kliknij na pierwszy czy drugi link, poczytaj ze zrozumieniem, spróbuj użyć.

0

Osobiscie moge powiedziec, ze tak. :p Jednak rozumiem, chodzi o to żeby nazwa zmiennej jak najlepiej charakteryzowała to co zawiera. Mam nadzieje ze teraz dobrze zrozumialem. Ok, poczytam, moze zrozumiem, co prawda w calym poleceniu do zadania sa ograniczenia ze daty sa z XXI wieku i rok reprezentujemy przez liczby [0,127] no i nie ma o wyjatkach mowy no ale zawsze warto wiedziec moze wiecej. Dzieki za pomoc.

1 użytkowników online, w tym zalogowanych: 0, gości: 1