2009-03-01 14 views
47

Często używam ($var & 1) w moim kodzie, który zwraca wartość true, jeśli $var jest liczbą nieparzystą, a false, jeśli jest liczbą parzystą.Zrozumienie operatora PHP i (ampersand, bitwise i)

Ale co właściwie robi "&"?

+0

Dla niektórych pytanie nie jest proste, a on prosi o szczegółowe wyjaśnienie dotyczące operatora, jak widać na podstawie odpowiedzi, którą przyjął. –

+0

@Olafur - operator & jest dość prosty. Nie chce szczegółowego wyjaśnienia, chce wyjaśnienia AN, ponieważ używał go, nie wiedząc, co dokładnie robi. Choć podziwiam jego chęć przyznania się, że on tego nie wie i pragnie się go nauczyć, to wciąż jest to pytanie Google. –

+0

Nie chodzi o to, że odpowiedź jest prosta, ale jeśli umieszczenie jej tutaj oznacza po prostu skopiowanie jej z innego miejsca. To jest zbędne. Wydaje mi się, że niektórzy ludzie naprawdę używają SO, by zabić wolny czas. Być może jestem trochę stronniczy, ale lubię SO dla zagadek, a nie dla pytań typu "czat". – Caffeine

Odpowiedz

52

& jest binarny and. Jeśli masz wartość binarną, a ty and z inną wartością binarną, wynik będzie bitowy and z dwóch. Przykład:

01101010 
& 01011001 
= 01001000 

bit jest najbardziej z prawej albo 1 (w tym przypadku, gdy liczba jest liczbą nieparzystą), albo jest to wartość 0, w przypadku których liczba jest liczbą parzystą. Jeśli masz & liczbę z 1, patrzysz tylko na najmniej znaczący bit, a jeśli sprawdza, czy liczba jest równa 1 lub 0. Jak wspomnieli inni, spójrz na operatorów bitowych, aby uzyskać informacje na temat ich działania.

18

To także ciekawy wiedzieć o bitowego i PHP:

/** 
* Regular 
*/ 
echo (true && true); // 1 
echo (true && false); // nothing 

echo (true || false); // 1 
echo (false || false); // nothing 

echo (true xor false); // 1 
echo (false xor false); // nothing 

/** 
* Bitwise 
*/ 
echo (true & true); // 1 
echo (true & false); // 0 

echo (true | false); // 1 
echo (false | false); // 0 

echo (true^false); // 1 
echo (false^false); // 0 
+1

Ta odpowiedź tak naprawdę nie wyjaśnia, w jaki sposób && jest różna i bardzo dobrze moim zdaniem. && rzuca oba parametry do wartości logicznej i przypomina porównywanie pojedynczego bitu. i porównuje bitowo: każdy bit w jednym parametrze jest porównywany z każdym bitem w drugim. – thomasrutter

+3

"regular" jest znany jako logiczny i/lub –

+1

Ważne jest również, aby wiedzieć, że operatory bitowe, takie jak & i | działają na liczbach całkowitych. Przykłady w tej odpowiedzi działają tylko dlatego, że 'true' konwertuje na' 1' i 'false' konwertuje na' 0'. Gdybyś miał 'echo (" cheese "i 4)' to wyprowadziłoby zero, podczas gdy 'echo (" cheese "&& 4)' wyprowadziłoby wartość true. – thomasrutter

24

dwie operacje, które są fundamentalne dla systemów binarnych są OR i AND.

OR oznacza "jeśli A jest włączone lub B jest włączone". Przykładem świata rzeczywistego byłyby dwa przełączniki równolegle. Jeśli któraś z nich pozwala na przepływ prądu, wówczas prąd przechodzi.

AND oznacza "jeśli A i B są włączone". Przykładem świata rzeczywistego są dwa przełączniki w szeregu. Prąd przepłynie tylko wtedy, gdy obydwa dopuszczą prąd.

W komputerze nie są to fizyczne przełączniki, ale półprzewodniki, a ich funkcjonalność nazywa się logic gates. Robią to samo, co przełączniki - reagują na prąd lub brak prądu.

Po zastosowaniu do liczb całkowitych każdy bit w jednej liczbie jest łączony z każdym bitem w innym numerze. Aby zrozumieć operatory bitowe OR i AND, musisz przekonwertować liczby na binarne, a następnie wykonać operacje OR lub AND na każdej parze pasujących bitów.

Dlatego:

00011011 (odd number) 
AND 
00000001 (& 1) 
== 
00000001 (results in 1) 

Zważywszy

00011010 (even number) 
AND 
00000001 (& 1) 
== 
00000000 (results in 0) 

The (& 1) działanie porównuje się zatem do najbardziej po prawej bitu na 1 przy użyciu i logiki. Wszystkie inne bity są skutecznie ignorowane, ponieważ wszystko I nic nie jest niczym. Liczba parzysta w systemie binarnym jest również liczbą parzystą w zapisie dziesiętnym (10 to wielokrotność 2).

Inne podstawowe operacje na systemach dwójkowych to NOT i XOR. NIE oznacza "jeśli A jest wyłączone" i jest jedyną formą bramki logicznej, która pobiera tylko jeden sygnał lub "parametr" zamiast dwóch. XOR oznacza "jeśli albo A, albo B jest włączone, ale nie oba". Są też NAND, NOR i NXOR, które zasadniczo NIE są połączone z AND, OR i XOR, tzn. NAND oznacza "jeśli A i B są , a nie zarówno na".

W programowaniu, operator

& means AND, 
| means OR, 
~ means NOT, and 
^ means XOR. 

Pozostali mogą być wykonane przez łączenie ich, na przykład:

~ (a & b) is equivalent to a NAND operation 

PHP specjalnej nocie

bitowe operatorów nie działają w wartościach zmiennoprzecinkowych, aw PHP wartości zmiennoprzecinkowe będą niejawnie konwertowane na liczby całkowite jako pierwsze. Liczby spoza zakresu, które można wyrazić jako liczby całkowite, zostaną obcięte do zera - to znaczy, że wszystkie liczby w PHP_INT_MAX będą wyglądać "równomiernie" w wyrażeniu ($num & 1)). Jeśli chcesz obsługiwać numery spoza PHP_INT_MIN/PHP_INT_MAX, potrzebujesz fmod($num, 2). Jeśli jednak korzystasz z 64-bitowego PHP, twoje liczby całkowite będą miały większą precyzję niż zmienne.

+2

Osobiście uważam, że wyjaśnia to problem lepiej niż zaakceptowana odpowiedź, ponieważ w rzeczywistości wyjaśnia to, co operacje bitowe robią za kulisami, co jest ** kluczowe ** dla zrozumienia i korzystania z nich. – Byson

11

Wiem, że twoje pytanie dotyczy zrozumienia operatora bitowego, a zaakceptowana odpowiedź wyjaśnia to dobrze. Ale na przykład dajesz, nie mogę pomóc, ale polecając użyć operatora modulo Zamiast:

($var % 2) /* instead of */ ($var & 1) 

ponieważ sprawia, że ​​intencją jasne, że podczas sprawdzania, że ​​liczba jest nieparzysta (nie podzielna przez dwa), a jest bardziej uniwersalne, a więc można go używać ($ var% 3) w ten sam sposób i wydedukować, jak to działa na każdym N.

11

w uzupełnieniu do innych odpowiedzi, warto zauważyć, że

if(func1() && func2()) 

tylko zadzwoń pod numer func2(), jeśli func1() zwraca wartość true ("la ocena zy "), natomiast

if(func1() & func2()) 

wezwie obie funkcje niezależnie, ale tablica prawdy dla obu będzie to samo (zakładając, że wrócą wartości logicznych).


thomasrutter zaznacza (w komentarzach poniżej), że prawdopodobnie nie powinien zrobić ten ostatni w praktyce. (A & B) niekoniecznie będzie miał taką samą prawidłowość jak (A && B), szczególnie gdy A i B są liczbami całkowitymi. np. jeśli A = 1 i B = 2 (obie prawda), A & B będzie falsey, natomiast A & & B jest prawdą. Również inny programista może pomyśleć, że jest to literówka i "poprawił" ją do dwóch ampersandów.

+1

+1, jest to bardzo interesujące i nieznane przez wszystkich – dgraziotin

+0

Ważne rozróżnienie. –

+1

Chociaż działa to * przez większość czasu *, nie zawsze działa, na przykład gdy funkcje zwracają liczby. Powiedzmy, że func1() zwraca 1, a func2() zwraca 4. Funkcja func1() i& func2() 'sprawdzi" true ", a' func1() i func2() 'sprawdzi" 0 ". Nawet w przypadkach, w których to działa, nie nazwałbym tego dobrą praktyką kodowania, ponieważ polega ona na efektach ubocznych porządku oceny i konwersji typu, co utrudnia odczytanie i zrozumienie celu kodu. Każda osoba przeglądająca kod może założyć, że to literówka. – thomasrutter