📝 이것이 자바다

Chapter 03. 연산자

j_estory 2022. 10. 30. 14:52

3.1 부호/증감 연산자

  • 부호 연산자는 변수의 부호를 유지하거나 변경한다.
  • 주의할 점은 부호 변경 후의 타입이다. 
  • 정수 타입 (byte, short, int) 연산의 결과는 int 타입이다. 
    • 부호를 변경하는 것도 연산이므로 부호 변경 후, 타입은 반드시 int에 대입해야 한다.

🏷 ++ 연산자, -- 연산자

int x = 1;
int y = 1;
int result1 = ++x + 10; // x를 1 증가 -> int result1 = 2 + 10
int result2 = y++ + 10; // y + 10 -> y를 1 증가
  • 부호 + 피연산자 
    • 피연산자의 값을 1 증가시킨다.
  • 피연사자 + 부호
    • 다른 연산을 수행한 후에 피연산자의 값을 1 증가시킨다.

 

3.2 산술 연산자

  • 산술 연산자는 (+, -, *, /, %) 총 5개이다. 
  • 곱셈의 경우, *를 사용하고 나눗셈의 경우 /를 사용한다는 것이 일반 수학과 다르다. 
  • % 연산자는 나눗셈을 수행한 후에 몫이 아닌 나머지를 산출하는 연산자이다. 

🏷 산술 연산의 특징

  • 피연산자가 정수 타입(byte, short, char, int) 이면, 연산의 결과는 int 타입이다. 
  • 피연산자가 정수 타입이고, 그 중 하나가 long 타입이면 연산의 결과는 long 타입이다. 
  • 피연산자 중 하나가 실수 타입이면 연산의 결과는 실수 타입이다. 

 

3.3 오버플로우와 언더플로우

더보기

📘 오버 플로우

  • 타입이 허용하는 최대값을 벗어나는 것을 의미

📘 언더 플로우

  • 타입이 허용하는 최소값을 벗어나는 것을 의미
  • 정수 타입에서 오버플로우 또는 언더플로우가 발생되면 실행 에러가 날 것 같지만,
    그렇지는 않고 해당 정수 타입의 최소값 또는 최대값으로 돌아가게 된다.
byte value = 127;
value++; // value : -12
  • 예를들어, byte 타입의 경우 최대값 127에서 1을 더하면 128이 되어 오버플로우가 발생하고 연산 결과는 최소값인 -128이 된다. 
  • 마찬가지로 -128에서 1을 빼면 -129가 되어 언더플로우가 발생하여 연산 결과는 127이 된다. 
  • short, int, long 타입은 값의 범위만 다를 뿐 오버플로운 및 언더플로우가 발생하였을 때 최소값 또는 최대값으로 돌아간다.
  • 만약 Int 타입에서 오버플로우 또는 언더플로우가 발생될 가능성이 있다면 long 타입으로 연산을 하도록 해야 한다.

 

3.4 정확한 계산은 정수 연산으로

  • 산술 연산을 정확하게 계산하고 싶다면 실수 타입을 사용하지 않는 것이 좋다. 
  • 이해가 안감 ..

 

3.5 나눗셈 연산 후 NaN과 Infinity 처리

  • 나눗셈 및 나머지 연산에서 좌측 피연산자가 정수이가 우측 피연산자가 0일 경우 예외가 발생한다. 
    • 무한대의 값을 정수로 표현할 수 없기 때문이다. 
  • 하지만 좌측 피연산자가 실수이거나 우측 피연산자가 0.0 또는 0.0f이면 예외가 발생하지 않고
    연산의 결과는 Infinity (무한대) 또는 NaN (Not a Number) 이 된다. 
    • 위 상태에서 연산을 수행하면 결과는 계속 무한대와 NaN이 되므로 데이터가 엉망이 될 수 있다. 
    • Double.isInfinite()와 Double.isNaN()을 사용하여 확인 후 연산을 하자!

 

3.6 비교 연산자

  • 동등 ( ==, != ) 또는 크기 ( <, <=, >, >=)를 평가하여 boolean 타입인 true/false를 산출한다.
'A' == 65 // true
3 == 3.0 // true
0.1f == 0.1 // false
  • 부동 소수점 방식을 사용하는 실수 타입은 0.1을 정확히 표현할 수 없을 뿐만 아니라 float 타입과 double 타입의 정밀도 차이 때문이다. 
    • 해결 방법은 0.1f == (float) 0.1 -> true 가 된다.

❓ pg90 : 1이랑 1.0이랑은 왜 같고, 0.1f 랑 0.1은 왜 다르지?

  • double형과 float형은 모두 부동 소수점 형인데 왜 다른것일까 ..

 

3.7 논리 연산자

  • 논리 연산자는 논리곱(&&), 논리합(||), 배타적 논리합(^) 그리고 논리 부정(!) 연산을 수행한다. 
    • ^ : 피연산자 하나는 true이고 하나가 false일 경우에만 연산 결과가 true이다.

🏷 && vs &

  • && ( || )
    • 앞의 피 연산자가 false이면 뒤의 피연산자를 평가하지 않고 바로 false를 산출한다.
    • 더 효율적으로 동작한다.
  •  & ( | )
    • 두 피연산자를 모두 평가해서 산출 결과를 낸다. 

 

3.8 비트 논리 연산자

  • bit 단위로 논리 연산을 수행한다. 
    • & : AND (논리곱)
    • | : OR (논리합)
    • ^ : XOR (배타적 논리합)
    • ~ : NOT (논리 부정)
  • 0과 1이 피연산자가 되므로 2진수 0과 1로 저장되는 정수 타입(byte, int, long, short)만 피연산자가 될 수 있고, 
    부동 소수점 방식으로 저장되는 실수 타입(float, double) 은 피연산자가 될 수 없다. 
  • 비트 논리 연산자는 byte, char, short 타입 피연산자를 int 타입으로 자동 변환한 후 연산을 수행한다.

 

3.9 비트 이동 연산자

  • 비트를 좌측 또는 우측으로 밀어서 이동시키는 연산을 수행한다. 
  • 종류
    • a << b
      • 정수 a의 각 비트를 b 만큼 왼쪽으로 이동
      • 오른쪽 빈자리는 0으로 채움
    • a >> b
      • 정수 a의 각 비트를 b 만큼 오른쪽으로 이동
      • 왼쪽 빈자리는 최상위 부호 비트와 같은 값으로 채움
    • a >>> b
      • 정수 a의 각 비트를 b 만큼 오른쪽으로 이동
      • 왼쪽 빈자리는 0으로 채움

 

 

3.10 대입 연산자

  • 우측 피연산자의 값을 좌측 피연산자인 변수에 대입한다. 
  • 단순 대입 연산자
  • 복합 대입 연산자 
    • +=, -=, *=, /=, %= 등 ... 

 

3.11 삼항 연산자

  • 삼항연산자는 3개의 피연산자를 가진다.
  • ? 앞의 피 연산자는 boolean 변수 또는 조건식이 오므로 조건 연산자라고도 한다. 
    이 값이 true 이면 : 앞의 피연산자가 선택되고 flase 이면 : 뒤의 피연산자가 선택된다.

 

3.12 연산의 방향과 우선순위

  • x > 0 && y < 0 
    • >,< (>) && 이기 때문에 x>0, y<0이 먼저 처리된다.
  • *, /, %
    • 우선순위가 동일하기 때문에 방향이 왼쪽에서 오른쪽으로 수행된다. 
  • 대입 연산자 및 증감(++, --, +, -, ~, !)
    • 연산 순서가 오른쪽에서 왼쪽으로 수행된다. 
  • 우선 순위 
    • 증감 > 곱 나눗셈 나누기 > 더하기 빼기 > <,> > ==, != > && > || > ==, += 
    • 여러 연산자들이 섞여 있으면 헷갈리니 괄호를 사용하여 우선순위를 높이자 !!