value & 0xff는 Java에서 무엇을합니까?


101

다음 Java 코드가 있습니다.

byte value = 0xfe; // corresponds to -2 (signed) and 254 (unsigned)
int result = value & 0xff;

인쇄하면 결과는 254이지만이 코드가 어떻게 작동하는지 모르겠습니다. 경우 &운영자는 단순히 비트, 왜 그것은 바이트 대신 정수 발생하지 않습니다입니까?


코드를 Eclipse에 복사합니다. "유형 불일치 : int에서 바이트로 변환 할 수 없습니다"라고 경고합니다. int 값 = 0xfe로 변경해야합니다.
Ben Cheng

1
@BenCheng이어야합니다byte value = (byte) 0xfe;
Bek

답변:


173

의 하위 8 비트에 result의 8 비트를 넣은 결과 (부호없는) 값으로 설정 됩니다 .valueresult

이와 같은 것이 필요한 이유 byte는 Java에서 서명 된 유형 이기 때문 입니다. 방금 쓴 경우 :

int result = value;

그런 다음 대신 result값으로 끝납니다 . 더 미묘한 점은가 값 1 에서만 작동하도록 정의되어 있다는 것입니다.ff ff ff fe00 00 00 fe&int

  1. valueint( ff ff ff fe) (으 ) 로 승격됩니다 .
  2. 0xff이다 int리터럴 ( 00 00 00 ff).
  3. &대한 원하는 값을 산출하기 위해이 적용됩니다 result.

(포인트 전환 인 것을 int발생 하기 전에& 연산자 적용된다.)

1 글쎄요. &오퍼레이터 작동 long피연산자가 인 경우뿐만 값 long. 하지만 byte. Java 언어 사양, 섹션 15.22.15.6.2를 참조하십시오 .


그 표기법에서 x는 무엇을 의미합니까? x는 숫자 또는 16 진수가 아닙니까?
Callat 2016 dec. 05. 05

3
@KazRodgers- 0x(또는 0X) 접두사는 뒤에 오는 정수 리터럴이 16 진수 (기본 16)로 해석되어야 함을 Java에 알려줍니다. Java는 또한 08 진 리터럴에 대해 베어 접두어를 지원하고 이진 리터럴에 대해 0b(또는 0B) 접두사를 지원합니다. 정수 리터럴에 대한 자세한 내용은 Java 언어 사양 을 참조하십시오 .
Ted Hopp

뒤에 오는 리터럴? 예를 들어 0x3fa가 있다면. 3fa는 리터럴 숫자로 번역되는 부분이고 0x는 "이것은 16 진수입니다"라고 표시합니까? @TedHopp?
Callat

1
@KazRodgers-맞습니다. 참고 0x또는 0b자바에서 불법 구문은 그 자체로 (다음 자릿수없이).
Ted Hopp

1
@DmitryMinkovsky fe-8 비트의 16 진수 비트 패턴 , 2의 보수는 10 진수 값 −2에 해당합니다. 값을 유지하려면 (10 진수 값 254)가 아니라 ( 32 비트에서 -2, 2의 보수) Integer.valueOf(byte)를 생성해야합니다 . 이 변환 ( 값 에서 값으로 )은 부호 확장으로 알려져 있으며 Java 언어 사양의 일부입니다. 의 목적은 부호 확장을 실행 취소하는 것입니다 (즉, 0 확장을 시뮬레이션하기 위해 Java에없는 것). ff ff ff fe00 00 00 febytefeintff ff ff fevalue & 0xff
Ted Hopp

57

에서 http://www.coderanch.com/t/236675/java-programmer-SCJP/certification/xff

16 진수 리터럴 0xFF는 동일한 int (255)입니다. Java는 int를 32 비트로 나타냅니다. 바이너리에서 다음과 같이 보입니다.

00000000 00000000 00000000 11111111

임의의 숫자에 대해이 값 (255)을 사용하여 비트 단위 AND를 수행하면 숫자의 가장 낮은 8 비트를 제외한 모든 것을 마스킹 (제로 만들기)합니다 (있는 그대로).

... 01100100 00000101 & ...00000000 11111111 = 00000000 00000101

&는 %와 비슷하지만 실제로는 아닙니다 .

그리고 왜 0xff?이것은 ((2의 거듭 제곱)-1)입니다. 모든 ((2의 거듭 제곱)-1) (예 : 7, 255 ...)는 % 연산자처럼 동작합니다.

그런
다음 바이너리에서 0은 모두 0이며 255는 다음과 같습니다.

00000000 00000000 00000000 11111111

그리고 -1은 다음과 같습니다.

11111111 11111111 11111111 11111111

0xFF의 비트 AND와 0에서 255 사이의 값을 수행하면 결과는 값과 정확히 동일합니다. 255보다 큰 값이 여전히 있으면 결과는 0-255 내에 있습니다.

그러나 다음과 같은 경우 :

-1 & 0xFF

당신은 얻을

00000000 00000000 00000000 11111111, -1의 원래 값과 같지 않습니다 ( 11111111십진수로 255).


조금 더 많은 조작 : (질문과 관련이 없음)

X >> 1 = X/2
X << 1 = 2X

특정 비트가 설정되었는지 (1) 또는 설정되지 않았는지 (0) 확인한 다음

 int thirdBitTobeChecked =   1 << 2   (...0000100)
 int onWhichThisHasTobeTested = 5     (.......101)

 int isBitSet = onWhichThisHasTobeTested  & thirdBitTobeChecked;
 if(isBitSet > 0) {
  //Third Bit is set to 1 
 } 

특정 비트 설정 (1)

 int thirdBitTobeSet =   1 << 2    (...0000100)
 int onWhichThisHasTobeSet = 2     (.......010)
 onWhichThisHasTobeSet |= thirdBitTobeSet;

특정 비트를 다시 설정 (0)

int thirdBitTobeReSet =   ~(1 << 2)  ; //(...1111011)
int onWhichThisHasTobeReSet = 6      ;//(.....000110)
onWhichThisHasTobeReSet &= thirdBitTobeReSet;

XOR

XOR 연산을 두 번 수행하면 동일한 값이 생성됩니다.

byte toBeEncrypted = 0010 0110
byte salt          = 0100 1011

byte encryptedVal  =  toBeEncrypted ^ salt == 0110 1101
byte decryptedVal  =  encryptedVal  ^ salt == 0010 0110 == toBeEncrypted :)

XOR의 또 다른 논리는

if     A (XOR) B == C (salt)
then   C (XOR) B == A
       C (XOR) A == B

위의 내용은 아래와 같이 temp없이 두 변수를 교환하는 데 유용합니다.

a = a ^ b; b = a ^ b; a = a ^ b;

또는

a ^= b ^= a ^= b;



5

많은 코드를 줄이는 데 도움이됩니다. 때때로 8 비트로 구성된 RGB 값에서 사용됩니다.

0xFF를 의미 곳 (24) ( '0') 및도 8 (1 'S)00000000 00000000 00000000 11111111

변수를 효과적으로 마스킹하여 마지막 8 비트의 값만 남기고 나머지 비트는 모두 무시합니다.

색상 값을 특수 형식에서 표준 RGB 값 (8 비트 길이)으로 변환하려는 경우와 같은 경우에 가장 많이 나타납니다.

훌륭한 설명 여기를 참조하십시오


0

32 비트 포맷 시스템에서의 16 진수 값을 0xff나타낸다 00000000000000000000000011111111255(15*16^1+15*16^0)십진수. 비트 및 연산자는 첫 번째 피연산자에서와 같이 가장 오른쪽에있는 8 비트를 마스킹합니다.


좀 더 설명해 주 시겠어요?
ashishdhiman2007 2007
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.