3.1 부호/증감 연산자
부호 연산자는 변수의 부호를 유지하거나 변경한다.
연산자 | 설명 | |
+ | 피연산자 | 피연산자의 부호 유지 |
- | 피연산자 | 피연산자의 부호 변경 |
주의할 점은 부호 변경 후의 타입이다. 범위에 맞지 않는 타입의 변수에 연산자로 인한 변경될 값을 대입하게 된다면 컴파일 에러가 발생한다. 이때 정수 타입(byte, short, int) 연산의 결과는 int 타입이다. 부호를 변경하는 것도 연산이므로 부호 변경 연산 결과는 int 타입 변수에 대입해야 한다.
증감 연산자(++, --)는 변수의 값을 1 증가시키거나 1 감소시키는 연산자이다.
연산식 | 설명 | |
++ | 피연산자 | 피연산자의 값을 1 증가시킴 |
-- | 피연산자 | 피연산자의 값을 1 감소시킴 |
피연산자 | ++ | 다른 연산을 수행한 후에 피연산자의 값을 1 증가시킴 |
피연산자 | -- | 다른 연산을 수행한 후에 피연산자의 값을 1 감소시킴 |
변수 단독으로 증감 연산자가 사용될 경우 변수 어디에 붙어도 결과는 동일하다.
// 모두 i = i + 1;로 통일
++i;
i++;
// 모두 i = i - 1;로 통일
--i;
i--;
하지만 여러 개의 연산자가 포함되어 있는 연산식에서는 증감 연산자의 위치에 따라 결과가 달라진다.
int x = 1;
int y = 1;
int result1 = ++x + 10; // x를 1 증가 → int result1 = 2 + 10;
int result2 = y++ + 10; // int result2 = 1 + 10; → y를 1 증가
// result1에는 12 저장됨
// result2에는 11 저장됨
3.2 산술 연산자
연산자 | 설명 | ||
피연산자 | + | 피연산자 | 덧셈 연산 |
피연산자 | - | 피연산자 | 뺄셈 연산 |
피연산자 | * | 피연산자 | 곱셈 연산 |
피연산자 | / | 피연산자 | 나눗셈 연산 |
피연산자 | % | 피연산자 | 나눗셈의 나머지를 산출하는 연산 |
산술 연산의 특징
- 피연산자가 정수 타입(byte, short, char, int)이면 연산의 결과는 int 타입이다.
- 피연산자가 정수 타입이고 그 중 하나가 long 타입이면 연산의 결과는 long 타입이다.
- 피연산자 중 하나가 실수 타입이면 연산의 결과는 실수 타입이다.
3.3 오버플로우와 언더플로우
오버플로우(overflow): 타입이 허용하는 최대값을 벗어나는 것
언더플로우(underflow): 타입이 허용하는 최소값을 벗어나는 것
정수 타입 연산에서 오버플로우 또는 언더플로우가 발생되면 해당 정수 타입의 최소값 또는 최대값으로 되돌아간다.
short, int, long 타입은 값의 범위만 다를 뿐 오버플로우 및 언더플로우가 발생했을 떄 마찬가지로 최소값 또는 최대값을 되돌아간다.
연산 과정 중 발생하는 오버플로우와 언더플로우는 우리가 기대하는 값이 아니므로 항상 해당 타입의 범위 내에서 연산이 수행되도록 유의해야 한다. 만약 연산 과정에서 int 타입에서 오버플로우 또는 언더플로우가 발생될 가능성이 있다면 long 타입으로 연산을 하도록 해야 한다.
3.4 정확한 계산은 정수 연산으로
산술 연산을 정확하게 계산하고 싶다면 실수 타입을 사용하지 않는 것이 좋다.
3.5 나눗셈 연산 후 NaN과 Infinity 처리
나눗셈(/) 또는 나머지(%) 연산에서 좌측 피연산자가 정수이고 우측 피연산자가 0일 경우 예외(ArithmeticException)가 발생한다. 무한대의 값을 정수로 표현할 수 없기 때문이다.
하지만 죄측 피연산자가 실수이거나 우측 피연산자가 0.0 또는 0.0f이면 예외가 발생하지 않고 연산의 결과는 Infinity(무한대) 또는 NaN(Not a Number)이 된다. 이 상태에서 계속해서 연산을 수행하게 된다면 어떤 연산을 하더라도 결과는 계속해서 Infinity와 NaN이 되므로 데이터가 엉망이 될 수 있다.
그렇기 때문에 /와 % 연산의 결과를 먼저 확인하고 다음 연산을 수행하는 것이 좋다. Double.isInfinite()와 Double.isNaN()을 사용하여 결과를 확인한다. 변수값이 Infinity 또는 NaN일 경우 true를, 그렇지 않다면 false를 산출한다.
3.6 비교 연산자
동등 또는 크기를 평가해서 true/false를 산출한다. 조건문, 반복문에서 실행 흐름을 제어할 때 주로 사용된다.
구분 | 연산식 | 설명 | ||
동등 비교 | 피연산자1 | == | 피연산자2 | 두 피연산자의 값이 같은지를 검사 |
피연산자1 | != | 피연산자2 | 두 피연산자의 값이 다른지를 검사 | |
크기 비교 | 피연산자1 | > | 피연산자2 | 피연산자1이 큰지를 검사 |
피연산자1 | >= | 피연산자2 | 피연산자1이 크거나 같은지를 검사 | |
피연산자1 | < | 피연산자2 | 피연산자1이 작은지를 검사 | |
피연산자1 | <= | 피연산자2 | 피연산자1이 작거나 같은지를 검사 |
피연산자의 타입이 다를 경우에는 비교 연산을 수행하기 전에 타입을 일치시킨다. 실수 타입같은 경우에서 float 타입이 double 타입으로 변환되면 값이 true라도 false가 산출된다.
부동 소수점 방식을 사용하는 실수 타입은 소수값을 정확히 표현할 수 없고, float 타입과 double 타입의 정밀도 차이 때문이다. 해결 방법은 double 타입인 피연산자를 float 타입으로 강제 타입 변환 후에 비교 연산을 하면 된다.
문자열을 비교할 때에는 동등 연산자 대신 equals()와 ! equals()를 사용한다.
3.7 논리 연산자
아래의 논리 연산을 수행한다. 조건문, 반복문 등에서 주로 사용한다.
구분 | 연산식 | 결과 | 설명 | ||
AND (논리곱) |
true | && 또는 & |
false | true | 피연산자 모두가 true일 경우에만 연산 결과가 true |
true | false | false | |||
false | true | false | |||
false | true | false | |||
OR (논리합) |
true | || 또는 | |
false | true | 피연산자 중 하나만 true이면 연산 결과는 true |
true | false | true | |||
false | true | true | |||
false | true | false | |||
XOR (배타적 논리합) |
true | ^ | false | false | 피연산자가 하나는 true이고 다른 하나가 false일 경우에만 연산 결과가 true |
true | false | true | |||
false | true | true | |||
false | true | false | |||
NOT (논리 부정) |
! | true | false | 피연산자의 논리값을 바꿈 | |
false | true |
3.8 비트 논리 연산자
bit 단위로 논리 연산을 수행한다. 0과 1이 피연산자가 되므로 2진수 0과 1로 저장되는 정수 타입(byte, short, int, long)만 피연산자가 될 수 있다. 1은 true, 0은 false라고 생각하면 된다.
구분 | 연산식 | 결과 | 설명 | ||
AND (논리곱) |
1 | & | 1 | 1 | 두 비트 모두 1일 경우에만 연산 결과가 1 |
1 | 0 | 0 | |||
0 | 1 | 0 | |||
0 | 0 | 0 | |||
OR (논리합) |
1 | | | 1 | 1 | 두 비트 중 하나만 1이면 연산 결과는 1 |
1 | 0 | 0 | |||
0 | 1 | 1 | |||
0 | 0 | 0 | |||
XOR (배타적 논리합) |
1 | 1 | 0 | 두 비트 중 하나는 1이고 다른 하나가 0일 경우 연산 결과는 1 |
|
1 | 0 | 1 | |||
0 | 1 | 1 | |||
0 | 0 | 0 | |||
NOT (논리 부정) |
~ | 1 | 0 | 보수 | |
0 | 1 |
예시 (후에 작성 예정)
3.9 비트 이동 연산자
비트를 좌측 또는 우측으로 밀어서 이동시키는 연산을 수행한다.
구분 | 연산식 | 설명 | ||
이동 (Shift) |
a | << | b | 정수 a의 각 비트를 b만큼 왼쪽으로 이동 오른쪽 빈자리는 0으로 채움 a × 2^b와 동일한 결과가 됨 |
a | >> | b | 정수 a의 각 비트를 b만큼 오른쪽으로 이동 왼쪽 빈자리는 최상위 부호 비트와 같은 값으로 채움 a / 2^b와 동일한 결과가 됨 |
|
a | >>> | b | 정수 a의 각 비트를 b만큼 오른쪽으로 이동 왼쪽 빈자리는 0으로 채움 |
예시 (후에 작성 예정)
3.10 대입 연산자
우측 피연산자의 값을 좌측 피연산자인 변수에 대입한다. 우측 피연산자에는 리터럴 및 변수, 다른 연산식이 올 수 있다.
구분 | 연산식 | 설명 | ||
단순 대입 연산자 | 변수 | = | 피연산자 | 우측의 피연산자의 값을 변수에 저장 |
복합 대입 연산자 | 변수 | += | 피연산자 | 우측의 피연산자의 값을 변수의 값과 더한 후에 다시 변수에 저장 (변수 = 변수 + 피연산자) |
변수 | -= | 피연산자 | 우측의 피연산자의 값을 변수의 값과 뺀 후에 다시 변수에 저장 (변수 = 변수 - 피연산자) |
|
변수 | *= | 피연산자 | 우측의 피연산자의 값을 변수의 값과 곱한 후에 다시 변수에 저장 (변수 = 변수 * 피연산자) |
|
변수 | /= | 피연산자 | 우측의 피연산자의 값으로 변수의 값과 나눈 후에 다시 변수에 저장 (변수 = 변수 / 피연산자) |
|
변수 | %= | 피연산자 | 우측의 피연산자의 값으로 변수의 값과 나눈 후에 나머지를 변수에 저장 (변수 = 변수 % 피연산자) |
|
변수 | &= | 피연산자 | 우측의 피연산자의 값과 변수의 값을 & 연산 후 결과를 변수에 저장 (변수 = 변수 & 피연산자) |
|
변수 | |= | 피연산자 | 우측의 피연산자의 값과 변수의 값을 | 연산 후 결과를 변수에 저장 (변수 = 변수 | 피연산자) |
|
변수 | ^= | 피연산자 | 우측의 피연산자의 값과 변수의 값을 ^ 연산 후 결과를 변수에 저장 (변수 = 변수 ^ 피연산자) |
|
변수 | <<= | 피연산자 | 우측의 피연산자의 값과 변수의 값을 << 연산 후 결과를 변수에 저장 (변수 = 변수 << 피연산자) |
|
변수 | >>= | 피연산자 | 우측의 피연산자의 값과 변수의 값을 >> 연산 후 결과를 변수에 저장 (변수 = 변수 >> 피연산자) |
|
변수 | >>>= | 피연산자 | 우측의 피연산자의 값과 변수의 값을 >>> 연산 후 결과를 변수에 저장 (변수 = 변수 >>> 피연산자) |
3.11 삼항(조건) 연산자
피연산자 ? 피연산자 : 피연산자
? 앞의 피연산자는 boolean 변수 또는 조건식이 오므로 조건 연산자라고도 한다. 이 값이 true이면 콜론(:) 앞의 피연산자가 선택되고, false이면 콜론 뒤의 피연산자가 선택된다.
3.12 연산의 방향과 우선 순위
연산자 | 연산 방향 | 우선 순위 |
증감(++, --), 부호(+, -), 비트(~), 논리(!) | ← | 높음 ↑ | ↓ 낮음 |
산술(*, /, %) | → | |
산술(+, -) | → | |
쉬프트(<<, >>, >>>) | → | |
비교(<, >, <=, >=, instanceof) | → | |
비교(==, !=) | → | |
논리(&) | → | |
논리(^) | → | |
논리(|) | → | |
논리(&&) | → | |
논리(||) | → | |
조건(?:) | → | |
대입(=, +=, -=, *=, /=, %=, &=, ^=, |=, <<=, >>=, >>>=) | ← |
'JAVA 개념 > Part 01; 자바 언어 기초' 카테고리의 다른 글
[이것이 자바다] CHAPTER 04. 조건문과 반복문 (0) | 2024.06.15 |
---|---|
[이것이 자바다] CHAPTER 02. 변수와 타입 │ 개념 (0) | 2024.06.05 |
[이것이 자바다] CHAPTER 01. 자바 시작하기 (0) | 2024.05.31 |