MSM8994의 화룡점정 블로그

Java 자료형 범위 초과시 자료가 저장되는 방식 본문

코딩

Java 자료형 범위 초과시 자료가 저장되는 방식

msm8994 2018. 7. 12. 07:00

위 코드에서 b+i 대신 (char) (b+i) 를 하면 범위가 초과되어 다른 수가 저장되고, 0x12340041을 char로 강제변환한 결과가 0x0041이 되는지 이해하기 힘드셨을것 같습니다


byte의 범위는 -128부터 -1까지 음수 128개, 0부터 127까지 양수 128개 총 256가지의 수를 표현할 수 있습니다.
유니코드 문자 하나를 저장하는 char는 0x0000부터 0xFFFF까지 65536가지를 표현할 수 있습니다.
JDK 8부터 int와 long도 양수전용(unsigned)이 될 수 있다고 하지만 그냥 Java에선 양음수 둘 다 표현하기 위해 양수 범위가 반토막 나있다고 생각하시는게 편합니다.


여기서 b+i는 227입니다. 이미 b가 byte상 양수 최대치인 127(0111 1111)에 왔기 때문에
여기서 1을 더하면 128(1000 0000)이 되야하겠죠?
컴퓨터에서 음수 표현은 수를 2진수로 변환한 다음
각 비트를 대로 뒤집은 뒤 1을 더한 값인 2의 보수를 사용합니다.
그래서 127(0111 1111) 을 뒤집은 다음 1을 더한 값이 -127(1000 0001)이 되고,
하나씩 더해가면 -1(1111 1111)로 돌아옵니다.
여기서 1을 더하면 256(1 0000 0000) 이 아니냐고 생각하시겠지만
1인 9번째 비트는 8비트인 byte 자료형에서 칸이 모자라 버려지게 됩니다.
버려진 비트를 제외하고 남은 0000 0000은 0이 됩니다.

그럼 (byte) (127 + 100) 을 구할 수 있겠죠?
127+1이 -128이 되므로 나머지 99를 여기에 더하면 -29가 되는 것입니다.


char 0x12340041은 2진수로 (0001 0010 0011 0100 0000 0000 0100 0001) 입니다.
16진수 하나는 4비트로 2진수 4자리로 바로 변환할 수 있습니다.

2바이트(16비트)인 char 자료형은 하나에 4비트인 16진수 4자리를 표현할 수 있습니다.
방금 127(0111 1111)에 1을 더하면 -128(1000 0000)이 된다고 했는데
그럼 여기서도 -32768(1000 0000 0000 0000)이 되지 않을까요 라고 생각하셨다면 그건 short 입니다.
short와 자료형 크기는 같지만 양으로만 표현이 가능한 char는 16번째 비트 역시 부호 비트가 아니라 수를 표현하는데 사용합니다.

0x12340041의 뒷쪽 16비트만 남고 앞쪽은 무시해도 됩니다.
값이 넘더라도 0으로 넘어가지 음수로 넘어가지 않기 때문에 추가적인 계산이 소용없습니다.



그냥 듣기엔 많이 어려우실 것 같지만 2진수로 생각해보신다면 난이도가 조금 내려갈 것 같습니다.
열공하세요


Comments