- 정수와 실수는 컴퓨터 내부에서 표현하는 방식이 전혀 다릅니다.
- 따라서 정수와 실수를 더한다고 할 때 그대로 연산을 수행할 수 없습니다.
- 하나의 자료형으로 통일한 후 연산을 처리해줘야 합니다.
- 이럴 때 자료 형변환(Type Conversion)을 해줘야 합니다.
- 이번 강좌에서는 자료 형변환에 대해서 배워보도록 하겠습니다.
- 형변환은 묵시적 형변환과 명시적 형변환으로 나뉘기 때문에 따로 보도록 하겠습니다.
1. 묵시적 형변환(자동 형변환)
- 묵시적 형변환으로 자료형이 알아서 자동으로 변환되는 것을 말합니다.
- 묵시적 형변환이 일어나는 기본 원칙이 2가지가 있습니다.
- 바이트 크기가 작은 자료형에서 큰 자료형으로 형 변환은 자동으로 일어남
- 덜 정밀한 자료형에서 더 정밀한 자료형으로 형변환은 자동으로 일어남
- 우선적으로 자료형의 묵시적 형변환 관계를 보겠습니다.
- 자동으로는 위의 그림의 화살표 방향으로 처리가 됩니다.
- 화살표 반대방향으로 처리가 되려면 강제적으로 형변환, 즉 명시적 형변환이 일어나야 합니다.
- 그래서 간단하게 자동으로 형변환이 일어나는 경우를 정리해 보겠습니다.
- 정수(byte, short, int, long)를 실수(float, double)로 변환하는 경우
- 문자(char)를 정수(int, long)으로 변환하는 경우
- 바이트가 작은 자료형을 보다 큰 자료형으로 변하는 경우
- 이제 예제를 실습해 보겠습니다.
- 패키지(ch09_type_conversion)과 클래스(Ex01_AutoTypeCoversion.java)를 추가해 주세요.
- 기초적 작업을 모르는 분은 아래 주소를 클릭하고 보고 오세요.
https://ossam5.tistory.com/613
## 자동 형변환 실습1 - Ex01_AutoTypeCoversion.java
package ch09_type_conversion;
public class Ex01_AutoTypeCoversion {
public static void main(String[] args) {
//묵시적(자동) 형변환
//1. 정수 => 실수
double num1 = 1;
System.out.println(num1);
//2. 작은 바이트 => 큰 바이트
long num2 = 2;
System.out.println(num2);
//3. 문자(char) => 정수(int)
char ch = 'a';
int num3 = ch;
System.out.println(num3);
}
}
- num1의 경우를 보면, 리터럴 1은 타입이 int이고, num1은 타입이 double입니다.
- 리터럴 1을 num1에 저장하기 위해서 int를 double로 자동형 변환해서 저장한 것입니다.
- num2의 경우를 보면, 리터럴 2는 타입이 int이고, num2는 타입이 long입니다.
- 자동형 변환에 의해 int값 2를 long에 저장한 것입니다.
- 문자인 ch를 int인 num3에 값으로 대입했습니다.
- 2byte를 4byte인 int로 바꾸는 것으로 변경이 가능합니다.
## 자동 형변환 결과1 - Ex01_AutoTypeCoversion.java
- 첫 번째 값은 리터럴 1이 1.0으로 변환된 것이 보입니다.
- 두 번째 값은 2로 잘 반환되었습니다.
- 세 번째 값은 문자였던 a가 아스키코드값인 97로 정수로 바뀐 것을 확인할 수 있습니다.
2. 명시적 형변환(강제 형변환)
- 명시적 형변환은 묵시적 형변환과 반대입니다.
- 자동으로 변할 수 없기 때문에 강제적으로 형변환을 시켜줘야 합니다.
- 강제로 변환하는 경우를 보겠습니다.
- 바이트 크기가 큰 자료형에서 작은 자료형으로 대입하는 경우
- 더 정밀한 자료형에서 덜 정밀한 자료형으로 대입하는 경우
1) 명시적 형변환 문법
자료형 변수명 = (자료형)값;
- 변수 선언 시 값을 대입할 때 앞에 괄호를 쓰고 자료형을 써주면 됩니다.
2) 강제 형변환 실습
- 다시 간단하게 강제로 형변환이 일어나는 경우를 정리해 보겠습니다.
- 실수(float,double)을 정수(byte, short, int, long)으로 변환하는 경우
- 현재 자료형의 바이트보다 작은 바이트를 가진 자료형으로 변환하는 경우
- 자동 자료형 변환이 일어나지만 필요에 의한 경우 : 나누기
## 강제 형변환 실습1 - Ex02_ForcedTypeConversion.java
package ch09_type_conversion;
public class Ex02_ForcedTypeConversion {
public static void main(String[] args) {
//명시적(강제) 형변환
//1. 실수 => 정수
int num1 = (int)3.14;
System.out.println(num1);
//2. 큰 바이트 => 작은 바이트
byte num2 = (byte)num1;
byte num3 = 3;
System.out.println(num2);
//3. 에러가 아닌 필요에 의해서 형변환하는 경우(나누기)
System.out.println(1/2);
System.out.println((double)1/2);
}
}
- num1은 정수를 선언하고 리터럴을 실수를 담았습니다.
- 형변환을 하지 않으면 에러가 발생되므로 정수가 되라고 해야 합니다.
- 물론 3.14가 아닌 3으로 정수로 바뀌어서 반환됩니다.
- num2는 byte타입인데 더 큰 바이트인 int타입의 num1을 담았습니다.
- 그렇기 때문에 강제형변환을 해줘야 합니다.
- num3인 경우로 그냥 숫자인 3을 담을 때는 byte범위이기 때문에 에러가 나지 않습니다.
- 에러는 아니지만 1/2로 나누면 원래 0.5가 나와야 하지만, 나눠지는 숫자가 둘 다 int여서 결과값이 int인 정수로 0이 나옵니다.
- 그래서 1과 2 둘 중에 하나라도 실수인 double이어야 실수를 반환할 수 있습니다.
## 강제 형변환 결과1 - Ex02_ForcedTypeConversion.java
- 첫 번째 값은 3.14인 실수가 int인 정수로 3으로 반환되는 것을 볼 수 있습니다.
- 두 번째 값은 byte가 int값을 원래는 못 가져오는데 형변환을 통해 가져올 수 있는 것을 확인할 수 있습니다.
- 세 번째 값은 1/2를 나눴는데 두 수치가 모두 정수여서 정수인 0으로 반환되는 것을 볼 수 있습니다.
- 네 번째 값은 1을 실수로 처리했기 때문에 실제로 1.0/2가 돼서 결과적으로 0.5인 실수로 반환되는 것을 확인할 수 있습니다.
3. 오버플로우와 언더플로우
- 정수 같은 경우는 자료형 타입에 따라 숫자의 범위가 있었습니다.
- 정수형의 범위를 다시 한번 정리해 보도록 하겠습니다.
자료형 | 바이트 크기 | 수의 범위 |
byte | 1 | -(2^7) ~ (2^7) -1 (-128~127) |
short | 2 | -(2^15) ~ (2^15) -1 (-32,768~32,767) |
int | 4 | -(2^31) ~ (2^31) -1 (-2,147,483,648~2,147,483,647) |
long | 8 | -(2^63) ~ (2^63) -1 (-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807) |
- 위에 보이는 표와 같은 수의 범위를 가집니다.
- 그럼 byte로 보자면 127이 최고 수치입니다. 여기서 1을 더하면 어떻게 될까요?
- 128로 증가할 수 없겠죠? 그래서 -128로 내려가 버립니다.
- 이럴 때 발생하는 것을 오버플로우라고 합니다.
1) 오버플로우(Overflow)
- 정수 변수가 표현할 수 있는 정수의 범위를 넘어서 의도했던 값과 다르게 나오는 현상입니다.
- 양수에서 음수로 바뀌는 것을 말합니다.
- 위에서도 설명했듯이 127 => -128이 되는 것을 의미합니다.
## 오버플로우 실습1 - Ex03_Overflow.java
package ch09_type_conversion;
public class Ex03_Overflow {
public static void main(String[] args) {
//Overflow
byte num1 = 127;
//byte num2 = num1 + 1; //형변환안하면 에러
byte num2 = (byte)(num1 + 1);
System.out.println(num2);
}
}
- byte의 범위는 -128~127입니다.
- num1에는 가장 높은 숫자인 127을 대입했습니다.
- num2에는 num1 + 1을 대입하면 에러가 발생합니다. 128로 올라갈 수 없기 때문입니다.
- 그래서 이때 (byte)를 통해서 형변환을 해줘야 합니다.
- 그럼 127 + 1이 어떻게 형변환되는지 결과를 확인해 봅니다.
## 오버플로우 결과1 - Ex03_Overflow.java
- 128이 될 순 없어서 범위에 오버플로우가 되면서 -128로 처리가 됩니다.
- 이렇게 양수에서 음수가 되는 것을 오버플로우라고 합니다.
2) 언더플로우(Underflow)
- 언더 플로우는 오버플로우와 반대개념이라고 보면 됩니다.
- 음에서 양으로 바뀌는 것입니다.
## 언더플로우 실습1 - Ex04_Underflow.java
package ch09_type_conversion;
public class Ex04_Underflow {
public static void main(String[] args) {
//Underflow
byte num1 = -128;
//byte num2 = num1 - 1; //형변환안하면 에러
byte num2 = (byte)(num1 - 1);
System.out.println(num2);
}
}
- byte의 범위는 -128~127입니다.
- num1에는 가장 낮은 숫자인 -128을 대입했습니다.
- num2에는 num1 - 1을 대입하면 에러가 발생합니다. -129로 내려갈 수 없기 때문입니다.
- 그래서 이때 (byte)를 통해서 형변환을 해줘야 합니다.
- 그럼 -128 - 1이 어떻게 형변환되는지 결과를 확인해 봅니다.
## 언더플로우 결과1 - Ex04_Underflow.java
- -129이 될 순 없어서 범위에 언더플로우가 되면서 127로 처리가 됩니다.
- 이렇게 음수에서 양수가 되는 것을 언더플로우라고 합니다.
'컴퓨터언어 > JAVA(자바)' 카테고리의 다른 글
[JAVA강좌] 11강 복합대입연산자와 증감연산자 (0) | 2024.01.10 |
---|---|
[JAVA강좌] 10강 연산자 개념과 산술연산자 (0) | 2024.01.05 |
[JAVA강좌] 8강 상수와 리터럴 (0) | 2024.01.04 |
[JAVA강좌] 7강 자료형 없이 선언 - var - 자바10부터 생긴 문법 (0) | 2024.01.02 |
[JAVA강좌] 6강 참조형변수 - String(문자열) (0) | 2023.12.28 |