Na CodeReview opublikowałem działający fragment kodu i poprosiłem o wskazówki, jak go ulepszyć. Jednym z nich było użycie metody boolowskiej, aby sprawdzić, czy ArrayList ma parzystą liczbę indeksów (co było wymagane). To był kod, który został zasugerowany:
private static boolean isEven(int number)
{
return (number & 1) == 0;
}
Ponieważ już nagabywałem tego konkretnego użytkownika o dużą pomoc, zdecydowałem, że nadszedł czas, aby nękać społeczność SO! Naprawdę nie rozumiem, jak to działa. Metoda jest wywoływana i przyjmuje rozmiar ArrayList jako parametr (tj. ArrayList ma dziesięć elementów, liczba = 10).
Wiem, że pojedynczy &
biegnie porównanie liczby i 1, ale potem się zgubiłem.
Sposób, w jaki to czytam, mówi, że zwróć prawdę jeśli number == 0
i 1 == 0
. Wiem, że to pierwsze nie jest prawdą, a drugie oczywiście nie ma sensu. Czy ktoś mógłby mi pomóc?
Edycja: Powinienem chyba dodać, że kod działa, na wypadek gdyby ktoś się zastanawiał.
number % 2 == 0
?Odpowiedzi:
Pamiętaj, że „&” to operacja bitowa. Prawdopodobnie jesteś tego świadomy, ale nie jest to dla mnie całkowicie jasne, biorąc pod uwagę sposób, w jaki zadałeś pytanie.
To powiedziawszy, teoretyczna idea jest taka, że masz jakieś int, które można wyrazić w bitach przez pewną serię jedynek i zer. Na przykład:
...10110110
W systemie binarnym, ponieważ ma podstawę 2, ilekroć wersja bitowa liczby kończy się na 0, jest parzysta, a gdy kończy się na 1, jest nieparzysta.
Dlatego zrobienie bitowego & z 1 dla powyższego to:
...10110110 & ...00000001
Oczywiście jest to 0, więc można powiedzieć, że oryginalne wejście było parzyste.
Alternatywnie rozważ liczbę nieparzystą. Na przykład dodaj 1 do tego, co mieliśmy powyżej. Następnie
...10110111 & ...00000001
Jest równa 1 i dlatego nie jest równa zeru. Voila.
źródło
n%k == n&(k-1)
dla wszystkich,k
które mają dodatnią potęgę 2. Może to nie być to, o co pytał pytający, ale warto wiedzieć.log
ani2^
gdzieś w tym wyrażeniu?Możesz określić, czy liczba jest parzysta lub nieparzysta na podstawie ostatniego bitu w reprezentacji binarnej:
1 -> 00000000000000000000000000000001 (odd) 2 -> 00000000000000000000000000000010 (even) 3 -> 00000000000000000000000000000011 (odd) 4 -> 00000000000000000000000000000100 (even) 5 -> 00000000000000000000000000000101 (odd) 6 -> 00000000000000000000000000000110 (even) 7 -> 00000000000000000000000000000111 (odd) 8 -> 00000000000000000000000000001000 (even)
&
między dwiema liczbami całkowitymi jest operatorem bitowym AND:0 & 0 = 0 0 & 1 = 0 1 & 0 = 0 1 & 1 = 1
Więc jeśli
(number & 1) == 0
taktrue
, to znaczy, żenumber
jest równy.Załóżmy zatem
number == 6
, że :6 -> 00000000000000000000000000000110 (even) &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 1 -> 00000000000000000000000000000001 ------------------------------------- 0 -> 00000000000000000000000000000000
a kiedy
number == 7
:7 -> 00000000000000000000000000000111 (odd) &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 1 -> 00000000000000000000000000000001 ------------------------------------- 1 -> 00000000000000000000000000000001
źródło
&
jest bitowym operatorem AND.&&
jest operatorem logicznym ANDW systemie binarnym, jeśli bit cyfr jest ustawiony (tj. Jeden), liczba jest nieparzysta.
W systemie binarnym, jeśli bit cyfr jest równy zero, liczba jest parzysta.
(number & 1)
jest bitowym testem AND bitu cyfr.Innym sposobem na to (prawdopodobnie mniej wydajnym, ale bardziej zrozumiałym) jest użycie operatora modułu
%
:private static boolean isEven(int number) { if (number < 0) throw new ArgumentOutOfRangeException(); return (number % 2) == 0; }
źródło
&
jest również logicznym AND.&&
zwarcia, podczas gdy&
nie.number % 2
to nie to samo, conumber & 1
jeślinumber
jest ujemne.number < 0
sprawę - podczas gdy nieparzysta liczba ujemna mod 2 to -1, parzysta mod 2 to nadal 0.To wyrażenie oznacza „liczba całkowita reprezentuje liczbę parzystą”.
Oto powód, dla którego: binarna reprezentacja liczby dziesiętnej
1
to00000000001
. Wszystkie liczby nieparzyste kończą się na a1
w systemie dwójkowym (łatwo to zweryfikować: załóżmy, że binarna reprezentacja liczby nie kończy się na1
; wtedy składa się z niezerowych potęg dwóch, co zawsze jest liczbą parzystą). Kiedy robisz binarnyAND
z liczbą nieparzystą, wynikiem jest1
; kiedy robisz binarnyAND
z liczbą parzystą, wynikiem jest0
.Była to preferowana metoda decydowania o parzystości / nieparzystości w czasach, gdy optymalizatory były słabe lub nieistniejące, a
%
operatorzy wymagali dwudziestokrotnej liczby cykli wykonywanych przez&
operatora. W dzisiejszych czasach, jeśli to zrobisznumber % 2 == 0
, kompilator prawdopodobnie wygeneruje kod, który zostanie wykonany równie szybko, jak to(number & 1) == 0
robi.źródło
Pojedynczy
&
oznacza bitowyand
operator, a nie porównanieWięc ten kod sprawdza, czy pierwszy
bit
(najmniej znaczący / najbardziej prawy) jest ustawiony, czy nie, co wskazuje, czy liczba jest,odd
czy nie; ponieważ wszystkie liczby nieparzyste kończą się1
na najmniej znaczącym bicie, npxxxxxxx1
źródło
&
może być użyty jako logiczny,and
jeśli chcesz uniknąć skutków ubocznych z wyrażeń takich jakf(x) & g(x)
&
jestAND
operacją bitową .Dla liczby = 8:
1000 0001 & ---- 0000
Wynik jest taki
(8 & 1) == 0
. Tak jest w przypadku wszystkich liczb parzystych, ponieważ są one wielokrotnościami 2, a pierwsza cyfra binarna od prawej to zawsze 0. 1 ma wartość binarną 1 z wiodącymi zerami, więc kiedy mamyAND
parzystą liczbę zostajemy z 0.źródło
&
Operator w Javie jest iloczynem bitowym i operator. Zasadniczo(number & 1)
wykonuje bitowe i międzynumber
i1
. Wynik to 0 lub 1, w zależności od tego, czy jest parzysty, czy nieparzysty. Następnie wynik jest porównywany z 0, aby określić, czy jest parzysty.Oto strona opisująca operacje bitowe .
źródło
Wykonuje operację binarną przeciwko 1, która zwraca 0, jeśli najmniej znaczący bit nie jest ustawiony
na przykład
00001010 (10)
00000001 (1)
===========
00000000 (0)
źródło
To jest logiczna koncepcja projektowa bitowa i operator (AND).
powrót (2 i 1); oznacza - przekonwertuj wartość na liczby bitowe i porównaj funkcję (AND) i zwróci wartość.
Wolę ten link http://www.roseindia.net/java/master-java/java-bitwise-and.shtml
źródło