간단 지식/Java

01. 자동타입변환과 강제타입변환

납작한돌맹이 2020. 5. 1. 23:41
반응형

데이터 타입을 크기 순으로 나열해보면 다음과 같다.

byte(1) < short(2) <= char(2) < int(4) < long(8) < float(4) < double(8)

가장 기본이 되는 1byte를 시작으로 8byte인 double까지가 우리가 쓰는 데이터 타입이라 말할 수 있다.

long과 float은 byte만을 놓고 보면 long이 크다고 할 수 있지만, 값의 표현 범위는 float이 훨씬 넓다.


이렇게 여러 데이터 타입들을 가지고 연산식을 만들고 프로그램을 실행하면, 필연적으로 서로 다른 타입을 가진 피연산자들이 만나게 된다. 컴퓨터는 같은 타입 간의 연산 만을 이해하고 수행하기 때문에 피연산자들의 타입을 변환하는 작업을 해야 한다.

자동타입변환

프로그램 실행 중 자동으로 타입 변경

작은 데이터 타입에 저장된 값이 큰 데이터 타입에 저장될 때 발생

ex) byte value = 10;                               

int value2 = value;   <- 여기서 변환 발생

 

강제타입변환

casting이라고도 부르며 개발자가 직접 타입 변경

큰 데이터 타입에 저장된 값이 작은 데이터 타입에 저장해야 할 때 변경

큰 데이터 타입의 변수 앞에 ( )로 작은 데이터 타입을 적어 캐스팅

ex) int value = 10;                                       

byte value2 = (byte)value;   <- 여기서 캐스팅

 

 

좀 더 깊은 이해를 위해 타입 변환 시 메모리에서 일어나는 변화를 알아보겠다.

byte value = 10; 이 실행될 때 할당된 메모리(1byte)는 다음과 같다.

00001010

그리고 int value2 = value; 가 실행될 때 할당된 메모리(4byte)는 다음과 같다.

00000000 00000000 00000000 00001010

작은 컵의 물을 큰 컵에 옮길 때 물 질량의 손실이 없듯이, 자동타입변환에서는 값의 손실이 일어날 수 없다.

그러나 반대의 개념인 강제타입변환에서는 값의 손실이 발생할 것이다.

예를 들어 int value = x; 가 실행될 때 할당된 메모리(4byte)는 다음과 같을 것이다.(x는 임의의 큰 수)

01011100 00100100 11001101 00100010

그리고 byte value2 = (byte)value; 가 실행될 때 다음과 같이 1byte만이 저장될 수 있기 때문에 값이 누락된다.

x x x 00100010

타입 변환에서의 예외사항과 주의사항

1) 자동타입변환

    int --변환--> float, double : 끝에 소수점 .0을 추가하여 값을 표현

    char --변환--> int : unicode 값으로 변환

2) 강제타입변환

    float, double --변환--> byte, short, int, long : 소수점 아래 값은 누락

3) 예외사항

    자동타입변환에서 다른 타입을 char형으로 변환하는 것은 컴파일 에러가 발생한다. char의 범위는 0부터 시작되기 때문에 음수가 저장될 수 있는 타입인 byte, short, int, long, float, double은 캐스팅 후 char형으로 변환할 수 있다.

4-1) 주의사항1

   아무래도 개발자가 직접 지정해야 하는 강제타입변환에는 주의해야 하는 점이 있다. 그건 바로 위에서도 언급한 실이 발생하지 않도록 검사하는 것이 중요하다. 가장 기본적인 검사방법은 if문을 이용한 방법이다.

대략적인 구조는 다음과 같다.

   if (i<최솟값상수 || i>최댓값상수)

            변환x

   else

            변환o

여기서 i는 타입이 변환될 변수, 최솟값&최댓값상수는 변환할 type명.MIN_VALUE, type명.MAX_VALUE로 표현한다.

4-2) 주의사항2

   자동타입변환에서 손실이 일어나지 않을 거라 장담할 수 없다. 예를 들어 동일한 값을 가진 int형 변수 n1, n2가 있다고 가정해보자. 지금은 n2-n1=0 이지만, n1을 float형으로 변환하고, 다시 int형으로 재변환해보자. n2-n1의 결과는 여전히 0일까? 답은 변수에 저장된 정수의 크기에 따라 달라진다.

그 원인은 n1을 float형으로 변환하는 과정에 있다. float은 부호bit(1) + 지수bit(8) + 가수bit(23)으로 구성되는데, 가수bit가 변환할 int형 값을 다 담지 못하면 손실이 발생하여 근삿값으로 변환된다. 즉 정밀도 손실이 발생한다. 해결책은 단순하다. double을 사용하면 된다. double은 부호bit(1) + 지수bit(11) + 가수bit(52)으로 구성된다. int는 최대 크기가 32bit이기 때문에 손실이 절대 발생할 수 없다.

cf) 연산식에서의 자동타입변환   

   연산식은 같은 타입의 피연산자끼리 연산되는 게 일반적이지만, 서로 다른 타입의 피연산자들이 만나면 타입크기가 큰 쪽으로 변환된 후 연산된다. 즉 자동타입변환이 디폴트다. 크기가 작은 타입으로 결과를 내고 싶다면 개발자가 캐스팅을 해줘야 한다.

 

 

(이 글이 도움이 됐다면 광고 한번씩만 클릭 해주시면 감사드립니다, 더 좋은 정보글 작성하도록 노력하겠습니다 :) )

반응형