기본형의 종류와 범위
기본형 (Primitive type) - 종류와 크기
- 논리형 - true와 false중 하나를 값으로 갖으며, 조건식과 논리적 계산에 사용된다. boolean이 있다.
- 문자형 - 문자를 저장하는데 사용되며, 변수 당 하나의 문자만을 저장할 수 있다. char가 있다.
- 정수형 - 정수 값을 저장하는데 사용된다. 주로 사용하는 것은 int와 long이며, byte는 이진 데이터를 다루는데 사용되며, short은 c언어와의 호환을 위해 추가되었다.(short는 잘 안쓰임)
- 실수형 - 실수 값을 저장하는데 사용된다. float와 double이 있다.
※ Java에서는 최소단위가 1byte임., 그리고 Java에서는 문자의 경우 2byte문자 체계인 유니코드를 사용한다.
1 ibit = 2진수 1자리, 1byte는 8bit
종류 \ 크기(byte) | 1byte | 2byte | 4byte | 8byte |
논리형 | boolean(true, false) | |||
문자형 | char | |||
정수형 | byte | short | int(default type) | long |
실수형 | float | double(default type) |
기본형 (Primitive type) - 표현범위
타입의 크기는, 해당 타입으로 선언된 변수의 크기이다.
byte b;
만약 b에 3을 저장하면, 10진수 3이 2진수로 변환되어 저장된다.
즉, 10진수 3이 이진수로 11이므로, 11(2)가 저장된다.
나머지 빈자리에는 0이 채워진다.
1bit, 즉 2진수 한자리에 저장할 수 있는 값의 개수는 0과 1 2개뿐이다. 2 = 2^1
2bit에 저장할 수 있는 값의 갯수는 00, 01, 10, 11 총 4개이다. 4 = 2^2
n비트로 표현할 수 있는 값의 개수 : 2^n개 이다.
n비트로 표현할 수 있는 부호없는 정수의 범위는(양수를 사용하면) 1 ~ 2^n의 범위에 해당하는 정수를 표현할 수 있다.
그러나, 0을 범위에 포함시켜야 하기 때문에, 0 ~ 2(^n) - 1
그래서 8비트로 표현할 수 있는 부호없는 정수의 범위는 0 ~ 255까지이다.
반면에 n비트로 표현할 수 있는 부호있는 정수의 범위는 양수와 음수를 모두 표현할 수 있어야 하기 때문에 표현할 수 있는 범위의 절반을 음수 표현에 사용해야 한다.
즉, n비트로 표현할 수 있는 부호있는 정수의 범위는 -2^(n-1) ~ 2^(n-1) -1
자바에서 정수형은 모두 부호가 있기 때문에, -2^(n-1) ~ 2^(n-1) -1과 타입의 크기만 알고 있으면, 각 정수형의 범위를 쉽게 계산할 수 있다.
바이트 타입의 경우, 크기가 1byte. 즉 8bit이기 때문에, 8비트로 표현할 수 있는 부호있는 정수의 범위는 -2^7 ~ 2(^7) -1 이 된다.
즉, 바이트 타입의 범위는 -128 ~ 127이다.
그러면, 8비트의 부호없는 정수의 범위는 얼마일까? 0 ~ 255 까지이다.
정리해보면,
- n비트로 표현할 수 있는 값의 개수 : 2^n개
- n비트로 표현할 수 있는 부호없는 정수의 범위 : 0 ~ 2(^n) - 1
- n비트로 표현할 수 있는 부호있는 정수의 범위 : -2(^n-1) ~ 2(^n-1) -1
- n비트로 표현할 수 있는 값의 개수는 2^n 개로 똑같지만, 부호의 유무에 따라서 값의 범위가 달라진다.
이번에는, 각 정수형 타입의 변수에 저장할 수 있는 값의 범위를 직접 계산해서 확인해보자.
- byte
byte 타입의 변수에 값이 저장되는 형식, 즉, 저장 형식은 아래와 같다.
전체 8비트 중에서 맨 왼쪽의 1비트를 값의 부호를 나타내는데 사용한다. 이것을 부호비트 혹은 sign bit라고 한다.
이 부호비트의 값이 0이면 양수이고, 1이면 음수이다. 그래서, 이 부호비트의 값만 봐도, 양수인지, 음수인지 알 수 있다.
부호비트를 제외한 나머지 7비트로는, 2^7 즉, 128개의 수를 표현할 수 있다.
양수 128개와 음수 128개 모두 256, 즉 2^8개의 값을 표현할 수 있다. (범위는 0을 포함해야 하기 때문에, 양수의 경우 0~127, 음수의 경우 -1 ~ -128 이다. 그래서 byte타입의 전체범위는 -128 ~ 127이 되는 것이다.
- short
숏타입은 크기가 2byte이므로 , 즉 16bit로 나타낼 수 있는 부호있는 값의 범위는, -2^15 ~ 2(^15) -1 이다.
2^15는 32768이므로 숏타입의 범위는 -32768 ~ 32767 까지 이다.
- char
char타입의 범위는 0 ~ 2(^16) - 1 즉, 0 ~ 65535 이다.
char타입은 문자를 저장하기 위한 타입이지만, 컴퓨터는 모든 데이터를 숫자로 저장하기 때문에, 문자도 지정된 문자코드로 변환되어 저장된다.
예를 들어, 문자 'A'를 변수 ch에 저장하면, 문자 'A' 가 그대로 저장되는 것이 아니라, 문자 'A'의 문자코드인 65가 저장된다. 엄밀히 말하면 2진수로 저장된다.
char타입도 short타입처럼 2byte, 즉 16bit이므로 16자리의 2진수로 변환되는 것이다.
문자코드는, 문자마다 일련번호를 붙여놓은 것이라서 굳이 음수를 사용할 필요가 없다. 따라서 char타입의 저장식에는 부호비트가 없다.
캐릭터 타입은 short타입과 달리 16비트를 모두 양수값을 표현하는데 사용할 수 있다.
그래서 같은 2byte라도 short타입과 chr타입의 범위가 다르다.
즉, 부호가 없으므로 범위는 0 ~ 2(^16)-1 이다. 즉 0 ~ 65535 이다.
- int
integer 타입은 크기가 4byte, 즉 32bit이므로, 범위가 -2^31 ~ 2(^31)-1 이다.
2^31은 2^10 * 2^10 * 2^10 * 2 로 대략 20억이다.
이정도면 왠만한 정수를 다루기에 충분하지만, 떄로는 부족할 수 있기 때문에, integer타입의 범위가 -20억 ~ 20억 이라는 것은 외워 두었다가, 이보다 큰 범위의 값을 다뤄야 할 때, long타입을 사용하면 된다.
- long
long타입의 크기는 8byte이고, 8byte는 64비트이다.
2^63 = 2^3 * 2^60 이다.
2^60은 (2^10)^6이고, 2^10은 약 10^3이므로 2^3 *2^60은 약 8 * 10^18이다. 1경이 10^16이니까, 10^18은 약 800경이다.
그래서 long타입의 범위는 -800경 ~ 800경 이다.
그러면 만약에 800경을 넘는 수를 다뤄야 한다면 어떻게 해야할까? 그럴때는 실수타입 또는 BigInteger라는 클래스를 사용하면 된다.
각 타입의 크기만 알면, 위와 같은 공식으로 최대값과 최소값을 계산할 수 있기 때문에, 각 타입의 최댓값과 최솟값을 굳이 외우지 않아도 된다.
이번에는 실수형인 float와 double타입의 저장형식과 범위에 대해서 알아보자.
- float
먼저 표를 보면, float타입의 변수에 저장 가능한 값의 범위는 1.4*10^-45 ~ 3.4*10^38 이다.
여기서 알파벳 E는 10의 몇제곱인지를 나타내는 기호이다.
위의 표는 양수의 범위만을 적은 것이고, 음수의 범위는 앞에 마이너스(-)를 붙이면 된다.
즉, float타입의 범위는 -3.4 * 10^38 ~ 3.4 * 10^38 이다.
여기 가운데에 -1.4*10(^-45) ~ 1.4*10(^-45) 이부분은 float타입으로 표현할 수 없는 범위이다.
그런데, float타입은 integer타입과 같은 4byte인데, 어떻게해서 이렇게 큰 수를 표현할 수 있는 것일까?
그이유는, float type의 저장 형식에 있다.
float타입은 정수형과 달리 값을, 부호, 지수, 가수 이렇게 3부분으로 나누어 저장한다.
3.4*10^38을 예로 들면, 3.4가 가수, 38이 지수이다.
그래서 같은 크기인 정수형 integer타입보다 float타입으로 훨씬 큰 범위의 수를 표현할 수 있다.
대신에 정수형과 달리 실수형은, 원래 저장하려던 값과 실제로 저장된 값 사이에 오차가 발생할 수 있다.(오차 발생이유는 추후 설명예정)
어쨋든, 실수형은 오차가 발생할 수 있기 떄문에, 정밀도 라는 것이 중요하다.
정밀도라는것은 값을 몇자리까지 오차없이 정확하게 표현할 수 있는지를 의미한다.
float의 경우 오차없이 7자리까지 표현할 수 있다.
정밀도를 결정하는 것은 가수의 자리수이다.
float타입의 가수는 23자리지만, 정규화를 통해서 실제로 24자리까지 저장할 수 있다.
10^7 < 2^24 < 10^8 이다. 따라서 float의 정밀도가 7자리인 것이다.
- double
double은 가수의 자리수가 float의 약 2배이기 때문에,
정밀도도 float의 약 2배인 15자리이다.
정밀도가 float의 2배라서 double이라는 이름이 붙었다.
근데 여기서 중요한 것은, 실수를 저장할 변수의 타입을 결정할 때, 단순히 저장 가능한 값의 범위만으로 타입을 선택해서는 안된다는 것이다.
10^38은 상당히 큰 값이라서 왠만해서는 이 범위를 넘지 않겠지만, 정확한 계산을 해야하는 경우에는 정밀도가 더 중요하다.
정밀도가 중요한 경우에는 float보다 double을 사용해야 한다.
사실 10진수로 7자리 정도의 정밀도는 생각보다 그리 높은 것이 아니어서, 실수형에서는 float가 아니라 double이 default 타입이다.
'JAVA' 카테고리의 다른 글
화면으로부터 입력받기 (0) | 2022.03.13 |
---|---|
printf를 이용한 출력 (0) | 2022.03.12 |
기본형과 참조형 (0) | 2022.03.11 |
두 변수 바꾸기 (0) | 2022.03.11 |
문자, 문자열 리터럴, 문자열 결합 (0) | 2022.03.10 |
댓글
이 글 공유하기
다른 글
-
화면으로부터 입력받기
화면으로부터 입력받기
2022.03.13 -
printf를 이용한 출력
printf를 이용한 출력
2022.03.12 -
기본형과 참조형
기본형과 참조형
2022.03.11 -
두 변수 바꾸기
두 변수 바꾸기
2022.03.11