[Java] 이항 연산자

정보구니·2021년 12월 21일
0

Java

목록 보기
10/39
post-thumbnail

이항연산자


피연산자가 두개인 연산자를 가리켜 이항 연산자(binary operator)라 한다.

+= 같은 대입연산자가 이항연산자에 속할 수 있다.


자바에서 제공하는 모든 연산자는 다음과 같다.

연산의 진행 순서는 다음 두가지를 통해 결정된다.

  • 우선순위
  • 결합 방향

여기서 우선순위는 하나의 문장 안에 두개 이상의 연산자가 존재할 때 우선순위를 적용시켜 순서를 결정하고,

결합방향은 하나의 문장 안에 우선순위가 같은 연산자가 두개 이상 존재할 때 결합 방향을 적용시켜 연산의 순서를 결정한다.

정리하자면,
연산의 순서를 결정 짓는 첫번째 요소는 우선순위고, 두번째 요소는 결합방향이다.
( 우선순위가 같을 때 결합 방향을 따진다 )





대입 연산자와 산술 연산자


대입 연산자와 산술 연산자는 대표적인 이항 연산자이다.

int num1 = 7;
int num2 = 3;

System.out.println("num1 + num2 = " + (num1 + num2));  // 덧셈
System.out.println("num1 - num2 = " + (num1 - num2));  // 뺄셈
System.out.println("num1 * num2 = " + (num1 * num2));  // 곱셈
System.out.println("num1 / num2 = " + (num1 / num2));  // 몫
System.out.println("num1 % num2 = " + (num1 % num2));  // 나머지


// 출력 결과
num1 + num2 = 10
num1 - num2 = 4
num1 * num2 = 21
num1 / num2 = 2
num1 % num2 = 1

위 예제에서 확인할 수 있듯이 특정 연산을 소괄호로 묶어주면 연산자의 우선순위에 상관없이 해당 부분의 연산이 먼저 진행된다.


나눗셈 연산자 참고 사항

이때 나눗셈 연산자/는 피연산자의 자료형이 무엇인지에 따라
나눗셈이 진행되는 형태가 달라진다는 것을 알고 넘어가자 !

int num1 = 7;
int num2 = 3;

System.out.println("num1 / num2 = " + (num1 / num2));  // 정수형 나눗셈
System.out.println("num1 / num2 = " + (7.0 / 3.0));    // 실수형 나눗셈


// 출력 결과
num1 / num2 = 2
num1 / num2 = 2.3333333333333335





복합 대입 연산자


복합 대입 연산자는 대입 연산자가 다른 연산자와 묶여서 정의된 형태를 갖는다.

복합 대입 연산자의 종류는 다음과 같다.


short num = 10;
num = (short)(num + 77L);  // 형 변환 안하면 오류 발생
int rate = 3;
rate = (int)(rate * 3.5);  // 형 변환 안하면 오류 발생
		
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);


// 출력 결과
87
10
87
10

위 예제를 통해 대입연산자를 사용할 경우 형 변환이 필요없다는 것을 알 수 있다.

하지만 대입연산자로 문장을 구성하는 것은 추천하지 않는다고 한다.
단계적으로 명시적 형 변환을 시켜 코드의 의도를 명확히 하는 것이 좋은 코드 구성이라는 것을 기억하자 !





관계 연산자


관계 연산자의 연산 결과는 true또는 false 이다.

예제를 통해 확인해 보도록 하겠다.

System.out.println("3 >= 2 : " + (3 >= 2));
System.out.println("3 <= 2 : " + (3 <= 2));
System.out.println("7.0 == 7 : " + (7.0 == 7));
System.out.println("7.0 != 7 : " + (7.0 != 7));


// 출력 결과
3 >= 2 : true
3 <= 2 : false
7.0 == 7 : true
7.0 != 7 : false

여기서 == 연산을 위해 자동 형 변환이 일어난 뒤,
비교 연산이 진행 된다는 것을 짚고 넘어가자 !





논리 연산자


논리 연산자는 피연산자도 true/false의 형태이며, 연산 결과도 true/false의 형태를 갖는다.

논리 연산자의 연산 결과는 다음과 같다.
( 아래 표를 진리표라고 함 )

예제를 통해 확인해 보도록 하겠다.

int num1 = 11;
int num2 = 22;
boolean result;
		
result = (1 < num1) && (num1 <100);                   // 논리 AND
System.out.println("1 초과 100 미만인가? " + result);
		
result = ((num2 % 2) == 0) || ((num2 % 3) == 0);      // 논리 OR
System.out.println("2 또는 3의 배수인가? " + result);
		
result = !(num1 != 0);                                // 논리 NOT
System.out.println("0인가? " + result);


// 출력 결과
1 초과 100 미만인가? true
2 또는 3의 배수인가? true
0 인가? false



논리 연산자 사용시 주의할 점 (SCE)

  • SCE (Short-Circuit Evaluation)
    연산의 효율 및 속도를 높이기 위해 불필요한 연산을 생략하는 행위

연산의 특성 중 SCE는 불필요한 연산을 줄여주는 유용함이 있지만, 부작용이 발생할 수 있기때문에 주의해야 한다.

예제를 통해 확인해 보도록 하겠다.

int num1 = 0;
int num2 = 0;
boolean result;
		
result = ((num1 += 10) < 0) && ((num2 += 10) > 0);
System.out.println("result = " + result);
System.out.println("num1 = " + num1);
System.out.println("num2 = " + num2);
		
result = ((num1 += 10) > 0) || ((num2 += 10) > 0);
System.out.println("resutl = " + result);
System.out.println("num1 = " + num1);
System.out.println("num2 = " + num2);


// 출력 결과
result = false
num1 = 10
num2 = 0
resutl = true
num1 = 20
num2 = 0

num5num6 모두 10씩 증가한 결과를 보여야 하는데,
SCE로 인해 num6에 대한 연산이 생략된 것을 확인 할 수 있다.

따라서 문장을 구성할 때 하나의 문장에 너무 많은 연산을 포함하지 않는 것이 좋다.

다음과 같이 코드를 나누어 작성하는 것이 바람직하다.

num1 += 10;
num2 += 10;
result = (num1 < 0) && (num2 < 0);
result = (num1 > 0) || (num2 > 0);






참고
열혈 자바 chapter04

0개의 댓글