3.4 이항 연산자
이항 연산자는 피연산자가 두 개인 연산자를 말하며 여기에는 산술 연산자( +,-,*,/,%)
문자열 연결 연산자(+), 대입연산자(=, +=, -=, *=, /=, %=, &=, ^=, |=, <<=, >>=,>>>=)
비교연산자(<, <=, >, >=, ==, !=), 논리 연산자(&&, ||, &, |, ^, !)
비트 논리연산자(&, |, ^), 비트이동연산자( <<, >>, >>>)등이 있다.
모르는 연산자들은 읽어보고 예시로 한번 확인..
3.4.1 산술 연산자( +,-,*,/,%)
사칙연산 + % 포함한 산술 연산자는 총 5개 이 산술 연산자는 boolean 타입을 제외한 모든 기본 타입에 사용가능
연산식 | 설명 | ||
피연산자 | + | 피연산자 | 덧셈연산 |
피연산자 | - | 피연산자 | 뺄셈연산 |
피연산자 | * | 피연산자 | 곱셈 연산 |
피연산자 | / | 피연산자 | 좌측 피연산자를 우측 피연산자로 나눗셈 연산 |
피연산자 | % | 피연산자 | 좌측 피연산자를 우측 피연산자로 나눈 나머지를 구하는 연산 |
ex) int result = num % 3; 에서 result값은 0,1,2, 중의 한 값
1.피연산자들 모두 정수타입, int(4byte) 보다 작으면 int 타입으로 변환후 연산 수행 결과값 int
ex) byte + byte -> int + int = int
2.피연산자들 모두 정수타입, long 타입 있을경우 long 타입으로 변환후 연산수행 결과값 long
ex) int + long -> long + long =long
3.피연산자 중 실수 타입 존재, 크기가 큰 실수 타입으로 변환후 연산수행 결과값 실수타입
ex) int + double -> double +double = double
정리하면 long제외한 정수타입 연산은 int타입으로 산출,
피연산자 중 하나라도 실수 타입이면 실수 타입으로 산출
예시
int int1 =10;
int int2 =4;
int result2 = int 1/ int 2'; // 2
double result3 = int 1 / int 2; // 2.0나옴
결과값을 2.5를 나오게 하고 싶으면 피연산자중 최소한 하나는 실수 타입이어야함
double result3 = (int1*1.0) / int2; //2.5
double result3 = (double) int1 / int2; //2.5
double result3 = int1 / (double) int2 ; //2.5
산술 연산자 예시
결과값
har 타입도 정수 타입이므로 산술 연산이 가능
주의할 점은 char타입이 산술 연산이 될 경우 int 타입으로 변환되므로
산출 타입은 int타입이다.
예제 확인
결과값
'A'+1은 리터럴 문자 'A'에 1을 더한 것인데, 문자 A는 65라는 유니코드를 가지므로 'A' +1은 66이 된다.
따라서 66인 유니코드는 문자 B이므로 c1에는 문자 B가 저장된다
자바는 리터럴 간으 ㅣ연산은 타입 변환 없이 해당 타입으로 계산하기 때문
그러나 변수c2에 1을 더하면 c2는 int타입으로 변환되고 1과 연산하기 때문에
산출 타입은 int 타입이 된다. 따라서 char 타입 변수 c3에 대입이 안되어 컴파일 에러발생
강제 타입변환을 해줘야함 char c3 =(char) (c2 +1);
오버플로우 탐지
산술 연산을 할 떄 주의할 점은 연산 후의 산출값이 산출 타입으로 충분히 표현 가능한지 봐야함
산출 타입으로 표현할 수 없는 값이 산출되었을경우, 오버플로우가 발생하고
(쓰레기값(엉뚱한값)을 얻으수 있기 떄문이다. 예시를 통해 확인
예시
결과값
변수 x,y는 int 타입이고, x*y도 int타입이므로 연산의 산출 타입은 int 타입이다.
위 코드는 컴파일 에러는 발생하지 않지만 변수 z에는 올바른 값이 저장되지 않는다.
그이유는 10^6 * 10^6 = 10^12가 되어 int 타입에 저장되는 값의 범위를 초과해버렸다.
그래서 쓰레기값인 -727379968 이 나옴
올바른 값을 얻기 위해서는 변수 x,y중 최소 하나라도 long 타입이 되어야하고 변수 z가 long 타입이어야한다.
오버플로우 해결
결과값이 10000000000 나옵니다.
이런 경우 산술 연산자 사용하지 말고 메소드를 이용하는 것이 좋다고 한다.
메소드는 산술 연산을 하기전에 피연산자들의 값을 조사해서
오버플로우를 탐지할 수 있기 때문이다.
지금은 그냥 이런것도 있구나~ 하고 넘어가자 안배운거라..
산술 연산 전에 오버플로우를 탐지
결과값
사실 정확히는 잘 모르겠습니다.
다만 safeAdd 메소드를 이용하여 int left, int right 에따라서
오버플로우를 감지하냐 안하냐 뭐 이런 것 인거 같습니다.
책의 설명을 보면 그냥 그런가보다...라는 생각뿐이라서 나중에 뒤에서 다시 알려준다고하니...
정확하게 계산할 때에는 부동소수점 타입을 사용하지 않는다 예시
결과값
result 변수의 값은 0.2999~~3이 되어 정확히 0.3이 되지 않는다.
이것을 이진 포맷의 가수를 사용하는 부동소수점 타입(float,double)은 0.1을 정확히
표현 할수 없어 근차시로 처리하기 때문이다.
정확한 계산이 필요하다면 정수 연산으로 변경해서 다음 예시와 같이 해야됨
결과값
NAN과 Infinity 연산
/ or % 연산자를 사용 할때 주의할 점이 있다.
좌측 피연산자가 정수 타입인 경우 나누는수인 우측 피연산자를 0을 사용할 수 없다.
만일 0으로 나누면 컴파일은 정상적으로 되지만
실행시 ArithmeticException(예외)이 발생한다
결과값
자바는 프로그램 실행 도중 예외가 발생하면 실행이 즉시 멈추고 프로그램은 종료된다.
ArithmeticException이 발생했을 경우 프로그램이 종료되지 않도록 하려면 예외처리해야됨
예외처리는 예외가 발생되었을 경우,catch 블록을 실행하도록.. 10장에서 학습하니 그냥 보기만하자
그러나 실수 타입인 0.0 or 0.0f 로 나누면 ArithmeticException 발생 않고
/ 연산의 결과는 Infinity(무한대) , % 연산의결과는 NaN( Not a Number)
5 / 0.0 -> Infinity(무한대)
5 % 0.0 -> NaN( Not a Number)
주의할 점은 / 와 % 연산의 결과가 Infinity or NaN이 나오면 다음 연산을 수행해서는 안된다.
왜냐하면 이 값과 산술 연산을 하면 어떤 수와 연산하더라고 Infinity 와 NaN 산출되어 데이터가 이상해짐
/ 와 % 연산의 결과가 Infinity or NaN인지 확인하려면
Double.isInfinite() 와 Double.isNaN() 메소드를 이용하면 된다고 한다
이 메소드들은 double타입의 값을 매개값으로 받아서
값이 Infinity or NaN 이라면 true를 return, 그렇지 않으면 false를 return
뒤에서 배우겠죠? 이런게 있구나 하고 넘어갑시다
Infinity 와 NaN 예시
결과값
입력값의 NaN 검사
부동소수점(실수)을 입력받을 떄는 반드시 NaN검사해야된다..
여기는 예시와 결과값만 보겠다.. 이해가 잘안되서 나중에 다시보면...?
"NaN" 문자열의 문제점 예시
결과값 NaN 나옴
"NaN"을 체크하고 연산 수행 예시
결과값
지금은 잘 몰라도 배우다보면 이해가지 않을까...
'adavaj P(출처 이것이 자바다) > 연산자' 카테고리의 다른 글
chapter03 연산자 확인문제 (0) | 2021.09.07 |
---|---|
chapter03 연산자04 (0) | 2021.09.04 |
chapter03 연산자01 (0) | 2021.09.04 |