본문 바로가기
study_java/java_수강정리(~10.29)

[JAVA]4일차

by developer_j 2020. 5. 15.
728x90
반응형

< 수업 4일차 >

 

4일차 수업의 핵심.

형. 변. 환.

형변환이란 변수 또는 상수의 자료형을 변환하는 것이다. 우리는 처리하려는 데이터들의 타입을 왜 굳이 바꾸어야 할까?

우선, 값이 같더라도 실수형 데이터와 정수형 데이터는 데이터 처리 방법이 매우 다르다.

int형 정수 200의 bit :            00000000 00000000 00000000 11001000

float형 정수 200.0의 bit :     01000011 01001000 00000000 00000000

이처럼 같은 값이어도 데이터 bit의 형태가 매~우 다르다. 이렇게 다른 데이터들을 동시에 다루고, 연산하고, 대입해야하므로 우리는  데이터들의 자료형을 하나로 맞춰야 한다. 그리고 그 과정이 바로 형변환이다. 형변환은 변수에 변수값으로 무언가를 대입하거나, 연산을 할 때 타입이 다르면 일어난다.

형변환의 종류에는 자동 형변환명시적 형변환이 있다.  자동 형변환은 말그대로 컴퓨터가 알아서 내부적으로 형변환을 시키는 것이다. 큰 바구니 안에 더 작은 바구니가 쏙 들어가는 것처럼, 더 큰 범위를 표현할 수 있는 자료형 변수안에는 더 작은 자료형 변수가 들어갈 수 있다. 더 작은 자료형 변수는 bit 자리를 늘리기만 하면 되니까 비교적 쉽게 자동형변환이 이루어진다. 한편 명시적 형변환은 사용자가 수동적으로 변환할 자료형을 데이터 앞에 의도적으로 표현해주는 것을 말한다. 작은 바구니 안에 더 큰 바구니를 넣으려면 자르거나 모양을 구겨야 한다. CPU가 큰 데이터를 일부러 작게 표현하기 위해 데이터를 잘라내야한다는 뜻이다. 사용자가 의도한 결과라면 다행이지만, 아닐 수도 있다. 따라서 좀 더 명확하게 해두기 위해서 명시적으로 사용자가 직접 데이터 데이터의 자료형을 맞춰주기 위해 형변환 표시를 해준다. 

형변환은 아래그림의 형변환 원칙을 기준으로 한다.화살표 방향으로 갈수록 더 큰 바구니라고 생각하면 된다. 바이트 크기 순서대로 인 것 같지만 아니다. 그럼 long이 float보다 뒷자리에 있어야 되지 왜 저렇게 배치 되어있겠닝..(스스로에게 하는 말) 컴퓨터는 자릿수를 더 보존하는 쪽으로 형변환을 하려한다. 실수형은 자릿수가 더 많고 표현범위가 더 크기때문에, 정수형보다 더 높은 서열이라고 할 수 있다. 

 

형변환 원칙은 바이트 크기로 이해해서는 안된다. 형변환 원칙은 자릿수를 더 많이 보존하는 쪽으로 우선순위를 둔다. 즉, 실수형이 서열이 더 높다. 

 

형변환은 연산을 하거나 대입할 때, 피연산자들끼리 자료형이 다르면 일어난다. 형변환은 여러 예시를 함께 참조해야 이해가 훨씬 수월하다.

package lecture;

public class lecture04 {
	public static void main(String[] args) {
		double n = 90.3;
		int score =(int) n;	//명시적 형변환.
		
		System.out.println(score);
	}
}

ㅡ결과
90
(0.3이 짤렸다)

#대입 #명시적형변환 #성공적

위의 예시는 double형 변수 n을 int형 변수 score에 담으면서 형 변환을 해준 것이다. 대입될 변수의 자료형을 맞추지 않으면 에러가 발생한다. 대입 대상인 변수와 대입 결과인 값의 자료형이 맞아야 대입할 수 있다. 위의 코드에서도 8바이트 double형 변수인 n을 4바이트 int형 변수에 담아내는 과정에서 double형의 bit를 쳐냈고, 그 결과로 소수점 부분의 데이터가 탈락된 90이 출력되었다. 이처럼 서열 낮은 int에 서열 높은 double이 들어가려면 (int)로 서열을 낮춰주고, 이것을 눈에 보이도록 명시해놓았으므로 명시적 형변환이라고 한다.

 

package lecture;

public class lecture04 {
	public static void main(String[] args) {
		float f = 1234;
		System.out.println(f);
	}
}
--결과
1234.0

#대입 #자동형변환

1234는 정수형이고, float형 변수 f는 실수형 자료형이다. 타입이 다른데 왜 에러가 발생하지 않을까? 같은 4바이트라서? 아니다. 1234는 정수형이므로 디폴트인 int형이고, float형 실수형 변수 f가 서열이 더 높다. 즉, float가 더 표현범위가 크기때문에 int의 형변환이 내부적으로, 자동으로 이루어 진다.

좀 더 이해를 돕기 위해 추가하자면, 자동 형변환은 "자료형 확장"이라고 하기도 한다. 그렇다면 명시적 형변환은 "자료형 축소"를 위한 표시 같은 거라고 할 수 있겠다.

 

한편, 연산 과정에서도 형변환이 필요하다. 

package lecture;

public class lecture04 {
	public static void main(String[] args) {
		int num1 = 50;
		long num2 = 314567L;
		
		//int num3 = num1+ num2; --> 에러가 난다. 
		int num3 = num1+ (int)num2; // 에러가 안난다!

		System.out.println(num3);
	}
}

#연산 #명시적형변환

연산을 하기 위해서는 기본적으로 피연산자들의 데이터 타입을 한쪽으로 맞춰줘야 하는데, 연산이건 대입이건 '=' 기호를 기준으로 오른쪽에 위치하는 변수 혹은 값들은 기본적으로 정수형이면 int, 실수형이면 double이 디폴트 자료형으로 취급된다. 위의 코드에서 num1과 num2는 둘다 정수형이다. 그러나 연산 과정에서 두 변수는 연산 디폴트인 int로 잡힌다. num2가 만약 int보다 작거나(short라던가) 같다면 에러가 발생하지 않는다. 그러나 num2는 int보다 큰 long형 변수이기 때문에 형변환을 해주어야 에러가 발생하지 않는다. 

 

package lecture;

public class lecture04 {
	public static void main(String[] args) {
		int num1 = 50;
		long num2 = 314567L;

		long num3 = num1 + num2;
	
		System.out.println(num3);
	}
}

#연산 #자동형변환

이 코드에서는 long보다 int가 작으므로 명시적 형변환을 해주지 않아도 자동적으로 형변환이 일어나고 있음을 알 수 있다.


따라서, 다음을 주의하여 형변환을 해주면 된다.
1. 선언한 변수에 대입하려는 값이 정수형 인지 실수형인지 확인한다.
2. 피연산자들의 타입이 다르다면 맞춰줘야 한다. 또한 연산 결과가 어떻게 출력되길 원하는지 스스로 제대로 파악하고 있어야 한다. 
3. 더 큰 범위의 자료형이 무엇인지 우선순위를 명확하게 알고 있어야 한다. (형변환 원칙)

 

public class lecture04 {
           public static void main(String[] args) {
                       short num = 10;
                       num = (short)(num + 77L);	//77L = 롱. 연산은 롱으로 진행됨. 하지만 num이 쇼트니까 쇼트로 캐스팅.

                       int rate = 3;
                       rate = (int)(rate * 3.5);	//3.5가 실수형. 연산은 더블로 진행됨. 하지만 rate가 int형-->int로 캐스팅

                       System.out.println(num);
                       System.out.println(rate);

                       //위 아래는 똑같은 식이다. += 차이인데 밑의 코드가 더 깔끔해보인다

                       num = 10;
                       num += 77L;

                       rate = 3;
                       rate *= 3.5;

                       System.out.println(num);
                       System.out.println(rate);
           }
}

 이 코드에서 위쪽의 식은 기본 연산으로, 형변환을 해주어야 한다. 

반면 아래쪽의 식은 복합대입연산자를 쓰며 형변환을 해주지 않아도 에러가 발생하지 않았다. 내부적으로 컴파일러가 알아서 형변환을 진행한다. 그냥 연산자가 있으면 형변환 규칙 하에 형변환이 거의 필요하지만, 복합대입연산자를 쓸 때는 안해도 된다고 보면 되겠다.

 


 

전위 연산자 ++num은 찍힌 그 자리에서 바로 1이 증가하고(세미콜론이 나오기 전에 증가하고), 후위 연산자 num++는 기존 num이 먼저 출력된 이후에 세미콜론이 끝나고 1이 증가한다.

 


컴퓨터는 모든 데이터를 bit로 처리한다. 0과 1! 옛날에는 개발자가 비트 단위 연산을 이용해 메모리 공간 사용을 절약하거나 성능의 향상을 기대할 수 있었다(지금은 기술이 발달해서 하드웨어 성능이 엄청 좋아졌기때문에 이전보다는 비트연산을 하지는 않지만, 제한적이고 과거의 하드웨어 시스템을 가지고 있는 경우 비트단위의 연산을 사용한다.

비트 연산자, 비트 쉬프트 연산자가 있는데 하나하나 가만히 뜯어보면 재밌지만 다 보려고 하면 뭔가 토나올거같다.

 

728x90
반응형

'study_java > java_수강정리(~10.29)' 카테고리의 다른 글

[JAVA]7일차  (0) 2020.05.19
[JAVA]6일차  (0) 2020.05.19
[JAVA]5일차  (0) 2020.05.15
[JAVA]3일차  (0) 2020.05.13
[JAVA]1일차 + 2일차  (0) 2020.05.12