2010-02-25 12 views
7

Hej, sam się uczę na temat bitowego i widziałem gdzieś w Internecie to przesunięcie arytmetyczne (>>) o jedną połowę liczby. Chciałem go przetestować:Dlaczego przesunięcie arytmetyczne wynosi połowę liczby tylko w NIEKTÓRYCH wypadkach?

44 >> 1 returns 22, ok 
22 >> 1 returns 11, ok 
11 >> 1 returns 5, and not 5.5, why? 

Inny przykład:

255 >> 1 returns 127 
127 >> 1 returns 63 and not 63.5, why? 

Dzięki.

+1

Dzielenie bity nie są dozwolone. Przepraszam. – leppie

+0

@leppie: huh ??? –

Odpowiedz

13

Operator przesunięcia bitowego nie dzieli się faktycznie przez 2. Zamiast tego przesuwa on bity liczby w prawo o liczbę pozycji podaną po prawej stronie. Na przykład:

00101100 = 44 
00010110 = 44 >> 1 = 22 

Wskazówki jak bity w drugiej linii są takie same jak w wierszu powyżej, jedynie przesunięte o jedno miejsce w prawo. Teraz spójrz na drugi przykład:

00001011 = 11 
00000101 = 11 >> 1 = 5 

To jest dokładnie ta sama operacja co poprzednio. Jednakże wynik 5 wynika z faktu, że ostatni bit jest przesunięty w prawo i znika, tworząc wynik 5. Z powodu tego zachowania, operator zmiany prawej będzie generalnie równoznaczny z dzieleniem przez dwa, a następnie wyrzuceniem dowolna pozostała część lub część dziesiętna.

+0

W pierwszym zdaniu myślę, że chciałeś powiedzieć prawo. – Joel

+0

@Joel: Masz rację. Naprawiony. –

+0

Cóż, operacja jest dokładnie taka sama jak podział całkowity lub mnożenie przez 2^n. – Tronic

1

Binarny nie ma pojęcia liczb dziesiętnych. Zwraca wartość obciętą (int).

11 = 1011 w binarnym. Przesuń w prawo i masz 101, czyli 5 w systemie dziesiętnym.

+0

Jest całkowicie możliwe, aby mieć cyfry po "dziesiętnym" punkcie w postaci binarnej. 101.1 ma sens, cyfra po punkcie reprezentuje po prostu 2^-1 w taki sam sposób, jak w dziesiętnym oznacza 10^-1. Problem polega na tym, że typ danych nie przechowuje danych w ten sposób, dlatego w operacji bit-shift wartość zostaje obcięta. – JonC

2

11 w formacie binarnym jest 1011

11 >> 1 

oznacza przesunięcie swoją reprezentację binarną w prawo o jeden krok.

1011 >> 1 = 101 

Wtedy masz 101 w formacie binarnym, który jest 1 * 1 + 0 * 2 + 1 * 4 = 5.
Jeśli zrobił 11 >> 2 trzeba wyniku 10 binarnym czyli 2 (1 * 2 + 0 * 1).

Przesunięcie o 1 w prawo przekształca sumę (A_i * 2^i) [i = 0..n] w sumie (A_ (i + 1) * 2^i) [i = 0..n-1 ] dlatego jeśli twoja liczba jest równa (tj. A_0 = 0), jest dzielona przez dwa. (Przepraszam za niestandardową składnię LateX ... :))

0

Przesunięcie bitów jest takie samo jak dzielenie lub mnożenie przez 2^n. W arytmetyce całkowitej wynik jest zaokrąglany w kierunku zera do liczby całkowitej. W arytmetykach zmiennoprzecinkowych przesunięcie bitów jest niedozwolone.

Wewnętrzna zmiana bitów, cóż, przesunięcia bitów, a zaokrąglenie oznacza po prostu bity, które spadają z krawędzi po prostu usuwane (nie, że to faktycznie obliczy dokładną wartość, a następnie ją zaokrągli). Nowe bity, które pojawiają się na przeciwległej krawędzi, są zawsze zerami dla prawej strony i dla dodatnich wartości. W przypadku wartości ujemnych, jeden bit jest dołączany po lewej stronie, więc wartość pozostaje ujemna (zobacz, jak działa two's complement), a używana przeze mnie definicja arytmetyczna nadal jest prawdziwa.

0

W większości języków statycznych typem zwrotu operacji jest np. "int". Wyklucza to wynik ułamkowy, podobnie jak dzielenie całkowite.

(Są lepsze odpowiedzi na temat tego, co znajduje się „pod maską”, ale nie ma potrzeby, aby zrozumieć te grok podstaw systemu typu).

Powiązane problemy