본문 바로가기
언어/JAVA

[변수] 타입 변환

by 코딩맛집 2023. 1. 17.

2.3.1 자동 타입 변환

작은 크기를 가지는 타입이 큰 크기를 가지는 타입에 저장될 때 발생한다.

큰 크기 타입과 작은 크기 타입의 구분은 사용하는 메모리 크기이다. 

크기별로 타입을 정리하면 다음과 같다.

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

float가 long보다 더 큰 타입으로 표시된 이유는 표현할 수 있는 값의 범위가 float이 더 크기 때문이다.

char 타입의 경우 int 타입으로 자동 변환되면 유니코드 값이 int 타입에 저장된다.

char charValue = 'A';
int intValue = charValue; //65가 저장

자동 타입 변환에서 단 하나의 예외가 있는데, char는 2byte의 크기를 가지지만, char의 범위는 0~65535이므로 음수가 저장될 수 없다. 따라서 음수가 저장될 수 있는 byte 타입을 char 타입으로 자동 변환시킬 수 없다.

byte byteValue = 65;
char charValue = byteValue; //컴파일 에러
char charData = (char) byteData; //강제 타입 변환

 

2.3.2 강제 타입 변환

큰 크기의 타입을 강제로 쪼개어 작은 크기의 타입으로 변환하는 것을 캐스팅이라고 한다.

예로, int 타입을 4개의 byte로 쪼갠 다음, 끝에 있는 1byte만 byte 타입의 변수에 저장하는 것은 가능하다. 강제 타입 변환은 캐스팅 연산자()를 사용하는데, 괄호 안에 들어가는 타입은 쪼개는 단위이다. 

끝 1byte만 byte 타입 변수에 담게 되므로 원래 int 값은 보존되지 않는다. 하지만 int 값이 끝 1byte로만 표현이 가능하다면 byte 타입으로 변환해도 같은 값이 유지될 수 있다. 이럴 경우 강제 타입 변환이 의미 있게 된다. 

 

실수 타입은 정수 타입으로 강제 타입 변환이 될 때, 소수점 이하 부분은 버려지고, 정수 부분만 저장된다. 주의할 점은 사용자로부터 입력받은 값을 변환할 때 값의 손실이 발생하면 안된다는 것이다. 아래 예제는 byte 타입으로 변환하기 전에 변환될 값이 byte 타입으로 변환된 후에도 값의 손실이 발생하지 않는지 검사해서 올바른 타입 변환이 되도록 한다.

public class Prac {
    public static void main(String[] args){

        int i =128;
        
        if( (i<Byte.MIN_VALUE) || (i>Byte.MAX_VALUE) ) {
            System.out.println("byte 타입으로 변환할 수 없습니다.");
            System.out.println("값을 다시 확인해 주세요.");
        } else {
            byte b = (byte) i;
            System.out.println(b);
        }

    }
}

자바 코드에서 데이터 값을 검사하기 위해 boolean과 char 타입을 제외하고 모든 기본 타입에 대해 최대값과 최소값을 다음과 같이 상수로 제공하고 있다. 어떤 정수값과 실수값을 다른 타입으로 변환하고자 할 때는 변환될 타입의 최소값과 최대값을 벗어나는지 반드시 검사하고 만약 벗어난다면 타입 변환을 하지 말아야 한다.

기본 타입 최대값 상수 최소값 상수  
byte Byte.MAX_VALUE Byte.MIN_VALUE
short Short.MAX_VALUE Short.MIN_VALUE
int Integer.MAX_VALUE Integer.MIN_VALUE
long Long.MAX_VALUE Long.MIN_VALUE
float Float.MAX_VALUE Float.MIN_VALUE
double Double.MAX_VALUE Double.MIN_VALUE

강제 타입 변환에서 정수 타입을 실수 타입으로 변환할 때 정밀도 손실을 피해야 한다. 예로, int 타입 변수 num1, num2에 동일한 1234567890 값을 저장시키고, num2를 float타입으로 변환시킨 후, 다시 int 타입으로 변환해서 num2에 저장한다.

그리고 num1-num2를 result 변수에 저장하고 출력하면 -4가 출력된다. 이러한 문제가 발생하는 이유는 float 타입은 다음과 같이 비트 수가 할당되어 있다.

float: 부호(1비트) + 지수(8비트) + 가수(23비트)

int 값을 손실 없이 float 타입의 값으로 변환할 수 있으려면 가수 23비트도 표현 가능한 double 타입을 사용한다. 1234567890은 23비트로 표현할 수 없어 정밀도 손실이 발생한다.

double: 부호(1비트) + 지수(11비트) + 가수(52비트)

 

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

연산은 기본적으로 같은 타입의 피연산자(operand) 간에만 수행되기 때문에 서로 다른 타입의 피연산자가 있을 경우 두 피연산자 중 크기가 큰 타입으로 자동 변환된 후 연산을 수행한다. 자바는 정수 연산일 경우 int 타입을 기본으로 한다. 그 이유는 4byte 단위로 피연산자를 저장하기 때문에 크기가 작은 타입은 int 타입으로 변환된 후 연산이 수행된다.

'언어 > JAVA' 카테고리의 다른 글

[변수 & 참조 타입] String  (2) 2023.01.23
[참조 타입] 데이터 타입 분류  (0) 2023.01.21
[chapter2] 확인문제  (0) 2023.01.16
[chapter3] 확인문제  (0) 2023.01.16
[chapter4] 확인문제  (0) 2023.01.16