[java] Java가 int를 바이트로 변환 할 때 이상한 행동?

int i =132;

byte b =(byte)i; System.out.println(b);

마인드 글링. 왜 출력 -124입니까?



답변

Java에서는 int32 비트입니다. A byte는 8 bits입니다.

자바에있는 대부분의 기본 유형이 서명되고 byte, short, int, 및 long2의 보수로 인코딩됩니다. 합니다 ( char유형은 부호이며, 기호의 개념은 적용되지 않습니다 boolean.)

이 숫자 체계에서 최상위 비트는 숫자의 부호를 지정합니다. 더 많은 비트가 필요한 경우 가장 중요한 비트 ( “MSB”)가 새 MSB에 복사됩니다.

그래서 당신은 바이트가있는 경우 255: 11111111
당신은로 표현하려는 int당신이 단순히로 1가 24 번 왼쪽 복사 (32 비트).

음의 2의 보수 수를 읽는 한 가지 방법은 최하위 비트로 시작하여 첫 번째 1을 찾을 때까지 왼쪽으로 이동 한 다음 이후에 모든 비트를 뒤집는 것입니다. 결과 숫자는 해당 숫자의 양수입니다.

예를 들어, = 11111111로 이동합니다 . 이것이 Java가 값으로 표시하는 것입니다.00000001-1

아마도 당신이하고 싶은 것은 부호없는 바이트 값을 아는 것입니다.

가장 중요하지 않은 8 비트를 제외한 모든 것을 삭제하는 비트 마스크를 사용하여이 작업을 수행 할 수 있습니다. (0xff)

그래서:

byte signedByte = -1;
int unsignedByte = signedByte & (0xff);

System.out.println("Signed: " + signedByte + " Unsigned: " + unsignedByte);

인쇄 할 것 : "Signed: -1 Unsigned: 255"

실제로 여기서 무슨 일이 일어나고 있습니까?

우리는 비트 단위 AND를 사용하여 모든 외부 부호 비트 (가장 중요한 8 비트의 왼쪽에 1이 있음)를 마스킹합니다. int가 바이트로 변환 될 때 Java는 가장 왼쪽의 24 비트를 잘라냅니다.

1111111111111111111111111010101
&
0000000000000000000000001111111
=
0000000000000000000000001010101

32 번째 비트는 이제 8 번째 비트 대신 부호 비트이므로 부호 비트를 0으로 설정하면 양수 값으로 Java에서 바이트의 원래 8 비트를 읽습니다.


답변

132자릿수 ( 기본 10 )는 1000_0100비트 ( 기본 2 )이고 Java는 int32 비트로 저장 됩니다.

0000_0000_0000_0000_0000_0000_1000_0100

int-to-byte의 알고리즘은 왼쪽 잘림입니다. 에 대한 알고리즘 System.out.println2의 보수입니다 ( 2의 보수는 가장 왼쪽에있는 비트가 1이면 음의 1의 보수 (비트 반전)에서 1을 뺀 것으로 해석됩니다 ). 따라서 System.out.println(int-to-byte( )):

  • 인터프리터로 (if-leftmost-bit-is-1 [negative (invert-bits (minus-one (] left-truncate ( 0000_0000_0000_0000_0000_0000_1000_0100) [)))]))
  • = interpret-as (if-leftmost-bit-is-1 [negative (invert-bits (빼기 -one (] 1000_0100[)))])
  • = 인터 프리트 그대로 (음 (인버트 비트 (마이너스-원 ( 1000_0100))))
  • = 인터 프리트 그대로 (음 (인버트 비트 ( 1000_0011)))
  • = 그대로 해석 (음수 ( 0111_1100))
  • = 그대로 해석 (음수 (124))
  • =-으로 해석 (-124)
  • = -124 타다 !!!

답변

Java의 바이트는 부호가 있으므로 -2 ^ 7-2 ^ 7-1 범위, 즉 -128-127입니다. 132가 127보다 높으므로 132-256 = -124로 줄 바꿈됩니다. 즉, 기본적으로 256 (2 ^ 8)은 범위에 들어갈 때까지 더하거나 뺍니다.

자세한 내용은 2의 보수 를 읽으십시오 .


답변

132는 -128 ~ 127 (Byte.MIN_VALUE ~ Byte.MAX_VALUE) 인 바이트 범위를 벗어납니다. 대신 8 비트 값의 최상위 비트는 부호가있는 것으로 간주되어이 경우 음수임을 나타냅니다. 따라서 숫자는 132-256 = -124입니다.


답변

혼란스러운 이론이없는 매우 기계적인 방법은 다음과 같습니다.

  1. 숫자를 이진 표현으로 변환하십시오 (계산기 사용?)
  2. 맨 오른쪽 8 비트 (LSB) 만 복사하고 나머지는 버립니다.
  3. 2 단계의 결과에서 맨 왼쪽 비트가 0이면 계산기를 사용하여 숫자를 10 진수로 변환하십시오. 이것이 당신의 대답입니다.
  4. 그렇지 않으면 (가장 왼쪽 비트가 1 인 경우) 대답은 부정적입니다. 가장 오른쪽의 모든 0과 0이 아닌 첫 번째 비트는 변경하지 마십시오. 나머지는 반대로 1을 0으로 바꾸고 0을 1로 바꿉니다. 그런 다음 계산기를 사용하여 10 진수로 변환하고 음수 부호를 추가하여 값이 음수임을 나타냅니다.

이보다 실용적인 방법은 위의 많은 이론적 답변에 따릅니다. 따라서 여전히 모듈로를 사용한다고 말하는 Java 책을 읽는 사람들은 위에서 설명한 4 단계가 모듈로 작업이 아니기 때문에 분명히 잘못되었습니다.


답변

2의 보수 방정식 :

여기에 이미지 설명을 입력하십시오


Java에서 byte(N = 8) 및 int(N = 32)는 위에 표시된 2의 보수로 표시됩니다.

방정식에서 7 은 음수 byte이지만 에 대해서는 양수입니다 int.

coef:   a7    a6  a5  a4  a3  a2  a1  a0
Binary: 1     0   0   0   0   1   0   0
----------------------------------------------
int:    128 + 0 + 0 + 0 + 0 + 4 + 0 + 0 =  132
byte:  -128 + 0 + 0 + 0 + 0 + 4 + 0 + 0 = -124


답변

종종 책에서 모듈로 나누기에 의해 int에서 byte로 캐스트하는 방법에 대한 설명을 찾을 수 있습니다. 이것은 아래에 표시된 것처럼 정확히 정확하지 않습니다. 실제로 가장 왼쪽에있는 비트가 설정되어 숫자를 음수로 지정하면 int 수의 이진 값에서 24 개의 최상위 비트가 무시되고 혼란이 남습니다.

public class castingsample{

public static void main(String args[]){

    int i;
    byte y;
    i = 1024;
    for(i = 1024; i > 0; i-- ){

      y = (byte)i;
      System.out.print(i + " mod 128 = " + i%128 + " also ");
      System.out.println(i + " cast to byte " + " = " + y);

    }

}

}