Przesunięcia bitowe

0

Dzień dobry jestem laikiem w dziedzinie programowanie poznałem już składnie wielu języków ale nigdy nie mogłem z opisów zrozumieć pojecia bitów w c++ czy php po co stosuje się bity i ich operatory bo z tego co pisze służy to do przesunięcia bitów

$a = 2;
$b = 2
$c = $a<<$b;

i jak wiadomo ten operator zrobi potęgowanie liczby $b i a$
ale własnie dla mnie jest to potęgowanie a wszędzie piszą o tym że to jakieś przesunięcie bitu i ja tego nie rozumiem kompletnie.
Znalazłem przykład gradienta

R, G, B - poszczególne składowe (w zakresie 0 - 255)
value - pełny kolor
**<< **- to w C i PHP operator przesunięcia bitowego w lewo. Pascalowy odpowiednik to shl
| - to w C i PHP operator sumy logicznej (OR). Pascalowy odpowiednik to or

Przykład:
W celu otrzymania gradientu czarny-żółty, mixujemy wzrost liniowy R z takim samym wzrostem G:

for (x = 0; x <= 100; x++)
{
value = (x*255)/100;
PutPixel(x, 0, (value **<< 16**) | (value << 8));
}

no i to funkcja do rysowania linii gradienta kolorów RGB i może mi ktoś wytłumaczyć po co jest ten operator << 8 i << 16
jak to działa dlaczego akurat są takie liczby i po co jaki to ma logiczno matematyczny sens jeśli mamy zakres 0 - 255 kolorów
to po co te przesunięcia jak je rozumiec jak to zwizualizować te przesunięcia bitów bo ja tego nie czaje w ogóle po co je się stosuje dlaczego i jak to mechanicznie działa, może mi ktoś w jasny sposób wytłumaczyć?

0

Wiesz jak przechowywane są liczby w pamięci komputera? Znasz system dwójkowy? Taka liczba 100 w dwójkowym to 01100100 przesuń bity o np. 2 w prawo i otrzymasz 00011001 czyli 25. I to cała filozofia.

Pierwszy raz słyszę, żeby używać przesunięcia bitów do potęgowania, tzn. to działa fajnie dla podstawy 2, bo to wynika z systemu dwójkowego, ale dla innej już się rozsypie.

Co do gradientu, kolor RGB to 3 bajty, żółty to RG i na maksa, w funkcji PutPixel na pozycji (x, 0) umieszczaną masz wartość 3 bajtową (chociaż zapewne 4 tak naprawdę, ale to pomińmy), a masz tylko 1 bajt danych. Załóżmy, że value to 127, czyli 01111111, przesuwasz to o 16 w lewo co daje w efekcie 01111111 00000000 00000000, teraz tą samą wartość przesuwasz w lewo o 8, co daje 00000000 01111111 00000000 teraz ORujesz to ze sobą co daje 01111111 01111111 00000000 i wartość RGB gotowa.

Na ogół przesunięć bitowych używa się jako sprytnego przyśpieszenia niektórych operacji, ponieważ jest to instrukcja bardzo tania.

0

Wielkie dzięki!
Wreszcie to czaje, widzisz problem polegał na tym że ja nigdy nie uczyłem się systemu binarnego i dlatego tego nie kumałem ale widzę że w tym jest był problem bardzo Ci dziękuje pozdrawiam

PS: zapomniałem zapytać o jeszcze jedno są też często w różnych kodach zapisy szestastkowe np

$a<<0xFF czyli mam rozumieć to tak że najpierw mam zamienić hex na bin czyli FF daje to 11111111 w binarnym i PHP tak to zrozumie?

a te oznaczenia "0x" to coś oznacza czy to tylko jest po to by wygodniej się czytało?

0xFF FF FF załóżmy jest sobie taki HEX no i (FF) jedną sztuke FF mam traktować jako jeden BIT? czy jeden BIT to jest odpowiednik jednego znaku (symbolu) bo jeden bajkt to 8 bitów czyli mam NP #FF1122 to razem jako całość jest jeden Bajt? RGB R- 1 bajt G - 1 bajt B- jeden bajt razem trzy bajty? więc w tym przypadku mamy 6 znaków FF1122 całość tworzy jeden bajt z tego co wyżej napisałeś ale czy jeden BIT to jest np jedno "F" czy dwa "FF" (FF)1122 i czy można też na tym operować?

0

$a<0xFF czyli mam rozumieć to tak że najpierw mam zamienić hex na bin czyli FF daje to 11111111 w binarnym i PHP tak to zrozumie?

Niskopoziomowo wszystko jest trzymane w formie binarnej i tylko na takiej reprezentacji komputer operuje, dlatego operacje bitowe są bardzo szybkie. To co Ty podajesz to literał. Czy podasz 255, 0xFF czy bindec('11111111') (PHP) - ostatecznie dla komputera jest to i tak 11111111.

a te oznaczenia "0x" to coś oznacza czy to tylko jest po to by wygodniej się czytało?

To informuje kompilator/parser że podajesz liczbę szesnastkową. W C++ możesz dodatkowo podawać literały ósemkowe (dodając prefiks 0, więc 0xFF == 0377).

jedną sztuke FF mam traktować jako jeden BIT?

Nie, jedna "sztuka FF" to 8 bitów = 1 bajt. Jedną cyfrę szesnastkową można zapisać na 4 bitach. Więc ilość bitów = ilość cyfr szesnastkowych * 4.

Zapisując kolor RGB, np. jako 0xFF0022 - każda para cyfr to osobna składowa koloru. 0xFF - kanał R (1 bajt), 0x00 - kanał G (1 bajt), 0x22 - kanał B (1 bajt).

Poszukaj w Internecie jakiegoś tutorialu/kursu o systemach liczbowych i potrenuj na kartce wszelkie warianty konwersji pomiędzy binarnym <-> dziesiętnym <-> szesnastkowym. Bez tego ciężko sensownie używać operacji bitowych. Z czasem większość operacji i charakterystycznych wartości będziesz obliczał w pamięci. :)

0

Bardzo dziękuje wam za pomoc, bo ja z 5 dni starałem się znaleźć jakieś info na google na ten temat o operacjach bitowych i wszędzie jest napisane takim językiem że nie idzie tego zrozumieć widocznie twórcy tutoriali nie biorą pod uwagę że może czytać to Newbie jak ja :P który nie rozumiał do tej pory jak działają w pamięci te przesunięcia.
z 15 h zmarnowałem ucząc się na pałe tych przesunięć teraz znalazłem fajny artykuł o liczeniu tego na kartce i wasze wypowiedzi (kolegów powyżej) bardzo pomogły mi to zrozumieć dziękuje.

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