programing

Java가 int를 바이트로 변환할 때 이상한 동작이 발생합니까?

goodsources 2022. 10. 10. 18:31
반응형

Java가 int를 바이트로 변환할 때 이상한 동작이 발생합니까?

int i =132;

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

출력 왜?-124

입니다.intA 32개byte 8분bits.

되어 있으며 는 서명되어 있습니다.byte,short,int , , , , 입니다.long되어 있습니다 2는 2의 보어로 부호화되어 있습니다.) (더 2는 2의 보어로 부호화되어 있습니다.)char이며, 은 type에는 되지 않습니다.boolean

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

바이트가 25511111111.int(32비트) 1을 왼쪽으로 24회 복사하기만 하면 됩니다.

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

를 들면, '먹다'와 같이요.1111111100000001=-1자바어

이 경우 바이트의 부호 없는 값을 알아야 합니다.

최하위 8비트를 제외한 모든 것을 삭제하는 비트마스크를 사용하면 이를 실현할 수 있습니다(0xff).

그래서:

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

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

예정 : 력: :"Signed: -1 Unsigned: 255"

여기서 실제로 무슨 일이 일어나고 있는 거죠?

모든 외부 부호 비트( 최하위 8비트의 왼쪽에 있는 1)를 마스킹하기 위해 비트 단위 AND를 사용하고 있습니다.int가 바이트로 변환되면 Java는 맨 왼쪽의 24비트를 잘라냅니다.

1111111111111111111111111010101
&
0000000000000000000000001111111
=
0000000000000000000000001010101

32번째 비트가 8번째 비트 대신 부호 비트이기 때문에(그리고 부호 비트를 양의 0으로 설정), Java는 바이트의 원래 8비트를 양의 값으로 읽습니다.

132디짓(베이스 10)은1000_0100비트(베이스 2) 및 Java 스토어int 32비트:

0000_0000_0000_0000_0000_0000_1000_0100

트렁크이고 int-to-byte 은 왼쪽 트렁크입니다.알고리즘은System.out.println2's-completion (2's-completion은 왼쪽 끝의 비트가1, 음의 one-completion(인버트 비트) - 1로 해석합니다.따라서System.out.println(int-to-byte( )) 말합니다

  • ( if - - - bit - - 1 [ ( bits ( bits ( sweight - one ) ) negative ( bits ( sweight - one ) - bit - ) left - bit cate negative ) ) )0000_0000_0000_0000_0000_0000_1000_0100 [ ) > > > > >
  • if-left-most-bit-is-1)][negative(negative)]1000_0100 ) ] ] ] [ ] ] ]
  • =)(negativenegative)((negative-bits)(=negratic-as(negative)(negratic-bits(negative1000_0100 ) ) ))
  • )(negative-as(negative1000_0011 ) ) )
  • =음수)(=negative(음수0111_1100
  • =부정적(부정적)
  • = as precision)
  • =-타다!!

Java의 바이트는 부호화되어 있기 때문에 -2^7 ~ 2^7-1 - 즉 -128 ~127 의 범위를 가집니다.132가 127보다 높기 때문에 132-256=-120으로 감깁니다.즉, 256(2^8)이 범위에 들어갈 때까지 가산 또는 감산됩니다.

자세한 내용은 2의 보충문을 읽어보시기 바랍니다.

132는 -128 ~127(바이트)의 바이트 범위를 벗어납니다.MIN_VALUE에서 바이트로MAX_VALUE) 대신 8비트 값의 상위 비트는 부호 있는 비트로 처리되며, 이 경우 음수임을 나타냅니다.그래서 숫자는 132 - 256 = - 132 입니다.

여기 산만한 이론이 없는 매우 기계적인 방법이 있다.

  1. 숫자를 이진 표현으로 변환합니다(계산기 사용).
  2. 오른쪽 끝 8비트(LSB)만 복사하고 나머지는 폐기하십시오.
  3. 스텝 #2의 결과에서 맨 왼쪽 비트가 0일 경우 계산기를 사용하여 숫자를 10진수로 변환합니다.이게 네 답이야.
  4. 그렇지 않은 경우(맨 왼쪽 비트가 1인 경우) 답은 부정입니다.오른쪽 끝의 0과 0이 아닌 첫 번째 비트는 변경되지 않은 상태로 둡니다.그리고 나머지를 반대로 바꿔서 1을 0으로 바꾸고 0을 1로 바꿉니다.그런 다음 계산기를 사용하여 10진수로 변환하고 음수 기호를 추가하여 값이 음수임을 나타냅니다.

이 보다 실용적인 방법은 위의 훨씬 이론적인 답변에 따른 것이다.그래서 아직도 자바 책을 읽고 모듈로를 사용하라고 말하는 사람들은 위에서 설명한 4단계는 모듈로 조작이 절대 아니기 때문에 이것은 분명히 잘못된 것입니다.

2의 보완 방정식:

여기에 이미지 설명 입력


로는 byte) 및 (N=8) »int(N=32)을 클릭합니다.

식에서 a는7 음수이다.byte이긴 하지만, for, for, for, for, for, for에 대해서는 긍정적이다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에서 바이트로의 캐스팅에 대한 설명을 찾을 수 있을 것이다.이것은 아래 그림과 같이 엄밀하게 정확하지 않습니다.실제로 일어나는 일은 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);

    }

}

}

동작 방법을 시뮬레이트 하는 퀵알고리즘은 다음과 같습니다.

public int toByte(int number) {
    int tmp = number & 0xff
    return (tmp & 0x80) == 0 ? tmp : tmp - 256;
}

어떻게 작동하나요? daxtr 답변을 보세요.그의 답변에 기재되어 있는 정확한 알고리즘의 실장은 다음과 같습니다.

public static int toByte(int number) {
    int tmp = number & 0xff;
    if ((tmp & 0x80) == 0x80) {
        int bit = 1;
        int mask = 0;
        for(;;) {
            mask |= bit;
            if ((tmp & bit) == 0) {
                bit <<=1;
                continue;
            }
            int left = tmp & (~mask);
            int right = tmp & mask;
            left = ~left;
            left &= (~mask);
            tmp = left | right;
            tmp = -(tmp & 0xff);
            break;
        }
    }
    return tmp;
}

이걸 수학적으로 이해하려면 어떻게 해야 하는지

따라서 기본적으로 숫자 b/w -128 ~127은 10진수 값과 동일하게 입력되며, 그 위에 숫자 - 256이 입력됩니다.

예: 132. 답은 132 - 256 = - 124가 될 것이다.

256 + 256 + (-displaces)의 답은 132입니다.

다른 예

double a = 295.04;
int b = 300;
byte c = (byte) a;
byte d = (byte) b; System.out.println(c + " " + d);

출력은 3944가 됩니다.

(295 - 256) (300 - 256)

메모: 소수점 이후의 숫자는 고려되지 않습니다.

개념적으로 -128 ~+127 의 범위에 이를 때까지, 256 의 반복 감산이 행해집니다.따라서 이 경우 132로 시작해서 -124로 끝납니다.

계산상으로는 이것은 원래 수치에서 최하위8비트를 추출하는 것에 해당합니다.(그리고 이들 8비트의 최상위 비트가 부호 비트가 됩니다.)

다른 언어에서는 이 동작이 정의되어 있지 않습니다(예를 들어 C 및 C++).

  1. in java int는 4바이트=4x8=32비트
  2. 바이트 = 8비트 범위 =-128 ~127

'int'를 'byte'로 변환하는 것은 큰 물체를 작은 상자에 끼워 넣는 것과 같다

사인인 -ve가 2의 보수가 되는 경우

예 1: 번호를 130으로 합니다.

스텝 1:130 비트간격 = 1000 0010

스텝 2: 콘디더의 첫 번째 7비트와 8비트가 부호(1=-ve 및 =+ve)

스텝 3: 첫 번째 7비트를 2에 추가

            000 0010   
          -------------
            111 1101
       add         1
          -------------
            111 1110 =126

스텝 4:8번째 비트는 "1"이므로 부호는 -ve입니다.

스텝 5: 130=120 바이트

예 2: 번호는 500으로 해 주세요.

스텝 1:500 비트 0001 1111 0100 인터밀리초

스텝 2: 첫 번째 7비트 출력 = 출력 0100

3단계: 나머지 비트는 '11'입니다. -ve 기호를 제공합니다.

4단계: 2의 칭찬을 받아들인다.

        111 0100
      -------------
        000 1011 
    add        1
      -------------
        000 1100 =12

5단계: 500=-12바이트

예 3: number=300

 300=1 0010 1100

 1st 7 bits =010 1100

 remaining bit is '0' sign =+ve need not take 2's compliment for +ve sign

 hence 010 1100 =44

 byte(300) =44
 N is input number
case 1: 0<=N<=127  answer=N;
case 2: 128<=N<=256 answer=N-256 
case 3: N>256   
        temp1=N/256;
        temp2=N-temp*256;
        if temp2<=127   then answer=temp2;
        else if temp2>=128  then answer=temp2-256;
case 4: negative  number input
        do same procedure.just change the sign of the solution           

언급URL : https://stackoverflow.com/questions/842817/odd-behavior-when-java-converts-int-to-byte

반응형