2.1.3 정수형
Java 언어에서는 정수를 표현하기 위한 형식으로 byte, short, int ,long 형식을 제공합니다.
byte 형식은 1바이트의 메모리를 사용하며 short는 2바이트, int는 4바이트, long은 8바이트를 사용합니다. 1bit로 0과 1을 표현할 수 있어서 1바이트(8비트)로 표현할 수 있는 가지 수는 2의 8승인 256가지입니다.
Java 언어에서 정수 형식은 2진 보수 표기 방식으로 부호 있는 수를 표현하므로 byte 형식으로 표현할 수 있는 정수는 -128~127입니다.
2진 보수 표기 방식은 첫 번째 비트가 0이면 부호가 없는 수이며 나머지 비트를 크기를 나타냅니다. 즉 8비트 메모리에 0010 0011 값이 있으면 1의 5승 + 1의 1승 + 1의 0승의 크기를 갖는 35를 나타내는 것입니다.
그리고 첫 번째 비트가 1이면 부호가 있는 수이며 나머지 비트를 2진 보수를 취한 값이 크기를 나타냅니다. 2진 보수를 계산할 때는 1진 보수(0은 1로 1은 0으로 변환)를 계산한 후에 1을 더합니다. 예를 들어 8비트 메모리에 1101 1101 값이 있으면 음수입니다. 두 번째 비트부터 101 1101을 1진 보수로 변환하면 010 0010 이며 1을 더하면 2진 보수를 계산할 수 있는데 이 값이 010 0011입니다. 따라서 8비트 메모리에 1101 1101은 크기가 35인 음수로 -35를 나타낸 것입니다.
이처럼 계산하면 8비트 메모리에 1111 1111 값이 있을 때 음수이며 111 1111을 이진 보수로 변환하면 1000 0000 이 되어 크기가 128입니다. 따라서 -128을 나타낸 것입니다.
그리고 8비트 메모리에 1000 0000 값이 있을 때도 음수이며 000 0000을 이진 보수로 변환하면 000 0001 이 되어 크기가 1입니다. 따라서 -1입니다.
즉 1바이트인 byte 형식은 음수 부분은 -128에서 -1까지 표현할 수 있습니다.
그리고 첫 번째 비트가 0인 부호 없는 수는 0000 0000에서 0111 1111까지 표현할 수 있으므로 0~127까지 표현할 수 있습니다.
따라서 byte 형식은 -128에서 127까지의 정수를 표현할 수 있습니다.
만약 byte 형식 b변수에 127이 있다고 가정합시다. 이 상태에서 변수 b에 b+1을 대입하면 어떻게 될까요? 아무런 변환없이 b = b+1;을 표현하면 byte 형식의 표현 범위를 벗어날 수 있기 때문에 컴파일 오류가 납니다. 이 때는 b = (byte)(b+1); 처럼 b+1 표현의 연산 결과를 byte 형식으로 명확히 변환 요청해야 합니다. 이를 명시적 캐스팅이라 부릅니다.
이렇게 명시적 캐스팅을 사용하여 b = b+1; 을 수행하게 작성하여 실행하면 표현 범위를 벗어나 overflow가 발생합니다. 그리고 해당 값을 확인하면 -128임을 알 수 있습니다.
이는 127은 8비트 메모리에 0111 1111 순으로 표현하며 여기에 1을 더하면 8비트 메모리에 1000 0000 가 되어 -128이 되는 것입니다.
마찬가지로 -128인 변수 b에 b = (byte)(b-1);을 표현하면 b의 값은 127로 바뀝니다.
private static void exByte() { System.out.println("byte 형식"); byte b = 127; b = (byte)(b+1); System.out.println(b); b = (byte)(b-1); System.out.println(b); }
byte 형식 -128 127
short, int, long도 표현 범위만 다를 뿐 같은 원리로 값을 메모리에 표현합니다.