[JAVA] 3장 연산자

SUbbb·2021년 9월 17일
0

Java 정리

목록 보기
3/4
post-thumbnail

"Do it! 자바 완전 정복" 책을 바탕으로 intellij와 함께 하는 JAVA 공부

1. 연산자의 종류

  1. 연산 결과가 특정 값이 나오는 산술, 증감, 비트, 시프트 연산자
  2. 연산 결과가 참(true)과 거짓(false) 중 하나의 값으로만 나타나는 비교, 논리 연산자
  3. 값을 반환하는 것이 아닌 값을 대입하는 의미를 지니고 있는 대입 연산자, 삼항 연산자

2. 연산자의 연산 방법

1. 산술 연산자와 증감 연산자

산술 연산자

가장 기본적인 연산자로, 사칙연산과 나머지 연산이 존재

'정수/정수' 형태

int/int = int이므로 5/2의 값은 2.5가 아니라 2이다.
즉, '정수/정수'의 결과는 나눗셈의 몫

나머지 연산(%)

말 그래도 나누기를 수행한 이후의 나머지
= 모듈로(modulo) 연산

증감 연산자(++, --)

변숫값을 1씩 증가 또는 감소시키는 연산자
실행의 우선순위에 따라 전위형후위형이 존재

전위형

다른 모든 명령보다 먼저 실행

후위형

가장 나중에 실행

int a1 = 3;
int b1 = ++a1;          // a1 값에 1을 더하기(전위형) -> a1 값을 b1에 대입

System.out.println(a1); // 4
System.out.println(b1); // 4

int a2 = 3;             
int b2 = a2++;          // a2 값을 b2값에 대입 -> a2 값에 1을 더하기(후위형)

System.out.println(a2); // 4
System.out.println(b2); // 3

2. 비트 연산자

말 그대로 비트 단위의 연산자로, AND(&), OR(|), XOR(^), NOT(~)가 존재

비트 AND, 비트 OR, 비트 XOR의 연산 과정 살펴보기

비트 단위의 연산을 직접 계산하기 위해서는 10진수를 비트 단위의 표현 방식인 2진수로 바꿔 표기할 수 있어야 함

자바 코드상에서 10진수를 2진수, 8진수, 16진수로 변환하는 메서드

  • Integer.toBinaryString()
  • Integer.toOctalString()
  • Integer.toHexString()

이를 다시 10진수로 변환하는 메서드

  • Integer.parseInt()

가 존재

비트 연산을 할 때 사용되는 비트 수
실제 비트 연산을 수행할 때의 최소 단위는 int(4byte = 32bit)

비트 NOT 연산 과정 살펴보기

양숫값과 음숫값을 읽는 방법

  1. 값의 첫 번째 비트부호 비트(0: 양수, 1: 음수)로, 숫자의 부호를 결정
  2. 양수는 1을 기준으로 값을 읽고, 음수는 0을 기준으로 값을 읽은 후에 1을 더한 값이 음수의 절댓값

NOT 연산자

0과 1을 반전시키는 연산으로, 부호 비트까지 반전시키므로 수행 시 항상 부호가 바뀌게 됨

음수 값을 읽을 때 0을 기준으로 읽은 후 왜 1을 더할까 ?

1을 더하지 않으면 음수에서 양수로 넘어가는 과정에서 10진수 0을 나타내는 표현이 2개 존재하게 됨

3. 시프트 연산자

비트의 위치를 좌우로 이동하는 연산으로, 산술 시프트(>>, <<)논리 시프트(>>>)가 존재

산술 시프트

숫자의 부호 비트는 유지하면서 나머지 비트를 왼쪽(<<) 또는 오른쪽(>>)으로 이동하는 연산자

<< 연산

부호 비트를 제외한 나머지 전체 비트가 왼쪽으로 이동하므로, 1bit 이동할 때마다 *2의 효과

>> 연산

부호 비트를 제외한 나머지 전체 비트가 오른쪽으로 이동하므로, 1bit 이동할 때마다 /2의 효과

빈칸

<< 연산일 때, 빈칸이 오른쪽에 생기며 0으로 빈칸을 채움
>> 연산일때, 빈칸은 왼쪽 부호 비트 다음에 생기며 부호 비트값과 동일한 값으로 채우기에 삭제되는 비트로 인해 값을 2로 나눈 결과와 다르게 나타날 수 있음

양수와 음수의 산술 시프트 연산 결과를 쉽게 계산하는 방법

논리 시프트

Logical right shift는 부호 비트를 포함해 전체 비트를 오른쪽으로 이동시키는 연산으로 빈칸은 모두 0으로 채움
부호 비트까지 이동시키므로 부호 비트가 1인 음수일 때 논리 시프트 이후에는 값이 양수로 변할 것

'3번째 비트는 사운드 ON/OFF 여부', '4번째 비트는 자동 완성 ON/OFF'와 같이 각 비트 위치에서의 값만이 의미가 있을 때 주로 사용하는 연산

  • 숫자의 크기나 부호는 의미가 없음
int flags = 0b10110110;
        
System.out.println(flags >>> 0 & 1);    // 0: 0번쨰 비트값
System.out.println(flags >>> 1 & 1);    // 1: 1번째 비트값
// ...
System.out.println(flags >>> 6 & 1);    // 6: 6번째 비트값
System.out.println(flags >>> 7 & 1);    // 7: 7번째 비트값

4. 비교 연산자

크기 비교(>, <, >=, <=)와 등가 비교(==, !=) 존재
연산 결과는 boolean

등가 비교(==)와 대입 연산자(=)를 혼동하지 말자
등가 비교 연산자(==)는 두 값이 동일한지 여부를 확인한 후 동일 여부를 boolean으로 반환
대입 연산자(=)는 오른쪽의 값을 왼쪽에 대입하는 연산자

등가 비교할 때 비교 대상 = "스택 메모리의 값"

이것이 중요한 이유는 스택 메모리의 값이 기본 자료형일 때와 참조 자료형일 때가 서로 다르기 때문
(2장 자료형 참고)

기본 자료형의 실제 데이터값스택 메모리에, 참조 자료형의 실제 데이터값힙 메모리에 저장되고, 스택 메모리에는 실제 데이터값의 위치(번지)가 저장

등가 비교 대상
기본 자료형 - 실제 데이터의 값
참조 자료형 - 실제 데이터값이 위치한 번짓값

String str1 = new String("안녕");
String str2 = new String("안녕");

System.out.println(str1 == str2);           //false
  • 실제 데이터 값은 동일하지만 번짓값이 다름
  • 참조 자료형이기에 실제 데이터값이 위치한 번짓값을 확인하여 false 출력

5. 논리 연산자

비트 연산자와 매우 비슷하지만, 피연산자로 boolean 값만 올 수 있고, 연산 결과 또한 boolean

비트 XOR과 논리 XOR 모두 기호 ^를 사용하며, 각각의 동작은 좌우에 위치한 피연산자의 자료형에 따라 결정됨

쇼트 서킷 (short circuit)

논리 연산은 비트 연산자로도 수행할 수 있다.
비트 연산자의 양쪽 피연산자의 자리에 boolean 값이 위치하면 비트 연산이 아닌 논리 연산을 수행

쇼트 서킷의 적용 여부 차이

쇼트 서킷: 연산을 수행하는 과정에서 결과가 이미 확정됐을 때 나머지 연산 과정을 생략하는 것
(5 > 3) || (3 < 2) 에서 왼쪽의 (5 > 3) 이 true이므로 항상 결과는 true일 것이기에 오른쪽 항은 읽지도 않는 것이 쇼트 서킷

논리 연산자로 논리 연산을 수행할 때는 쇼트 서킷이 적용되지만, 비트 연산자로 논리 연산을 수행하면 쇼트 서킷이 적용되지 않는다.

쇼트 서킷은 단순히 불필요한 계산 과정을 생략하는 것이므로 결과에 영향은 없다.

좋아보일 수는 있지만, 쇼트 서킷을 의도적으로 적용하지 않아야 하는 경우도 존재

int a = 3, b = 3, c = 3;

System.out.println(false && a++ > 6);   // false
System.out.println(true || b++ > 6);    // true
System.out.println(true ^ c++ > 6);     // true
System.out.printf("%d %d %d", a, b, c); // 3 3 4

위 경우, 비트 연산의 각 오른쪽 피연산자에 증감 연산자가 포함돼 있다.
논리 연산자일 때, 쇼트 서킷이 적용되면 각 변수의 증감 연산은 수행되지 않는다.
반면 비트 연산자일 때, 쇼트 서킷이 적용되지 않기에 각 변수의 증감 연산은 수행된다.

논리 XOR으로 연산 결과를 계산하기 위해서는 항상 양쪽 값을 모두 확인해야 하므로 쇼트 서킷을 구조적으로 적용할 수 없다.
이것이 논리 XOR 연산과 비트 XOR 연산의 연산 기호(^)가 동일한 이유

6. 대입 연산자

오른쪽 피연산자의 연산 결과를 왼쪽 변수에 대입하는 연산자

7. 삼항 연산자

자바 연산자 중 유일하게 3개의 피연산자가 있는 연산자

(true 또는 false) ? true일 때 연산 결과 : false일 때 연산 결과

물음표(?) 앞에는 boolean 자료형인 true 또는 false만 올 수 있지만 연산 결과가 boolean 자료형인 논리 연산자와 비교 연산자가 위치

profile
배우고 정리하고 공유하기

0개의 댓글