Mam następujący kod Java:
byte value = 0xfe; // corresponds to -2 (signed) and 254 (unsigned)
int result = value & 0xff;
Wynik po wydrukowaniu to 254, ale nie mam pojęcia, jak działa ten kod. Jeśli &
operator jest po prostu bitowy, dlaczego nie daje bajtu, a zamiast tego jest liczbą całkowitą?
java
integer
byte
bitwise-and
dagronlund
źródło
źródło
byte value = (byte) 0xfe;
Odpowiedzi:
Ustawia
result
wartość (bez znaku) wynikającą z umieszczenia 8 bitówvalue
w najniższych 8 bitachresult
.Powodem, dla którego coś takiego jest konieczne, jest to, że
byte
jest to typ podpisany w Javie. Jeśli właśnie napisałeś:wtedy
result
otrzyma wartośćff ff ff fe
zamiast00 00 00 fe
. Kolejną subtelnością jest to, że&
zdefiniowano, aby działał tylko naint
wartościach 1 , więc dzieje się tak:value
jest promowany doint
(ff ff ff fe
).0xff
jestint
literałem (00 00 00 ff
).&
Stosuje się w celu uzyskania pożądanej wartości zaresult
.(Chodzi o to, że konwersja do
int
następuje przed zastosowaniem&
operatora).1 Cóż, niezupełnie.
&
Operator działa nalong
wartości, a także, jeśli którykolwiek z operandów jestlong
. Ale nie włączonebyte
. Zobacz specyfikację języka Java, sekcje 15.22.1 i 5.6.2 .źródło
0x
(lub0X
) informuje Javę, że następujący po nim literał liczby całkowitej powinien być interpretowany jako szesnastkowy (podstawa 16). Java obsługuje również czysty0
prefiks dla literałów ósemkowych i0b
(lub0B
) prefiks dla literałów binarnych. Więcej informacji na temat literałów całkowitych można znaleźć w specyfikacji języka Java .0x
lub0b
sama w sobie (bez żadnych cyfr po niej) jest niedozwoloną składnią w Javie.fe
w 8-bitach, uzupełnienie do dwóch odpowiada wartości dziesiętnej -2. Aby zachować wartość,Integer.valueOf(byte)
należałoby wygenerowaćff ff ff fe
(-2 w 32-bitach, uzupełnienie do dwóch), a nie00 00 00 fe
(wartość dziesiętna 254). Ta transformacja (zbyte
wartoścife
doint
wartościff ff ff fe
) jest znana jako rozszerzenie znaku i jest częścią specyfikacji języka Java. Celem programuvalue & 0xff
jest cofnięcie rozszerzenia znaku (tj. Symulacja rozszerzenia zerowego, czego Java nie ma).Od http://www.coderanch.com/t/236675/java-programmer-SCJP/certification/xff
Literał szesnastkowy 0xFF jest równą int (255). Java reprezentuje int jako 32 bity. Binarnie wygląda to tak:
Kiedy zrobisz trochę mądrze ORAZ z tą wartością (255) na dowolnej liczbie, zamaskuje (zrobi ZERO) wszystkie oprócz najniższych 8 bitów liczby (będzie tak jak jest).
I jest coś takiego jak%, ale nie naprawdę .
A dlaczego 0xff? to w ((potęga 2) - 1). Wszystkie ((potęga 2) - 1) (np. 7, 255 ...) będą zachowywać się jak operator%.
Następnie w
systemie binarnym 0 to wszystkie zera, a 255 wygląda następująco:
I tak wygląda -1
Kiedy wykonasz bitowe AND z 0xFF i dowolną wartość od 0 do 255, wynik jest dokładnie taki sam jak wartość. A jeśli jakakolwiek wartość wyższa niż 255 nadal będzie zawierała się w przedziale 0-255.
Jeśli jednak:
dostajesz
00000000 00000000 00000000 11111111
, co NIE jest równe pierwotnej wartości -1 (11111111
czyli 255 dziesiętnie).Sprawdź, czy konkretny bit jest ustawiony (1) czy nie (0)
Ustaw (1) określony bit
Ponownie ustaw (0) konkretny bit
XOR
Zwróć uwagę, że dwukrotne wykonanie operacji XOR da tę samą wartość.
Jeszcze jedna logika z XOR to
Powyższe jest przydatne do zamiany dwóch zmiennych bez temp, jak poniżej
LUB
źródło
Pomaga zredukować wiele kodów. Jest czasami używany w wartościach RGB, które składają się z 8 bitów.
gdzie 0xff oznacza 24 (0) i 8 (1) podobne
00000000 00000000 00000000 11111111
Widać to najczęściej w przypadkach, takich jak próba przekształcenia wartości kolorów ze specjalnego formatu na standardowe wartości RGB (o długości 8 bitów).
Świetne wyjaśnienie Zobacz tutaj
źródło
W formacie 32 bit systemie szesnastkowym wartość
0xff
oznacza00000000000000000000000011111111
, że jest255(15*16^1+15*16^0)
w układzie dziesiętnym. a operator bitowy & maskuje te same 8 skrajnych prawych bitów, jak w pierwszym operandzie.źródło