연산자(operator)

연산자의 우선순위와 결합규칙

  • 단항 연산자와 대입 연산자의 결합규칙은 오른쪽에서 왼쪽으로
    • x = y = 3
    • 오른쪽 대입연산자부터 처리하므로 y = 3이 먼저 수행되고 x = 3이 그 다음에 수행

산술 변환(usual arithmetic conversion)

  • 연산 수행 직전에 발생하는 피연산자의 자동 형변환
    • 두 피연산자의 타입을 같게 일치시킨다(보다 큰 타입으로)
    • 피연산자의 타입이 int보다 작은 타입이면 Int로 변환된다

3. 산술 연산자

3.1 사칙 연산자 - +, -, *, / /

  • int a = 1_000_000, int b = 2_000_000
  • long c = a * b –> int끼리 연산하면 결과도 int이므로 의도치 않은 값이 나옴
  • 문자 '2'를 숫자로 변환하려면 문자 '0'을 빼주면 된다.
char c1 = 'a';
char c2 = c1 + 1; // 컴파일에러
char c2 = 'a' + 1;  // 에러 없음
  • 컴파일에러: 수식에 변수가 들어가 있으면 컴파일러가 미리 계산할 수 없으므로 char로 형변환 후 담아야 함
  • 에러가 없는 이유는 'a' + 1은 리터럴간 연산이므로 런타임이 아닌 컴파일 시 계산을 한다. char c2에는 'b'를 저장한다.
  • 대문자와 소문자 간 코드값 차이는 10진수로 32
  • int / int의 결과는 int, 소수점 이하는 버림
    • (int)(pi * 1000) / 1000f; 괄호 우선순위가 가장 높다
    • (int)(3141.592f) / 1000f; 그 다음 단항연산자인 형변환 연산자의 형변환 수행. 소수점 이하는 버린다.
    • 3141 / 1000f; int와 float의 연산이므로 float로 변환하여 연산
    • 3.141f

3.2 나머지 연산자 - %

  • 나머지 연산자(%)는 나누는 수로 음수도 허용하지만 부호는 무시되므로 나머지 연산을 한 결과를 나눠지는 수에 붙이면 된다.

4. 비교 연산자

  • 비교 연산자도 이항 연산자이므로 연산을 수행하기 전에 형변환을 통해 두 피연산자의 타입을 갖게 맞춘 다음 피연산자를 비교한다.
10.0 == 10.0f // true
0.1 == 0.1f // false

float f = 0.01f; // 0.0000000149011612 저장
double d = 0.1;  // 0.0000000000000001 저장
  • 10.0f는 오차없이 저장 가능하지만 0.1f는 저장할 때 2진수로 변환하는 과정에서 오차가 발생한다. 정수형과 달리 실수형은 근사값으로 저장하므로 오차가 발생할 수 있다.
  • float를 double로 바꾸면 정밀도는 높아지지만 오차가 없어지지는 않는다.
  • floatd와 double을 비교하려면 double을 float로 형변환한 다음에 비교
String str = "abc";
boolean result = str.equals("abc");
  • 문자열 비교는 equals()를 사용
  • 같은 문자열을 다음 두 변수를 ==로 비교하면 false다. 내용은 같지만 서로 다른 객체이므로.
  • 대소문자 구별없이 비교하려면 equalsIgnoreCase()
  • String만 new를 사용하지 않고 초기화 가능

5. 논리 연산자

5.1 논리 연산자 - &&, ||, !

  • x   y
    • x가 true이면 y는 항상 true이다.
    • or연산은 참일 확률이 높은 피연산자를 왼쪽에 놓아야 더 빠른 결과를 얻을 수 있다.

5.2 비트 연산자 - &, |, ^, ~, 〈〈, 〉〉

  • 이진수로 표현한 피연산자를 비트단위로 논리 연산한다.
  • 비트 연산은 피연산자로 실수는 허용하지 않고 정수(문자 포함)만 허용
  • I (or) : 피연산자 중 한 쪽의 값이 1이면, 1을 결과로 얻는다. 이외에는 0을 얻는다.
  • & (and) : 피연산자 양쪽이 모두 1이어야만 1을 결과로 얻는다. 이외에는 0을 얻는다.
  • ^ (xor) : 피연산자의 값이 서로 다를 때만 1을 결과로 얻는다. 같을 때는 0을 얻는다.

~ 비트 전환 연산자

  • 논리부정 연산자와 유사하게 이진수로 표현했을 때 0은 1로, 1은 0으로 바꾼다.
  • 부호가 반대로 변경된다. 즉, 피연산자의 '1의 보수'를 얻는다.
  • 예: 10진수 10 (이진수: 0001010) –> 10진수 -11 (이진수: 11110101)
  • 양의정수 p가 있을 때, p에 대한 음의 정수를 얻으려면 ~p+1을 계산하면 된다.

« » 시프트 연산자

  • 2진수로 표현한 피연산자의 각 자리를 오른쪽(») 또는 왼쪽(«)으로 이동
  • 8 « 2 : 10진수 8의 2진수를 왼쪽으로 2자리 이동
  • «
    • 자리 이동으로 저장범위를 벗어난 값들은 버려지고 빈자리는 0으로 채워진다.
    • 왼쪽 피연산자가 음수인 경우 빈자리를 1로 채운다.
  • 2진수 n자리를 왼쪽으로 이동하면 2^n으로 곱한 결과를, 오른쪽으로 이동하면 2^n으로 나눈 결과를 얻을 수 있다. - x « n은 x * 2^n - x » n은 x / 2^n
  • 10진수로 자리이동을 하면 123에서 오른쪽으로 2자리 이동했을 때 10^2을 곱해 12300
  • x » n 에서 n의 값이 자료형의 비트수보다 크면 자료형의 비트수로 나눈 나머지 만큼 이동한다.

Source