반응형

기본형 (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