Java) 연산자에서 잊기 쉬운 부분

Wonjun Lee·2024년 4월 2일
0

X << 2 + 1;
data & 0xff == 0
x < -1 || x > 3 && x < 5

우선순위를 고려하여 괄호로 표시하면 다음과 같다.

X << (2 + 1)
data & (0xff == 0)
(x < -1) || ((x > 3) && (x < 5))

  1. 쉬프트 연산은 산술 연산이지만 (2의 제곱수를 곱하는 연산이므로.) 덧셈 연산자보다 우선순위가 낮다.
  2. bitwise & 연산자는 비교연산자보다 우선순위가 낮다.
  3. AND 연산자는 OR 연산자보다 우선순위가 높다.

참고사항)
instanceof 연산자는 비교연산자로 == !=보다 우선순위가 높다.
같은 비교연산자라도 >=, <= 등의 크기비교 연산은 ==와 !=보다 높다.
!는 논리값을 반전시키지만, 단항 연산자이므로 우선순위가 가장 높다.
비트 연산자는 논리 연산자보다 우선순위가 높다. & ^ | 순으로 낮아진다.
증감 연산자는 정수, 실수 모두 사용 가능하다.

x = 5;
x = x++ - ++x;
위 연산의 결과 x의 값은 무엇일까?

보기 쉽게 괄호로 묶으면
x = (x++) - (++x); 이다.
왼쪽의 괄호부터 계산된다. 이때, 후위연산자이므로 증가 이전의 값을 반환하고 그 직후에 x의 값은 1이 증가된다. 다음라인으로 가지 않아도 증가된다.
따라서,
x = 5 - (++x)이고, 이후 x는 6인데 한 번 더 전위연산으로 증가되니, 7이 되고 7을 반환한다.
x = 5 - 7;

따라서 결과는 -2 가 된다.


산술 연산자에서 나눗셈은 분모의 형태에 주의해야한다.
정수형 나눗셈을 수행할 경우 분모에 0이 올 수 없다.
--> ArithmeticException(uncheckedException)이 발생함.

실수형 나눗셈을 수행할 경우 분모에 0이 오면 Intinity가 출력된다.
반대로 분모가 Intinity인 경우 0.0이 출력된다.


자바의 연산과정에서 정수형 피연산자들은 int 보다 작은 타입일 때 자동으로 4바이트로 처리되기 때문에 다음 문장은 오류가 발생한다.
byte a = 1, b = 2;
byte c = a + b; // 여기서 오류. int형 값을 byte에 저장하기 때문


리터럴과 리터럴, 상수와 리터럴 연산은 컴파일 시간에 실제값으로 치환하여 코드를 효율적으로 구성하게 된다. 따라서 이 경우 타입 불일치로 발생하는 문제는 컴파일 에러에 속한다.

이런 특징 덕에 굳이 어렵게 식을 작성하지 않아도 성능 차이가 없다.
예를 들어서, 초단위를 일 단위로 변경할 때, 86400으로 나눌 필요 없이 60 * 60 * 24로 적는 편이 낫다.

서로 다른 기호 간의 나머지 연산은 분모 부분에 0이 와선 안된다. 결과값의 부호는 피제수 부호에 따른다.

-10 % 8 = -2
10 % -8 = 2
-10 % -8 = -2


비트 연산자 & ^ | ~ >> <<
이들은 피연산자로 실수를 허용하지 않는다.(정수, 문자는 가능하다.)


시프트 연산은 2의 제곱수로 곱하거나 나누는 것과 같다. 하지만 음의 정수에 대해서는 산술연산과 쉬프트 연산으로 나눗셈하는 것이 동일하지 않다.

-7 >> 2는 -4이지만, -7 / 2 는 -3이다.

따라서 이런 경우 피제수를 2의 보수화하여 몫을 구하고 다시 보수화하는 방법을 사용한다. 하지만 번거로우므로 산술 연산을 이용한다.

쉬프트 연산은 자동으로 좌측 피연산자를 int 타입으로 변경한다. 연산의 결과 역시 int 타입이다. 우측 피연산자는 형변환 되지 않는다.

쉬프트 연산에서 쉬프트 양을 나타내는 오른쪽 피연산자는 int 타입의 비트 수인 32로 나눈 나머지 만큼만 이동한다.

n << m은 사실 n << (m % 32) 이다.

m은 부호 없는 정수로 취급되어 음수를 입력해도 자동변환된다. 가능하면 양수만 사용한다.

0개의 댓글