Java가 int를 바이트로 변환할 때 이상한 동작이 발생합니까?
int i =132;
byte b =(byte)i; System.out.println(b);
출력은 왜?-124
입니다.int
A 32개byte
8분bits
.
되어 있으며 는 서명되어 있습니다.byte
,short
,int
, , , , 입니다.long
되어 있습니다 2는 2의 보어로 부호화되어 있습니다.) (더 2는 2의 보어로 부호화되어 있습니다.)char
이며, 은 type에는 되지 않습니다.boolean
이 번호 체계에서 최상위 비트는 번호의 부호를 지정합니다.더 많은 비트가 필요한 경우 최상위 비트("MSB")가 새 MSB에 복사됩니다.
바이트가 255
11111111
.int
(32비트) 1을 왼쪽으로 24회 복사하기만 하면 됩니다.
음수 2의 보수를 읽는 한 가지 방법은 최하위 비트로 시작하여 첫 번째 1을 찾을 때까지 왼쪽으로 이동한 다음 모든 비트를 반전하는 것입니다.결과 숫자는 해당 숫자의 양의 버전입니다.
를 들면, '먹다'와 같이요.11111111
에 00000001
=-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.println
2'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(negative
1000_0100
) ) )) - )(negative-as(negative
1000_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 입니다.
여기 산만한 이론이 없는 매우 기계적인 방법이 있다.
- 숫자를 이진 표현으로 변환합니다(계산기 사용).
- 오른쪽 끝 8비트(LSB)만 복사하고 나머지는 폐기하십시오.
- 스텝 #2의 결과에서 맨 왼쪽 비트가 0일 경우 계산기를 사용하여 숫자를 10진수로 변환합니다.이게 네 답이야.
- 그렇지 않은 경우(맨 왼쪽 비트가 1인 경우) 답은 부정입니다.오른쪽 끝의 0과 0이 아닌 첫 번째 비트는 변경되지 않은 상태로 둡니다.그리고 나머지를 반대로 바꿔서 1을 0으로 바꾸고 0을 1로 바꿉니다.그런 다음 계산기를 사용하여 10진수로 변환하고 음수 기호를 추가하여 값이 음수임을 나타냅니다.
이 보다 실용적인 방법은 위의 훨씬 이론적인 답변에 따른 것이다.그래서 아직도 자바 책을 읽고 모듈로를 사용하라고 말하는 사람들은 위에서 설명한 4단계는 모듈로 조작이 절대 아니기 때문에 이것은 분명히 잘못된 것입니다.
로는 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++).
- in java int는 4바이트=4x8=32비트
- 바이트 = 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
'programing' 카테고리의 다른 글
이 버전의 MariaDB는 아직 'LIMIT & IN / ALL / ANY / SOME 서브쿼리'를 지원하지 않습니다.여러 WHERE 및 LIMITS (0) | 2022.10.10 |
---|---|
팬더 MultiIndex DataFrame에서 행 선택 (0) | 2022.10.10 |
jQuery를 사용하여 사용자가 div의 맨 아래로 스크롤할 때 감지 (0) | 2022.10.01 |
대문자 부울란과PHP 소문자 (0) | 2022.10.01 |
동적 html 로드 후 클릭 이벤트를 추가하기 위한 jQuery .live() vs .on() 메서드 (0) | 2022.10.01 |