Jakie są przykłady rzeczywistych zastosowań następujących operatorów bitowych?
- I
- XOR
- NIE
- LUB
- Przesunięcie w lewo / w prawo
language-agnostic
bitwise-operators
Louis Go
źródło
źródło
Odpowiedzi:
Pola bitowe (flagi)
To najbardziej efektywny sposób reprezentowania czegoś, którego stan jest zdefiniowany przez kilka właściwości „tak lub nie”. Listy ACL są dobrym przykładem; jeśli powiedzmy 4 dyskretne uprawnienia (odczyt, zapis, wykonywanie, zmiana zasad), lepiej przechowywać to w 1 bajcie zamiast marnować 4. Można je zmapować na typy wyliczeń w wielu językach dla dodatkowej wygody.
Komunikacja przez porty / gniazda
Zawsze obejmuje sumy kontrolne, parzystość, bity stopu, algorytmy sterowania przepływem itp., Które zwykle zależą od wartości logicznych poszczególnych bajtów w przeciwieństwie do wartości liczbowych, ponieważ medium może być w stanie przesłać tylko jeden bit na czas.
Kompresja, szyfrowanie
Oba są silnie zależne od algorytmów bitowych. Spójrz na algorytm deflacji - wszystko jest w bitach, a nie w bajtach.
Maszyny o stanach skończonych
Mówię przede wszystkim o rodzaju wbudowanym w jakiś sprzęt, chociaż można je również znaleźć w oprogramowaniu. Są kombinatoryczne w przyrodzie - mogą one być coraz dosłownie „skompilowany” w dół do kilka bramek logicznych, więc muszą być wyrażone jako
AND
,OR
,NOT
, itd.Grafika Nie ma tu wystarczająco dużo miejsca, aby dostać się do każdego obszaru, w którym operatorzy są wykorzystywani do programowania grafiki.
XOR
(lub^
) jest tutaj szczególnie interesujące, ponieważ zastosowanie tego samego wejścia po raz drugi spowoduje cofnięcie pierwszego. Starsze GUI polegały na tym przy podświetlaniu wyboru i innych nakładkach, aby wyeliminować potrzebę kosztownych przerysowań. Nadal są przydatne w powolnych protokołach graficznych (np. Zdalny pulpit).To tylko kilka pierwszych przykładów, które wymyśliłem - nie jest to wyczerpująca lista.
źródło
Czy to dziwne?
Czy można go podzielić przez dwa (parzyste)?
źródło
Oto kilka typowych idiomów dotyczących flag przechowywanych jako pojedyncze bity.
Ustaw flagę podlegającą opłacie:
Wyczyść flagę CallerIDMissing:
Sprawdź, czy ustawione są CallerIDMissing i Chargeable:
źródło
Użyłem operacji bitowych przy wdrażaniu modelu bezpieczeństwa dla CMS. Miał strony, do których użytkownicy mogliby uzyskać dostęp, gdyby byli w odpowiednich grupach. Użytkownik może być w wielu grupach, dlatego musieliśmy sprawdzić, czy istnieje skrzyżowanie między grupami użytkowników i grupami stron. Przypisaliśmy więc każdej grupie unikalny identyfikator potęgi-2, np .:
Mamy LUB te wartości razem i przechowujemy wartość (jako pojedynczy int) ze stroną. Np. Jeśli dostęp do strony mogą uzyskać grupy A i B, przechowujemy wartość 3 (która w postaci binarnej to 00000011) jako kontrolę dostępu do stron. W podobny sposób przechowujemy wartość identyfikatorów grup ORed z użytkownikiem, aby reprezentować, w których grupach się znajdują.
Aby więc sprawdzić, czy dany użytkownik może uzyskać dostęp do danej strony, wystarczy ORAZ wartości razem i sprawdzić, czy wartość nie jest zerem. Jest to bardzo szybkie, ponieważ ta kontrola jest realizowana w jednej instrukcji, bez zapętlania, bez rund bazy danych.
źródło
Dobrym przykładem jest programowanie na niskim poziomie. Może być na przykład konieczne zapisanie określonego bitu w rejestrze odwzorowanym w pamięci, aby jakiś sprzęt zrobił to, co chcesz:
Również
htonl()
ihtons()
są realizowane przy użyciu&
i|
operatorów (na maszynach, których kolejność bajtów (kolejność bajtów) nie zgadza się kolejność sieci):źródło
htons()
ihtonl()
są funkcjami POSIX do zamiany ashort
lub along
zh
endianness hosta ( ) nan
kolejność bajtów w sieci ( ).htonl()
dotyczy wartości 32-bitowejint
?long
oznacza 64-bitowe w wielu językach.Używam ich na przykład do uzyskiwania wartości RGB (A) z upakowanych wartości kolorów.
źródło
(a & b) >> c
jest ponad 5 razy szybszy niża % d / e
(oba sposoby na wyodrębnienie jednej wartości koloru z int reprezentującej ARGB). Odpowiednio, 6,7s i 35,2s dla 1 miliarda iteracji.%
nie jest operatorem Modulus, lecz operatorem Remainder. Są równoważne wartościom dodatnim, ale różnią się wartościami ujemnymi. Jeśli podasz odpowiednie ograniczenia (przekazującuint
zamiast zamiastint
na przykład), wówczas dwa przykłady powinny być tej samej prędkości.Kiedy mam kilka flag boolowskich, lubię je przechowywać w int.
Wyciągam je za pomocą bitowego AND. Na przykład:
itp.
źródło
if (flags.feature_one_is_one) { // turn on feature }
. Jest w standardzie ANSI C, więc przenośność nie powinna stanowić problemu.& = AND:
maskowanie określonych bitów.
Definiujesz określone bity, które powinny być wyświetlane lub nie. 0x0 i x kasują wszystkie bity w bajcie, a 0xFF nie zmienia x. 0x0F wyświetli bity w dolnej części.
Konwersja:
Aby rzutować krótsze zmienne na dłuższe o identyczności bitowej, konieczne jest dostosowanie bitów, ponieważ -1 w int to 0xFFFFFFFF, podczas gdy -1 w długim to 0xFFFFFFFFFFFFFFFF. Aby zachować tożsamość, po konwersji zastosujesz maskę.
| = LUB
Ustaw bity. Bity zostaną ustawione niezależnie, jeśli są już ustawione. Wiele struktur danych (pól bitowych) ma flagi takie jak IS_HSET = 0, IS_VSET = 1, które można ustawić niezależnie. Aby ustawić flagi, zastosuj IS_HSET | IS_VSET (W C i asemblerze bardzo wygodnie to czyta)
^ = XOR
Znajdź bity, które są takie same lub różne.
~ = NIE
Odwróć bity.
Można pokazać, że wszystkie możliwe lokalne operacje bitowe mogą być zaimplementowane przez te operacje. Jeśli chcesz, możesz zaimplementować instrukcję ADD wyłącznie za pomocą operacji bitowych.
Niektóre wspaniałe hacki:
http://www.ugcs.caltech.edu/~wnoise/base2.html
http://www.jjj.de/bitwizardry/bitwizardrypage.html
źródło
= ~
, a nie|=
, które jest OR.& = AND
- Dlaczego miałbym chcieć wyczyścić wszystkie bity, dlaczego miałbym chcieć uzyskać niezmodyfikowaną wersję bajtu i co mam zrobić z dolnym skubaniem?xor
sam w sobie. Mogę wymyślić kilka powodów, dla których możesz chcieć wyodrębnić niższy kęs. Zwłaszcza jeśli ten niższy skrawek jest częścią struktury danych i chcesz użyć go jako maski lubOR
innej struktury.Szyfrowanie to wszystkie operacje bitowe.
źródło
Możesz użyć ich jako szybkiego i brudnego sposobu na haszowanie danych.
źródło
Właśnie użyłem bitowego XOR (
^
) około trzy minuty temu, aby obliczyć sumę kontrolną dla komunikacji szeregowej ze sterownikiem PLC ...źródło
Bitowe & służy do maskowania / wydobywania określonej części bajtu.
1 bajtowa zmienna
Zwłaszcza operator zmiany biegów (<< >>) jest często używany do obliczeń.
źródło
To jest przykład odczytu kolorów z mapy bitowej w formacie bajtowym
Mam nadzieję, że te małe przykłady pomogą ...
źródło
W abstrakcyjnym świecie współczesnego języka nie ma ich zbyt wiele. File IO jest łatwym, który przychodzi na myśl, chociaż wykonuje on operacje bitowe na czymś już zaimplementowanym i nie implementuje czegoś, co wykorzystuje operacje bitowe. Mimo to, jako prosty przykład, ten kod pokazuje usunięcie atrybutu „tylko do odczytu” dla pliku (aby można go było używać z nowym FileStream określającym FileMode.Create) w c #:
Jeśli chodzi o niestandardowe implementacje, oto ostatni przykład: Stworzyłem „centrum wiadomości” do wysyłania bezpiecznych wiadomości z jednej instalacji naszej aplikacji rozproszonej do drugiej. Zasadniczo jest analogiczny do wiadomości e-mail, w komplecie ze skrzynką odbiorczą, skrzynką nadawczą, wysłaną itp., Ale zapewnia także dostawę z potwierdzeniami odczytu, więc istnieją dodatkowe podfoldery poza „skrzynką odbiorczą” i „wysłane”. To, co to oznaczało, wymagało ode mnie ogólnego określenia, co jest „w skrzynce odbiorczej”, a co „w wysłanym folderze”. Z wysłanego folderu muszę wiedzieć, co jest przeczytane, a co nieprzeczytane. O tym, co jest nieprzeczytane, muszę wiedzieć, co otrzymano, a co nie. Używam tych informacji do zbudowania dynamicznej klauzuli where, która filtruje lokalne źródło danych i wyświetla odpowiednie informacje.
Oto jak zestawiony jest wyliczenie:
Czy widzisz co to robi? Poprzez anding (&) wartością wyliczenia „Skrzynka odbiorcza”, InboundMemos, wiem, że InboundMemosForMyOrders znajduje się w skrzynce odbiorczej.
Oto uproszczona wersja metody, która buduje i zwraca filtr definiujący widok dla aktualnie wybranego folderu:
Niezwykle prosta, ale zgrabna implementacja na poziomie abstrakcji, która zwykle nie wymaga operacji bitowych.
źródło
Przykładem jest kodowanie Base64. Kodowanie Base64 służy do reprezentowania danych binarnych jako drukowalnych znaków do wysyłania przez systemy pocztowe (i inne cele). Kodowanie Base64 przekształca ciąg 8-bitowych bajtów w 6-bitowe indeksy wyszukiwania znaków. Operacje bitowe, przesuwanie i „dodawanie” lub „notowanie” są bardzo przydatne do implementacji operacji bitowych niezbędnych do kodowania i dekodowania Base64.
To oczywiście tylko 1 z niezliczonych przykładów.
źródło
Dziwi mnie, że nikt nie wybrał oczywistej odpowiedzi na epokę Internetu. Obliczanie prawidłowych adresów sieciowych dla podsieci.
http://www.topwebhosts.org/tools/netmask.php
źródło
Zwykle operacje bitowe są szybsze niż mnożenie / dzielenie. Więc jeśli musisz pomnożyć zmienną x przez powiedzmy 9, zrobisz to
x<<3 + x
co byłoby kilka cykli szybciej niżx*9
. Jeśli ten kod znajduje się w ISR, zaoszczędzisz na czasie odpowiedzi.Podobnie, jeśli chcesz użyć tablicy jako kolejki kołowej, szybsze (i bardziej eleganckie) byłoby obsługiwanie kontroli zawijania za pomocą nieco mądrzejszych operacji. (Twój rozmiar tablicy powinien wynosić 2). Np .: możesz użyć
tail = ((tail & MASK) + 1)
zamiasttail = ((tail +1) < size) ? tail+1 : 0
, jeśli chcesz wstawić / usunąć.Również jeśli chcesz, aby flaga błędu zawierała wiele kodów błędów, każdy bit może zawierać osobną wartość. Możesz ORAZ z każdym kodem błędu jako czekiem. Jest to używane w uniksowych kodach błędów.
Również n-bitowa mapa bitowa może być naprawdę fajną i zwartą strukturą danych. Jeśli chcesz przydzielić pulę zasobów o rozmiarze n, możemy użyć n-bitów do przedstawienia bieżącego stanu.
źródło
Wydaje się, że nikt nie wspomniał o matematyce stałoprzecinkowej.
(Tak, jestem stary, ok?)
źródło
Czy liczba
x
jest potęgą 2? (Przydatne na przykład w algorytmach, w których licznik jest zwiększany, a działanie ma być podejmowane tylko logarytmicznie kilka razy)Który z najwyższych bitów jest liczbą całkowitą
x
? (To na przykład można wykorzystać do znalezienia minimalnej mocy 2, która jest większa niżx
)Który z najniższych
1
bitów jest liczbą całkowitąx
? (Pomaga znaleźć liczbę razy podzielną przez 2.)źródło
x & -x
.Operatory bitowe są przydatne do zapętlania tablic o długości równej potędze 2. Jak wspomniano wiele osób, operatory bitowe są niezwykle przydatne i są używane w flagach , grafice , sieci i szyfrowaniu . Nie tylko to, ale są niezwykle szybkie. Moim ulubionym jest użycie pętli tablica bez warunkowych . Załóżmy, że masz tablicę opartą na indeksie zerowym (np. Indeks pierwszego elementu wynosi 0) i musisz zapętlać ją w nieskończoność. Przez nieokreślony mam na myśli przejście od pierwszego elementu do ostatniego i powrót do pierwszego. Jednym ze sposobów realizacji tego jest:
Jest to najprostsze podejście, jeśli chcesz uniknąć jeśli oświadczenie, można użyć modułu zespolonego podejście tak:
Wadą tych dwóch metod jest to, że operator modułu jest drogi, ponieważ szuka pozostałej części po dzieleniu liczb całkowitych. I pierwsza metoda uruchamia instrukcję if na każdej iteracji. Jeśli operator bitowy ma długość 2, możesz łatwo wygenerować sekwencję
0 .. length - 1
, używając&
operatora (bitowego i)i & length
. Wiedząc o tym, kod z góry staje sięOto jak to działa. W formacie binarnym każda liczba, która jest potęgą 2 odejmowana przez 1, jest wyrażana tylko z jedynkami. Na przykład 3 w systemie binarnym to
11
7111
, 15 to1111
i tak dalej, masz pomysł. A co się stanie, jeśli&
dowolna liczba w stosunku do liczby składającej się tylko z liczb binarnych? Powiedzmy, że robimy to:Jeśli
num
jest mniejsze lub równe 7, wynik będzie taki,num
że każdy bit&
z 1 ma swoją wartość. Jeślinum
jest większy niż 7, podczas&
operacji komputer weźmie pod uwagę zera 7, które oczywiście pozostaną jako zera po&
operacji, pozostanie tylko część końcowa. Tak jak w przypadku9 & 7
binarnego będzie to wyglądaćwynikiem będzie 0001, który ma wartość 1 w systemie dziesiętnym i adresuje drugi element w tablicy.
źródło
Używam ich do opcji wielokrotnego wyboru, w ten sposób przechowuję tylko jedną wartość zamiast 10 lub więcej
źródło
może być również przydatny w modelu relacyjnym sql, powiedzmy, że masz następujące tabele: BlogEntry, BlogCategory
tradycyjnie możesz utworzyć relację nn między nimi za pomocą tabeli BlogEntryCategory lub gdy nie ma zbyt wielu rekordów BlogCategory, możesz użyć jednej wartości w BlogEntry, aby połączyć się z wieloma rekordami BlogCategory, tak jak zrobiłbyś to z oznaczonymi wyliczeniami, w większości RDBMS są również bardzo szybcy operatorzy do wyboru w tej kolumnie „oflagowanej” ...
źródło
Jeśli chcesz zmienić tylko niektóre bity wyjść mikrokontrolera, ale rejestr, w którym chcesz zapisać, to bajt, robisz coś takiego (pseudokod):
Oczywiście wiele mikrokontrolerów pozwala zmieniać każdy bit indywidualnie ...
źródło
Jeśli kiedykolwiek chcesz obliczyć swój mod liczbowy (%) pewną potęgę 2, możesz użyć
yourNumber & 2^N-1
, która w tym przypadku jest taka sama jakyourNumber % 2^N
.Prawdopodobnie jest to przydatne tylko jako alternatywa dla operacji modułu z bardzo dużą dywidendą, która wynosi 2 ^ N ... Ale nawet wtedy jego wzrost prędkości w stosunku do operacji modułu jest pomijalny w moim teście na .NET 2.0. Podejrzewam, że nowoczesne kompilatory już wykonują takie optymalizacje. Czy ktoś wie o tym więcej?
źródło
%
operacja Remainder, traktuje negatywnie inaczej. Jednak jeśli przejdzieszuint
do%
, kompilator C # faktycznie wygeneruje kod maszynowy przy użyciu bitowego AND, gdy drugi argument jest znaną potęgą dwóch.Widziałem je stosowane w systemach kontroli dostępu opartych na rolach.
źródło
W moim pytaniu istnieje rzeczywiste zastosowanie w świecie -
Odpowiadasz tylko na pierwsze powiadomienie WM_KEYDOWN?
Podczas korzystania z komunikatu WM_KEYDOWN w Windows C bit 30 interfejsu API określa poprzedni stan klucza. Wartość wynosi 1, jeśli klucz jest wciśnięty przed wysłaniem wiadomości, lub zero, jeśli klucz jest podniesiony
źródło
Są one najczęściej używane do operacji bitowych (niespodzianka). Oto kilka rzeczywistych przykładów znalezionych w bazie kodu PHP.
Kodowanie znaków:
Struktury danych:
Sterowniki bazy danych:
Implementacja kompilatora:
źródło
Za każdym razem, gdy zaczynałem programowanie w C, rozumiałem tabele prawdy i tak dalej, ale nie wszystko klikało, jak właściwie z niego korzystać, dopóki nie przeczytałem tego artykułu http://www.gamedev.net/reference/articles/article1563.asp (który podaje przykłady z życia)
źródło
x == 1
iy == 2
, tox || y
ocenia na 1, ax | y
ocenia na 0. Nie widzę też, dlaczegox^true
jest!x
w jakikolwiek sposób lepszy . To bardziej pisanie na maszynie, mniej idiomatyczne, a jeślix
nie, tobool
nie jest wiarygodne.x^true
przewyższa!x
to, żesome->complicated().member->lookup ^= true;
nie ma wersji jednoargumentowych przypisań złożonych.Nie sądzę, że liczy się to jako bitowe, ale tablica Ruby definiuje operacje ustawiania za pomocą zwykłych liczb całkowitych operatorów bitowych. Tak
[1,2,4] & [1,2,3] # => [1,2]
. Podobnie dlaa ^ b #=> set difference
ia | b #=> union
.źródło
Rozwiązanie liniowe Tower Of Hanoi wykorzystuje operacje bitowe do rozwiązania problemu.
Wyjaśnienie tego rozwiązania można znaleźć tutaj
źródło