Java week3


3주차

산술 연산자
비트 연산자
관계 연산자
논리 연산자
instanceof
assignment(=) operator
화살표(->) 연산자
3항 연산자
연산자 우선 순위
(optional) Java 13. switch 연산자

연산자

  • 연산: 데이터를 처리하여 결과를 산출하는 것으로 연산식은 반드시 하나의 값을 산출
  • 연산자(operator): 연산에 사용되는 표시나 기호
  • 피연산자: 연산되는 데이터
  • 피연산자의 수에 따라서
    • 단항 연산자: ++x;
    • 이항 연산자: x + y;
    • 삼항 연산자: 조건식(피연산자1) ? 값 또는 연산식(피연산자2): 값 또는 연산식(피연산자3)
      • 피연산자1 인 조건식이 참 인경우 피연산자2 산출. 거짓 인경우 피연산자3 산출.
      • ex) int num=20 (num>10) ? “A”: “B”;
  • 연산자 종류: 산술, 부호, 문자열, 대입, 증감, 비교, 논리, 조건, 비트, 쉬프트
  • 연산 방향: 증감, 대입 연산자는 우변에서 좌변, 나머지는 좌측에서 우측으로 연산이 이루어진다.
  • 연산자 우선순위 는 하단에서 설명


1. 산술 연산자

  • +, -, *, /, %: 사칙연산과 나머지 계산을 하는 연산으로 결과는 숫자 타입으로 결과가 나온다
    • / : 몫
    • %: 나머지
  • 우선순위: *, /, % 이 같은 우선순위를 가진다.
  • 산술 연산자는 피연산자들의 타입이 동일하지 않을 경우 다음의 규칙을 통해서 피연산자들의 타입을 일치하여 연산을 수행
1. 피연산자들이 정수이면서 int보다 작은 경우(= byte) int로 변환하여 계산, int로 산출
	byte + byte => int + int = int
2. 피연산자들이 정수이면서, long타입이 있는 경우 long으로 변환하여 계산, long으로 산출
	int + long => long + long = long
3. 피연산자 중 실수 타입(float, double)이 있는 경우, 크기가 큰 실수 타입으로 변환 후 연산, 큰 실수 타입으로 산출
	int + double => double + double = double	
	

1번의 경우에는 기본적으로 Java가 아니 JVM이 32bit 단위로 계산을 하기 때문에 int(4byte) 타입으로 나오게 됨

산술 연산을 적용할 때는 해당 타입의 범위를 벗어나는지 체크하는 로직이 들어가야 할 듯
  • NaN Infinity 연산
5 / 0 -> ArithmeticException 발생
5 % 0  -> ArithmeticException 발생

- 실수타입으로 나눈다면?
double a = 5 / 0.0 -> Infinity
double b = 5 % 0.0 -> NaN(Not a Number)

a + 1
b + 2

이런식으로 연산을 이어나가게되면 엉망이된다.
  • 무한대 이거나, Not a Number 의 경우는 사실 연산 과정에서 잘못된 입력을 받았다고 생각하면된다.
  • Double.isInfinite(), Double.isNaN() 메소드를 활용해서 파악할 수 있다.


2. 비트 연산자

  • bit 단위로 연산. 0과 1이 피연산자이다.
  • 0과 1로만 표현이 가능한 정수 타입만 비트 연산을 할 수 있다.
  • 기능에 따라서 비트 논리 연산자비트 이동 연산자로 구분

비트 논리 연산자(&, |, ^, ~)

  • 논리곱(&) : 두 비트가 모두 1일 경우에 연산 결과가 1
  • 논리합(|) : 두 비트 중 하나이상 1이면 연산 결과가 1
  • 배타적 논리합(^): 두 비트 중 하나만 1이면 연산 결과가 1
  • 논리 부정(~): 보수
  • 논리 연산 결과는 int 타입

  • 예시
1. 십진수 45, 25를 비트 논리 연산

45(10) = 00101101(2)
25(10) = 00011001(2)

(1) 논리곱(&)
00101101
00011001
00001001 = 9(10)

(2) 논리합(|)
00101101
00011001
00111101 = 61(10)

(3) 배타적 논리합(|)
00101101
00011001
00110100 = 52(10)

(4) 논리 부정(~)
00101101  -> 11010010
00011001 -> 11100110

비트 이동 연산자(«, », »>)

  • 정수 데이터의 비트를 좌측과 우측으로 이동하는 연산자 = 쉬프트연산
  • a « b // 정수 a의 각 비트를 b만큼 왼쪽으로 이동. 빈자리는 0으로 채워진다
  • a » b // 정수 a의 각 비트를 b만큼 오른쪽으로 이동. 빈자리는 최상위 부호 비트와 같은 값으로 채워진다
  • a »> b // 정수 a의 각 비트를 b만큼 오른쪽으로 이동. 빈자리는 0으로 채워진다 (자바에만 있는 연산임) -> 결과는 무조건 양수

  • 비트연산 잘 정리된 블로그


3. 관계(비교) 연산자

  • 비교 연산자는 대소(<, <=, >, >=) 동등(==, !=) 비교하여 boolean 타입을 리턴한다.
  • 비교할 때 비교되는 피연산자들의 타입을 일치시키는데 대표적인 예는 아래와 같다
- char = int
'A' == 65 // 이경우 int 타입으로 변환되어서 true를 리턴한다.

- int = double
3 == 3.0 // 이경우 double 타입으로 변환되어서 true를 리턴한다.


- 예외
double == float
3.0 == 3.0f  ------> false

기본적으로 실수에 f를 붙이지 않으면 double형으로 인식하는데
double 3.0과 float 3.0은 다르다.
이유는 모든 부동소수점 타입은 0.1을 정확하게 표현할 수 없다.
예를 들어서 0.1f 는 0.1의 근사값으로 0.10000000149011612와 같은 값이 된다.
때문에 실질적으로 0.1보다는 큰 값이다.
그래서 정확한 계산을 위해서는 int로 계산하는 것이 맞다. 아래 예시를 적는다.

추가) 실수타입.. 정확한 값을 계산하지 못하는 경우

  • 실수를 표현하는 방법으로 부동소수점을 사용
  • 32비트로 되어있으며 부호부에 1비트, 지수부(정수)에 8비트, 가수부(실수)에 23비트를 할당하는 표현 방식을 말한다.
  • 정수부분을 2진수로 변환한 값을 지수부에, 실수(소수점이하 부분)을 2진수로 변환한 값을 가수부에
  • ex) 0.3을 2진수로 변환하면 0100110011 …..무한 반복. 결국 아래와 같이 실수탑은 정확한 값을 계산하지 못함


4. 논리연산자

  • 논리곱(&& 혹은 &), 논리합( 혹은), 배타적 논리합(^), 논리 부정(!) 연산 수행
  • 피연산자는 boolean 타입만 사용
  • 논리곱(&&) : 피연산자 모두가 true 일 때 연산 결과가 true
  • 논리합(||) : 피연산자 하나이상 true 일 때 연산 결과가 true
  • 배타적논리합(^) : 피연산자가 하나만 true 일 때 연산 결과가 true
  • 논리부정(!) : 피연산자의 논리값을 바꿈 true -> false , false -> true

(&& vs &) , (|| vs |) 차이

  • &&, 연산자가 &,보다 결과를 빠르게 낼 수 있다.
  • &&, 연산자가 &,연산자와 다르게 앞의 피연산자의 결과에 따라서 뒤 연산 결과를 확인하지 않고, 결과를 산출한다


5. instanceof

  • 객체의 타입을 확인하는 연산자로, 특정 클래스나 인터페이스로부터 생성된 객체인지 판별하여 boolean 타입 리턴
  • 상속관계에서도 사용이 가능하다. 자식 클래스 객체 instanceof 부모 클래스 => true
  • ** 타입이 상위클래스도 하위클래스도 아닐경우 에러. 타입은 해당 객체의 클래스의 상위 클래스 혹은 하위 클래스
  • 사용방법 객체 instanceof 클래스
A a = new A();
boolean result = a instanceof A;


6. assignment(=) operator 대입 연산자

  • 연산이 있거나 단순히 대입이거나 최종적인 값을 좌측 연산자에 저장한다.
  • 모든 연산자 중에서 가장 낮은 연산 순위로 가장 마지막에 수행 된다.
  • 연산의 진행방향은 우측에서 좌측이다
  • a = b = 3 => b=3 그리고 a =b 실행

단순 대입 연산자

  • 우측 피연산자 값을 좌측 피연산자의 변수에 저장
  • 우측 피연산자는 리터럴, 변수, 연산식이 올 수 있다. 좌측에는 우측 값을 저장하는 변수가 온다.
  • =

복합 대입 연산자

  • 우측의 피연산자 값으로 좌측 변수에 연산자를 적용하여 다시 좌측 변수에 저장한다.
  • +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=, >>>=


7. 화살표(->) 연산자

  • Java 8에서 Lambda 표현식을 위해 사용하는 연산자
  • 화살표 연산자는 아래와 같이 표현한다.
Runnable runnable = new Runnable() {
	public void run() {........}
};

-> 화살표를 이용한 람다식 기본 표현

1. (매개변수) -> {함수본문}
2. () -> {함수몸체)
3. (매개변수) -> 함수본문
4. (매개변수) -> {return x;}


8. 연산자 우선 순위

  • 연산자 우선순위: 연산자가 복합적으로 사용되는 아래와 같은 예시에서 우선순위가 있다.
    • x > 0 && y < 0 : 1순위: x, y를 0과 크기를 비교하는 비교연산. 2순위: && 연산

|연산자|연산 방향|우선순위| |——|—–|:—–:| |증감(++, –), 부호(+, -), 비트(~), 논리(!)|<———-|높음| |산술(*, /, %)|———->|↑| |시프트(«, », »>)|———->|│| |비교(<, >, <=, >=, instanceof)|———->|│| |비교(==, !=)|———->|│| |논리(&)|———->|│| |논리(^)|———->|│| |논리(|)|———->|│| |논리(&&)|———->|│| |논리(∥)|———->|│| |논리(?:)|———->|↓| |대입(=, +=, -=, *=, /=, %=, &=, ^=, |=, «=, »=, »>=)|———->|낮음| ** 표 참고: 책 이것이 자바다

참고