Natrafiłem na następujący fragment kodu
if( 0 != ( x ^ 0x1 ) )
encode( x, m );
Co x ^ 0x1
znaczy Czy to jakaś standardowa technika?
c++
c
bit-manipulation
bitmask
KodeWarrior
źródło
źródło
0 != (x ^ 1)
→ x lub obie strony o 1 →(0 ^ 1) != (x ^ 1 ^ 1)
→ uprość →1 != x
if (1 != x)
trudno jest pisać.type
zx
nie podano - stąd nie wiemy, to jest liczbą całkowitą w tym C ++ oznaczone problem. Jasne, jeśli jest to C lubx
liczba całkowita, odpowiedź jest łatwa, ale to nie jest dane ioperator ^
istnieje możliwość przeładowania .Odpowiedzi:
Operacja XOR (
x ^ 0x1
) odwraca bit 0. Wyrażenie faktycznie oznacza: jeśli bit 0 x wynosi 0 lub dowolny inny bit x wynosi 1, to wyrażenie jest prawdziwe.I odwrotnie, wyrażenie jest fałszywe, jeśli x == 1.
Test jest taki sam jak:
i dlatego jest (prawdopodobnie) niepotrzebnie zaciemniony.
źródło
^
to bitowa operacja XOR0x1
jest1
w zapisie szesnastkowymx ^ 0x1
odwróci ostatni bitx
(jeśli nie jest to dla ciebie jasne, zapoznaj się z tabelą prawdy XOR w powyższym linku).Zatem warunek
(0 != ( x ^ 0x1 ))
będzie spełniony, jeślix
jest większy niż 1 lub jeśli ostatni bitx
wynosi 0. Co pozostawia tylko x == 1 jako wartość, przy której warunek będzie fałszywy. Jest to więc równoważne zPS Do cholery sposób na wdrożenie tak prostego warunku, mógłbym dodać. Nie rób tego A jeśli musisz napisać skomplikowany kod, zostaw komentarz . Błagam Cię.
źródło
x==0
;4 ^ 0x1
jest prawdą, ale4==0
oczywiście jest fałszywe.if (x == 0)
”, prawdax != 1
?x
jest to typ integralny. Jeśli jest tofloat
lubdouble
, to uważam, że wyrażenie dałoby prawdę1.0 <= x < 2.0
. A jeślix
jest typem zdefiniowanym przez użytkownika, wyrażenie może zwrócić wartość true, jeślix
jest to Yugo, kangur, urodziny słynnego kompozytora lub dowolna liczba, która dzieli co najmniej trzy cyfry z bieżącą ceną herbaty w Chinach wyrażoną w dolarach.operator^
dlafloat
/double
.Może to wydawać się uproszczonym wyjaśnieniem, ale jeśli ktoś chciałby przejść przez to powoli, jest poniżej:
^
jest bitowym operatorem XOR w c, c ++ i c #.Tabela prawdy z pomocą xor B :
Zilustrujmy więc
0 == ( x ^ 0x1 )
wyrażenie na poziomie binarnym:więc:
źródło
Jest to wyłączny operator OR (XOR). Aby zrozumieć, jak to działa, możesz uruchomić ten prosty kod
Wyjście będzie
Więc to wyrażenie
będzie równa prawda tylko wtedy, gdy x! = 0x1.
Nie zmienia samego x. Sprawdza tylko, czy x jest równe 0 lub 1. to wyrażenie można zmienić na
źródło
Sprawdza on, że
x
w rzeczywistości nie0x1
...xor
ingx
z0x1
spowodują 0 tylko wtedy, gdyx
jest0x1
... jest to stary trik stosowany głównie w asemblerzeźródło
!= 1
?xor
podejście zawierało mniej kodu maszynowego i było wykonywane szybciej niż odpowiednie przypisanie do0
... jednak to pytanie zawieraxor
ORAZ porównanie, więc mogę pomyśleć, że!=
może to być szybciej. Nie jestem jednak pewien, czy powinienem zobaczyć zestaw generowany przez kompilator.^
Operator bitowy XOR. I0x1
jest liczbą1
zapisaną jako stała szesnastkowa.Tak więc
x ^ 0x1
ocenia na nową wartość, która jest taka sama jakx
, ale z najmniej znaczącym odwróconym bitem.Kod robi tylko porównanie x z 1, w bardzo zawiły i niejasny sposób.
źródło
Operator xor (wyłączny lub) jest najczęściej używany do odwracania jednego lub więcej bitów. Operacja polega na zapytaniu, czy dokładnie jeden z bitów to jeden, prowadzi to do następującej tabeli prawdy (A i B są wejściami, Y jest wyjściowy):
Teraz celem tego kodu wydaje się sprawdzenie, czy dokładnie ostatni bit ma wartość 1, a pozostałe mają wartość 0, co jest równe
if ( x != 1 )
. Przyczyną tej niejasnej metody może być użycie wcześniejszych technik manipulacji bitami i być może wykorzystywanie innych miejsc w programie.źródło
^
jest bitowexor operator
wc
. W twoim przypadku x jest xor'ed z 1. na przykładx
ma wartość 10,10d ^ 1d ===> 1010b ^ 0001b = 1011b, 1011b == 11d
więc warunek staje się prawdziwy.źródło
10 != 1010
10 (decimal) == 1010 (binary)
b
ani czegoś takiego?Test bitowy wydaje się celowym zaciemnianiem, ale jeśli dane leżące u podstaw są danymi korporacyjnymi z systemu mainframe IBM, może to być po prostu napisanie kodu odzwierciedlającego oryginalną dokumentację. Formaty danych IBM sięgają lat 60. XX wieku i często kodują flagi jako pojedyncze bity w jednym słowie, aby zaoszczędzić miejsce. Gdy formaty zostały zmodyfikowane, bajty flag zostały dodane na końcu istniejących rekordów, aby zachować kompatybilność wsteczną. Na przykład dokumentacja rekordu SMF może pokazywać kod języka asemblera do testowania trzech pojedynczych bitów w ramach trzech różnych słów w jednym rekordzie w celu stwierdzenia, że dane są plikiem wejściowym. Wiem znacznie mniej o wewnętrznych elementach TCP / IP, ale możesz tam również znaleźć flagi bitowe.
źródło
Operator ^ jest bitowym xorem (patrz &, |). Wynik dla pary bitów to:
Więc wyrażenie
odwraca / odwraca 0-ty bit x (pozostawiając inne bity bez zmian).
Zastanów się, czy x może mieć wartości oprócz 0x0 i 0x1? Gdy x jest polem pojedynczego bitu, może mieć tylko wartości 0x0 i 0x1, ale gdy x jest liczbą całkowitą (char / short / long / etc), bity oprócz bitu 0 mogą wpływać na wynik wyrażenia.
Podane wyrażenie pozwala bitom obok bitu 0 wpływać na wynik,
Która ma równoważną prawdomówność jak to (prostsze) wyrażenie,
Zauważ, że to wyrażenie bada tylko bit0,
Zatem przedstawione wyrażenie naprawdę łączy dwie kontrole wyrażenia,
Czy autor zamierzał sprawdzić tylko bit0 i zamierzał użyć tego wyrażenia,
A może autor zamierzał połączyć wartości dla bit1-bitN i xor z bit0?
źródło
Dodam nową odpowiedź, ponieważ nikt tak naprawdę nie wyjaśnił, jak uzyskać odpowiedź intuicyjnie.
Odwrotnością
+
jest-
.Odwrotnością
^
jest^
.W jaki sposób można rozwiązać
0 != x - 1
zax
? Po+ 1
obu stronach:0 + 1 != x - 1 + 1
→1 != x
.W jaki sposób można rozwiązać
0 != x ^ 1
zax
? Po^ 1
obu stronach:0 ^ 1 != x ^ 1 ^ 1
→1 != x
.źródło
Sądzę, że są w nim inne bity lub wartości pól bitowych
x
, a to ma na celu sprawdzenie, czy ustawiony jest tylko bit niskiego rzędu. W tym kontekście domyślam się, że jest to ustawienie domyślne, a zatem kodowanie tego i niektórych powiązanychm
(prawdopodobnie droższych do kodowania) można pominąć, ponieważ oba muszą być wartością domyślną, zainicjowaną w konstruktorze lub podobnym.W jakiś sposób dekoder musi być w stanie wywnioskować, że brakuje tych wartości. Jeśli znajdują się na końcu jakiejś struktury, można to przekazać za pomocą
length
wartości, która jest zawsze obecna.źródło
XOR jest użyteczny w enum flagi C #. Aby usunąć pojedynczą flagę z wartości wyliczeniowej, konieczne jest użycie operatora xor ( tutaj )
Przykład:
źródło
Istnieje wiele dobrych odpowiedzi, ale lubię o tym myśleć w prostszy sposób.
Po pierwsze. Instrukcja if jest fałszywa tylko wtedy, gdy argument wynosi zero. Oznacza to, że porównywanie nie równe zeru jest bezcelowe.
Pozostaje nam więc:
XOR z jednym. XOR w zasadzie wykrywa różne bity. Tak więc, jeśli wszystkie bity są takie same, zwróci 0. Ponieważ 0 jest fałszem, jedyny raz zwróci fałsz, jeśli wszystkie bity są takie same. Więc to będzie fałsz, jeśli argumenty będą takie same, prawda, jeśli będą różne ... tak jak operator nie równy .
Jeśli faktem, jedyną różnicą między nimi jest to, że
!=
zwróci 0 lub 1, podczas gdy^
zwróci dowolną liczbę, ale prawdziwość wyniku zawsze będzie taka sama. Łatwym sposobem na przemyślenie tego jest.Końcowe „uproszczenie” jest konwertowane
0x1
na dziesiętne, które wynosi 1. Dlatego twoja instrukcja jest równoważna z:źródło
^ jest bitowym operatorem XOR
Jeśli x = 1
tutaj 0 == (x ^ 0x1)
Jeśli x = 0
tutaj 0! = (x ^ 0x1)
Tabela prawdy dla xor b:
Kod po prostu znaczy
źródło
Standardową techniką, która może być tutaj użyta, jest powtórzenie idiomu, który pojawia się w otaczającym kontekście dla jasności, zamiast zaciemnianie go poprzez zastąpienie go idiomem, który jest arytmetycznie prostszy, ale kontekstowo bez znaczenia.
Otaczający kod może często się odwoływać
(x ^ 1)
lub test może zapytać „jeśli bit 0 byłby odwrotnie, czy ta maska bitowa byłaby pusta?”.Biorąc pod uwagę, że warunek powoduje, że coś się
encode()
edytuje, może być tak, że w kontekście domyślny stan bitu 0 został odwrócony przez inne czynniki i potrzebujemy tylko zakodować dodatkowe informacje, jeśli któryś z bitów odbiega od wartości domyślnej (zwykle zero) ).Jeśli wyjmiesz wyrażenie z kontekstu i zapytasz, co robi, przeoczysz leżącą u jego podstaw intencję. Równie dobrze możesz spojrzeć na dane wyjściowe zestawu z kompilatora i zobaczyć, że po prostu dokonuje bezpośredniego porównania równości z 1.
źródło
Jak widzę, odpowiedzi do tej pory brakuje prostej zasady obsługi
XOR
s. Bez wchodzenia w szczegóły co^
i0x
średnia (iif
, i!=
etc), wyrażenie0 != (x^1)
może być przerobione w następujący sposób wykorzystując fakt, że(a^a)==0
:źródło