-
이항 연산자는 두 피연산자의 타입이 일치해야 연산이 가능하므로, 피연선자의 타입이 서로다르다면 연산 전에 형변환 연산자로 타입을 일치시켜야한다.
이처럼 연산 전에 피연산자 타입의 일치를 위해 자동 형변환되는 것을 '산술 변환' 또는 '일반 산술 변환'이라하며, 이 변환은 이항 연산에서만 아니라 단항 연산에서도 일어난다.
'산술 변환'의 규칙은 다음과 같다.
1. 두 피연산자의 타입을 같게 일치시킨다. (보다 큰 타입으로 일치) - 피연산자의 값손실을 최소화하기 위한 것
long + int ---> long + long ---> long
float + int ---> float + float ---> float
double + float ---> double + double ---> double
2. 피연산자의 타입이 int보다 작은 타입이면 int로 변환된다.
- char, short의 표현범위가 좁아서 연산중에 오버플로우(overflow)가 발생할 가능성이 높기 때문
byte + short ---> int + int ---> int
char + short ---> int + int ---> int
연산결과의 타입은 피연산자의 타입과 일치한다. 예를들어 int와 int의 나눗셈 연산결과는 int이다.
int / int --> int
5 / 2 --> 2
그래서 5 / 2의 결과가 2.5가 아닌 2이다. 위의 식에서 2.5라는 실수를 결과로 얻으려면, 피연산자 중 어느 한 쪽을 float와 같은 실수형으로 형변환해야 한다. 그러면, 다른 한 쪽은 일반 산술 변환의 첫 번째 규칙에 의해 자동적으로 형변환되어 두 피연산자 모두 실수형이 되고, 연산 결과 역시 실수형의 값을 얻을 수 있다.
int / (float) int --> int / float --> float / float --> float
5 / (float) 2 --> 5 / 2.0f --> 5.0f / 2.0f --> 2.5f
아래의 코드를 보면 컴파일 에러가 발생한다. 명시적으로 형변환이 필요하다. --> a와 b는 모두 int형보다 작은 byte 형이기 때문에 연산자 '+'는 이 두개의 피연산자들의 자료형을 int형으로 변환한 다음 연산(덧셈)을 수행한다.
그래서 'a + b'의 연산결과는 byte 형이 아닌 int형(4byte)인 것이다. 4byte의 값을 1byte의 변수에 형변환없이 저장하려고 했기 때문에 에러가 발생하는 것이다.크기가 작은 자료형의 변수를 큰 자료형의 변수에 저장할 때는 자동으로 형변환(type conversion, casting)되지만, 반대로 큰 자료형의 값을 작은 자료형의 변수에 저장하려면 명시적으로 형변환 연산자를 사용해서 변환해주어야 한다.
10 * 30의 결과는 300이지만, 형변환(캐스팅, casting)에서 배운 것처럼 큰 자료형에서 작은 자료형으로 변환하면 데이터의 손실이 발생하므로 값이 바뀔 수 있다. 300은 byte형의 범위를 넘기 때문에 byte형으로 변환하면 데이터 손실이 발생하여 결국 44가 byte형변수에 c에 저장된다.
위의 식 'a * b'의 결과 값을 담는 변수 c의 자료형이 long타입(8byte)이기 때문에 2x10^12 을 저장하기에 충분하므로 '2000000000000'이 출력될 것 같지만, 결과는 전혀 다른 값이 출력된다.
그 이유는 int타입과 int타입의 연산결과는 int 타입이기 때문이다.
'a * b'의 결과가 이미 int 타입의 값(-1454759936)이므로 long 형으로 자동 형변환되어도 값은 변하지 않는다.
long c = a * b;
--> long c = 1000000 * 2000000;
--> long c = -1454759936;
올바른 결과를 얻으려면 아래와 같이 변수 a 또는 b의 타입을 'long'으로 형변환해야 한다.
long c = (long) a * b;
--> long c = (long) 1000000 * 2000000;
--> long c = 1000000L * 2000000;
--> long c = 1000000L * 2000000L;
--> long c = 2000000000000L;
int int int
1000000 * 1000000 ---> -727379968 overflow 발생
int int long long long
1000000 * 1000000L ---> 1000000L * 1000000L ---> 1000000000000L
[참고 도서 Java의 정석_기초편] http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&mallGb=KOR&barcode=9788994492049&orderClick=LEa&Kc=