사칙 연산자, 산술변환
사칙 연산자 ( + - * /)
[예제 3-6]
public class Ex3_6 {
public static void main(String args[]){
int a = 10;
int b = 4;
System.out.printf("%d + %d = %d%n", a, b, a + b);
System.out.printf("%d - %d = %d%n", a, b, a - b);
System.out.printf("%d * %d = %d%n", a, b, a * b);
System.out.printf("%d / %d = %d%n", a, b, a / b);
System.out.printf("%d / %f = %f%n", a, (float)b, a / (float)b);
}
}
[실행 결과]
10 + 4 = 14
10 - 4 = 6
10 * 4 = 40
10 / 4 = 2
10 / 4.000000 = 2.500000
이 것만 조심하면 된다.
컴퓨터는 같은 타입끼리만 계산할 수 있다. 그리고 그 계산 결과는 해당타입으로 나온다.
원래 2.5인데 소수점 이하는 버려진다.
만약에 2.5를 얻고 싶다면, 어느 한쪽을 float로 만들어주면 된다.
그러면, 컴퓨터는 서로 다른타입을 계산하지 못하므로 integer와 float타입을 같은 타입으로 맞춰 주어야 하는데,
어느쪽으로 맞추냐면, 값손실이 적은 쪽으로 맞추기 위해 integer를 float로 바꾼다.
System.out.printf("%d / %f = %f%n", a, (float)b, a / (float)b);
// 결과값
// 10 / 4.000000 = 2.500000
이것처럼 한쪽만 float로 바꾸면 float가 나온다.
a를 바꿔도 되고 b를 바꿔도 되고, 아니면 둘다 바꿔도 되는데 귀찮으면 1개만 바꿔도 된다. 편한 쪽으로 바꾸자.
산술 변환
- 연산 전에 피연산자의 타입을 일치시키는 것
계산전에 피연산자 타입이 일치하지 않으면 타입을 일치시켜야 한다. 그다음 계산할 수 있다.
근데 매번 형변환 하기 귀찮아서 자동으로 형변환이 되기도 하는데 그러한 것을 "산술변환"이라고 한다.
산술변환에는 2가지 규칙이 있는데, 매우 중요하니 잘 외우도록 하자.
1. 두 피연산자의 타입을 같게 일치시킨다. (보다 큰 타입으로 일치)
long과 int사이는 long이 8byte, int는 4byte이므로 long으로 맞춘다.
float와 Int사이는 float가 4byte고, int도 4byte이지만, float의 범위가 더 넓으므로 float로 맞춘다.
double과 float사이는 double이 8byte고, float가 4byte이므로 double로 맞춘다.
2. 피연산자의 타입이 int보다 작은 타입이면 int로 변환된다.
integer보다 작은 타입은 byte, char, short 3가지가 있다.
이 타입들은 int로 변환된다.
byte랑 short랑 더한다고 가정해보자, byte는 1byte 고 short는 2byte여서 2byte인 short로 바뀌는게 아니라 4byte인 int로 바뀐다.
char랑 short를 더해도 둘다 2byte임에도 불구하고 4byte인 int로 바뀐다.
이렇게 하는 이유는,
byte는 범위가 -128~127,
char의 범위는 0~6만
short의 범위는 -3만~+3만
이므로 범위가 광징히 좁다고 말할 수 있다.
300*300만해도 9만이다. 이정도 작은 계산만해도 범위를 초과한다. 근데 범위를 벗어나면 오버플로우가 발생한다.
그러면, 바람직하지 않게 정확하지 않은 결과가 나올 수 있다.
그래서 일단 큰 타입의 int타입으로 바꿔놓고 계산을 한다.
그러면 오버플로우가 일어나서 정확하지 않은 계산결과가 나오는 일이 없을테니 말이다.
이렇게 두가지 규칙이 있고, 이 두가지 규칙은 반드시 꼭 외우자.
예를 들어서, 문자'2'에서 문자'0'을 빼면 char - char이 int-int로 바뀐다.
문자 '2'가 2로 바뀌면 어떻게 된다고 했는지 기억하는가?
유니코드 표에 따라 바뀐다고 했다.
유니코드에서 문자'2'가 코드 50이라서 int50으로 바뀌고, 문자'0'은 코드 48이므로 int48로 바뀐다.
그래서 결과가 50-48 즉, 2로 나온다.
그러니까, 문자'2'를 정수인 int2로 형변환을 해주면, '2'가 50으로 바뀌고 '0'(48)을 빼주는 것이다.
그래야 숫자 2를 얻을 수 있다.
[Ex3_9]
public class Ex3_9 {
public static void main(String args[]){
int a = 1_000_000; // 1,000,000 1백만 = 10의 6제곱
int b = 2_000_000; // 2,000,000 2백만 = 10의 6제곱
//10의 12제곱. int의 범위는 10의 9제곱. 그래서 오버플로우 발생
// long c = a * b; // a * b = 2,000,000,000,000 이 아니라 음수가 추력
// a나 b를 long으로 형변환 해주어야 함
long c = (long)a * b; // a * b = 2,000,000,000,000
System.out.println(c);
}
}
int a와 int b를 곱하면 int의 범위를 초과하여 오버플로우가 발생되고, 결과를 출력해보면 음수값이 나온다.
int a와 int b를 곱하면 대략 10의 12제곱인데, int범위는 10의 9제곱 이기 때문이다.
그래서 a나 b중 어느 한쪽을 (long) 형변환을 해줘야 한다.
그러면 컴파일에서 값손실을 최소화하는 방향으로 타입을 맞추어 둘다 long으로 맞추어 계산하기 때문에 long타입으로 결과가 나온다.
즉, 연산결과가 integer타입을 넘을 것 같으면 피연산자 중 하나를 (long)으로 형변환을 해주어야 한다.
'JAVA' 카테고리의 다른 글
비교 연산자, 문자열의 비교 (0) | 2022.03.16 |
---|---|
반올림 Math.round(), 나머지 연산자 (0) | 2022.03.16 |
형변환 연산자, 자동 형변환 (0) | 2022.03.15 |
증감 연산자, 부호 연산자 (0) | 2022.03.15 |
연산자의 우선순위와 결합규칙 (0) | 2022.03.14 |
댓글
이 글 공유하기
다른 글
-
비교 연산자, 문자열의 비교
비교 연산자, 문자열의 비교
2022.03.16 -
반올림 Math.round(), 나머지 연산자
반올림 Math.round(), 나머지 연산자
2022.03.16 -
형변환 연산자, 자동 형변환
형변환 연산자, 자동 형변환
2022.03.15 -
증감 연산자, 부호 연산자
증감 연산자, 부호 연산자
2022.03.15