Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Przesunięcia bitowe - problem z utratą bitów

Ostatnio zmodyfikowano 2014-08-14 13:41
Autor Wiadomość
An0nym8us
Temat założony przez niniejszego użytkownika
Przesunięcia bitowe - problem z utratą bitów
» 2014-08-08 17:50:29
Witam,

mam w zamiarze napisać prostą funkcję konwertującą VarInt do int. W tym celu postanowiłem wykorzystać przesunięcia bitowe, aby utracić 7 pierwszych niepotrzebnych bitów. Niestety, nie działają one w tej sytuacji:



    unsigned char ttt = 2u;

    int result = (ttt << 7) >> 7;
   
    std::cout << result;


Natomiast działają w takiej:



    unsigned char ttt = 2u;
    ttt = ttt << 7;
    ttt = ttt >> 7;
   
    std::cout << (int)ttt;


I tutaj moje pytanie: dlaczego tak się dzieje? Czy program przechowuje w buforze rzekomo utracone bajty do czasu nadpisania danej zmiennej (w tym przypadku result)?



PS: Proszę się nie sugerować nazwami zmiennych, wprowadzam byle jakie tylko wtedy kiedy coś "na szybko" testuję :).
P-115214
1234Marcineq
» 2014-08-08 18:37:39
dzieje się tak bo int jest 32 bitowe
int result = (ttt << 7) >> 7;
powoduje że najpierw zmienna result ma wartość 256
binarnie wygląda to tak:
00000000 00000000 00000001 00000000 ( pierwsze przesunięcie te w nawiasie)
drugie przesuniecie te poza nawiasem ustawia result
spowrotem na 2
00000000 00000000 00000000 00000010

w drugim przypadku zmienne są 8-bitowe czyli w pierwszym
przesunięciu jedynka wypada poza zmienną i nie wraca już
w drugim. dlatego zmienna ma wartość 0.
P-115219
An0nym8us
Temat założony przez niniejszego użytkownika
» 2014-08-08 23:52:59
Ok, ale czy tak działa kaskadowość operatorów? Poza tym, czy ta kaskadowość nie powinna "iść" od średnika, że się tak wyrażę ;-;? Czy po prostu kompilator wiedząc że wynik danych obliczeń znajdzie swój koniec w zmiennej typu int, tworzy w pamięci takową zmienną, na niej wykonuje te obliczenia a potem po prostu nadpisuje wskaźnik danego obiektu? Pytam bo z reguły nie wystarczy mi ogólna odpowiedź :).
P-115230
libed
» 2014-08-09 01:22:09
Jesli interesuje Cie tylko pierwszy bit to zastosuj koniunkcje.
int result = ttt & 1;[ / cpp ]
P-115234
Monika90
» 2014-08-09 09:11:06
Co to jest kaskadowość operatorów idąca od średnika?

Całkowitoliczbowe argumenty operatorów arytmetycznych (+ - * << >> itp) przed wykonaniem działania są poddawane promocji całkowitoliczbowej. Tzn, "małe" typy (między innymi bool, char, signed char, unsigned char, short, signed short) są konwertowane na int (na ogół na int), większe promocja pozostawia bez zmian. Te większe też mogą być konwertowane, ale to juz nie będzie promocja, to będzie zwykła konwersja arytmetyczna.

Zatem, jezeli mamy coś takiego

unsigned char x = 2;
x = x << 7;

to najpierw zostanie utworzona tymczasowa wartośc 2 typu int. Następnie zostanie przesunięta o 7 pozyji w lewo, wynikiem czego będzie 256 typu int. 256 będzie przypisane do zmiennej typu unsigned char, co polega na odrzuceniu nadmiarowych bitów, więc do x będzie przypisane 0.
P-115235
An0nym8us
Temat założony przez niniejszego użytkownika
» 2014-08-09 14:56:59
Pisząc "kaskadowość operatorów idąca od średnika" miałem na myśli:


int x, y, z;
x = y + z + x;

Wg mojego rozumowania (i tego co "chyba" widziałem w poradnikach) pierwsze wykona się "z + x" (wynik nazwijmy "result"), następnie "y + result", a potem wynik zostanie przypisany do 'z' poprzez operator '='.

Niemniej - dzięki za wyjaśnienie, teraz już to rozumiem :D.
P-115241
Monika90
» 2014-08-09 16:04:18
x = x + y + z;
to jest to samo co
x = ((x + y) + z);
może to zostać obliczone dowolnie, byle by wynik i wszystkie obserwowalne efekty uboczne były takie jakby najpierw było obliczone pierwsze dodawanie (od lewej), potem drugie i na końcu przypisanie do x.

Przy czym, pomimo tego że kolejność wykonywania dodawań jest tutaj określona, to kolejność wartościowania podwyrażeń x, y i z nie jest. Gdyby za x, y i z podstawić wywołania funkcji:
f() + g() + h()
to nie wiadomo w jakiej kolejności względem siebie byłyby te funkcje wywołane.
P-115247
An0nym8us
Temat założony przez niniejszego użytkownika
» 2014-08-14 13:41:59
Ok, mój kod aktualnie działa :). Dzięki za pomoc, pozdrawiam :).
P-115444
« 1 »
  Strona 1 z 1