Roel Notebook

[Java] 3주차 과제: 연산자

by Roel Downey
728x90
반응형

 

스터디 링크 : 링크 

 

목표

자바가 제공하는 다양한 연산자를 학습하세요.

학습할 것

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

 

 

산술 연산자

산술연산자는 수학적인 계산에 사용되는 연산자다. 산술 연산자는 모두 두개의 피 연산자를 가지는 이항 연산자이다.

( 이항 연산자란? 해당 연산의 실행을 위해서 두 개의 값이나 변수가 필요한 연산자를 의미 )

+ 더하기  ex) int result = 4+2; 
- 빼기  ex) int result = 4-2;
* 곱하기  ex) int result = 4*2;
/ 나누기  ex) int result = 4/2;
% 나머지  ex) int result = 4%2;

산술 연산시 조심하기!! 

- 정수형을 0으로 나누지 않는다. : ArithmeticException : / by zero

- 실수형을 0.0으로 / , % 연산을 수행하면 Infinity , -Infinity, NaN 값을 가진다.

 

 

 

 

비트 연산자

비트 단위로 논리 연산을 할때 사용하는 연산자이다.

& 비트가 모두 1이면 1을 반환 ( AND 연산 )
| 비트 중에서 하나라도 1이면 1을 반환 ( OR 연산 )
^ 비트가 서로 다르면 1을 반환 ( XOR 연산 )
~ 비트가 1이면 0을 반환, 0이면 1을 반환 ( NOT 연산 )
<< 왼쪽으로 비트를 이동 시킴 ( left shift 연산 )
>> 부호를 유지하면서 오른쪽으로 비트를 이동 시킴 ( right shift 연산 )
>>> 지정한 수만큼 비트를 전부 오른쪽으로 이동시키며, 새로운 비트는 전부 0이 된다.

 

아래의 그림은 비트 AND 연산을 하는 그림이다. 00001111 & 00010101 을 연산해라. 라는것 이다. 

http://tcpschool.com/java/java_operator_bitwise

위의 표를 보면 &는 비트가 모두 1이면 1을 반환하는 것이다. 그렇다면 0과 0, 0과 1, 1과 0은 모두 0을 반환한다. 

그렇다면 쉽게 표로 나타내보자.

x y result
0 0 0
0 1 0
1 0 0
1 1 1

 

아래의 그림은 비트 OR 연산을 하는 그림이다. 00001111 | 00010101 을 연산해라. 라는것 이다. 

http://tcpschool.com/java/java_operator_bitwise

위의 표를 보면 | 는 비트 중에서 하나라도 1이면 1을 반환한다. 표로 나타내보자.

x y result
0 0 0
0 1 1
1 0 1
1 1 1

 

아래의 그림은 비트 XOR 연산을 하는 그림이다. 00001111 ^ 00010101 을 연산해라. 라는것 이다. 

http://tcpschool.com/java/java_operator_bitwise

위의 표를 보면 ^ 는 비트가 서로 다르면 1을 반환한다. 표로 나타내보자.

x y result
0 0 0
0 1 1
1 0 1
1 1 0

 

아래의 그림은 << 연산을 하는 그림이다. 8 << 2 를 연산해라. 라는것 이다. 

http://tcpschool.com/java/java_operator_bitwise

숫자 8은 10진수이다. 10진수 8을 2진수로 변환을 하면 1000(2) 가 된다. 

1000(2)를 왼쪽으로 비트를 2개 옮겨라. 그럼 비트 이동으로 새로 생기는 오른쪽 비트들은 0으로 채워진다.

1000000(2) 된다. 10진수로 바꾸면 32가 된다.

실행 결과를 보면 왼쪽으로 이동할 때마다 값은 2배씩 증가한다.

 

 

 

아래의 그림은 >> 연산을 하는 그림이다. -8 >> 2 를 연산해라. 라는것 이다. 

http://tcpschool.com/java/java_operator_bitwise

숫자 -8은 10진수이다. 10진수 -8을 2진수로 변환을 하면 11111000(2) 가 된다.

11111000(2)를 오른쪽으로 비트를 2개 옮겨라. 그럼 비트 이동으로 새로 생기는 왼쪽 비트는 양수일 경우에는 0으로 , 음수일 경우에는 1로 채워진다. 

11111110(2) 된다. 10진수로 바꾸면 -2가 된다.

실행 결과를 보면 오른쪽으로 이동할 때마다 값은 2배씩 감소한다.

 

여기서 중요한건!! 음수 2진수를 10진수로 변환하려면

1단계 : 1은 0으로 0은 1로 변경한다. ( 1의 보수 )

0 0 0 0 0 0 0 1

2단계 : 1단계에서 나온 결과에 1을 더한다. ( 2의 보수 )

0 0 0 0 0 0 1 0

3단계 : 2단계 결과를 10진수로 변환하여 - 기호를 붙인다.

-2

 

 

 

아래의 그림은 >>> 연산을 하는 그림이다. -8 >>> 2 를 연산해라. 라는것 이다. 

http://tcpschool.com/java/java_operator_bitwise

숫자 -8은 10진수이다. 10진수 -8을 2진수로 변환을 하면 11111000(2) 가 된다.

11111000(2)를 오른쪽으로 비트를 2개 옮겨라. 그럼 비트 이동으로 새로 생기는 왼쪽 비트들은 0으로 채워진다.

00111110(2) 된다. 10진수로 바꾸면 62가 된다.

피연산자가 음수인 경우에는 부호 비트까지도 이동하므로, 전혀 다른 결과가 반환된다. 

 

 

관계 연산자

피연산자 사이의 상대적인 크기를 판단하는 연산자이다.

예를 들어 왼쪽의 피연산자와 오른쪽의 피연산자를 비교하여, 어느쪽이 큰지, 작은지, 서로 같은지를 판단한다.

관계 연산자 설명
== 왼쪽의 피연산자와 오른쪽의 피연산자가 같으면 참
!= 왼쪽의 피연산자와 오른쪽의 피연산자가 같지 않으면 참
> 왼쪽의 피연산자와 오른쪽의 피연산자가 크면 참
>= 왼쪽의 피연산자와 오른쪽의 피연산자가 크거나 같으면 참
< 왼쪽의 피연산자와 오른쪽의 피연산자가 작으면 참
<= 왼쪽의 피연산자와 오른쪽의 피연산자가 작거나 같으면 참

 

 

728x90

 

논리 연산자

주어진 논리식을 판단하여 참과 거짓을 결정한다.

논리 연산자 설명
&& 논리식이 모두 참이면 참반환
|| 논리식 중에 하나라도 참이면 참반환
! 논리식의 결과가 참이면 거짓, 거짓이면 참을 반환

진리표를 작성해보자

A B A && B A || B !A
true true true true false
true false false true false
false true false true true
false false false false true

 

 

instanceof

참조 변수가 참조하고 있는 인스턴스의 실제 타입을 반환해준다.

즉, 해당 객체가 어떤 클래스나 인터페이스로부터 생성되었는지를 판별해 주는 역할을 한다.

왼쪽 피연산자인 인스턴스가 오른쪽 피연산자인 클래스나 인터페이스로부터 생성되었으면 true를 반환, 그렇지 않으면 false를 반환

 

- 문법 -

인스턴스이름 instanceof 클래스또는인터페이스이름

 

class A {}
class B extends A {}
public static void main(String[] args) {
    A a = new A();
    B b = new B();

    System.out.println(a instanceof A); // true

    System.out.println(b instanceof A); // true

    System.out.println(a instanceof B); // false

    System.out.println(b instanceof B); // true
}

 

 

assignment(=) operator

대입 연산자는 변수에 값을 대입할 때 사용한다. 

대입 연산자 설명
= 왼쪽 피연산자에 오른쪽의 피연산자를 대입
+= 왼쪽 피연산자에 오른쪽의 피연산자를 더한 후 대입
-= 왼쪽 피연산자에 오른쪽의 피연산자를 뺀 후 대입
*= 왼쪽 피연산자에 오른쪽의 피연산자를 곱한 후 대입
/= 왼쪽 피연산자에 오른쪽의 피연산자를 나눈 후 대입
%= 왼쪽 피연산자에 오른쪽의 피연산자를 나머지를 대입
&= 왼쪽 피연산자를 오른쪽의 피연산자를 비트 AND 연산한 후 대입
|= 왼쪽 피연산자를 오른쪽의 피연산자를 비트 OR 연산한 후 대입
^= 왼쪽 피연산자를 오른쪽의 피연산자를 비트 XOR 연산한 후 대입
<<= 왼쪽 피연산자를 오른쪽의 피연산자만큼 왼쪽 시프트한 후 대입
>>= 왼쪽 피연산자를 오른쪽의 피연산자만큼 부호를 유지하고 오른쪽 시프트한 후 대입
>>>= 왼쪽 피연산자를 오른쪽의 피연산자만큼 부호에 상관없이 오른쪽 시프트한 후 대입

 

화살표(->) 연산자

Java8에서 추가된 람다 표현식의 부분이다.

(매개변수목록) -> { 함수몸체 } 형태로 작성한다.

 

 

 

 

3항 연산자

피연산자를 3개나 가지는 조건 연산자이다.

물음표(?) 앞의 조건식에 따라 결과값이 참이면 반환값1을 반환하고, 결과값이 거짓이면 반환값2를 반환

 

- 문법 - 

조건식 ? 반환값1  :  반환값2

 

int num1 = 5, num2 = 7;
int result;
 
result = (num1 - num2 > 0) ? num1 : num2;
System.out.println("두 정수 중 더 큰 수는 " + result + "입니다.");

결과 : 두 정수 중 더 큰 수는 7입니다.

 

 

 

연산자 우선 순위

연산자의 우선순위는 수식 내에 여러 연산자가 함께 등장할 때, 어떤 연산자가 먼저 처리될 것인가를 결정한다.

 

아래 표는 우선 순위를 나타낸 표이다.

우선순위 연산자 결합 방향
1순위 [ ]  ( )   . ->
2순위 ++  --  +(양수)  -(음수)  -  !  (type)  new <-
3순위 *   /   % ->
4순위 +(더하기)   -(빼기)    +(문자 결합 연산자) ->
5순위 <<    >>    >>> ->
6순위 <    <=    >    >=    instanceof ->
7순위 ==    != ->
8순위 & ->
9순위 ^ ->
10순위 | ->
11순위 && ->
12순위 || ->
13순위 ?   :     <-
14순위 =    *=  +=  -=  %=  <<=  >>=  >>>=  &=  ^=  != <-

표 참고 - edu.goorm.io/learn/lecture/41/%EB%B0%94%EB%A1%9C%EC%8B%A4%EC%8A%B5-%EC%83%9D%ED%99%9C%EC%BD%94%EB%94%A9-%EC%9E%90%EB%B0%94-java/lesson/39380/%EC%97%B0%EC%82%B0%EC%9D%98-%EC%9A%B0%EC%84%A0%EC%88%9C%EC%9C%84

 

내가 이해하기 좋게 설명 되어 있는 그림을 가져왔다. ( TCP SCHOOL.com )

http://tcpschool.com/java/java_operator_arithmetic

 

 

(optional) Java 13. switch operator

참고 - docs.oracle.com/en/java/javase/13/language/switch-expressions.html

 

Java Language Updates

Java SE 12 introduced switch expressions, which (like all expressions) evaluate to a single value, and can be used in statements. It also introduced "arrow case" labels that eliminate the need for break statements to prevent fall through. Based on develope

docs.oracle.com

- 기존 switch 문의 break 문 없이도 아래로 떨어지는걸 방지

public enum Day { SUNDAY, MONDAY, TUESDAY,
    WEDNESDAY, THURSDAY, FRIDAY, SATURDAY; }

// ...

    int numLetters = 0;
    Day day = Day.WEDNESDAY;
    switch (day) {
        case MONDAY:
        case FRIDAY:
        case SUNDAY:
            numLetters = 6;
            break;
        case TUESDAY:
            numLetters = 7;
            break;
        case THURSDAY:
        case SATURDAY:
            numLetters = 8;
            break;
        case WEDNESDAY:
            numLetters = 9;
            break;
        default:
            throw new IllegalStateException("Invalid day: " + day);
    }
    System.out.println(numLetters);

numLetters 변수 대신에 바로 반환 할수 있다면 더 좋을것 같다. 또 break 넘어가는걸 방지하기위해 사용하지 않도록 한다.

 

그럼 새로운 종류의 case 레이블을 사용하여 해보자.

    Day day = Day.WEDNESDAY;    
    System.out.println(
        switch (day) {
            case MONDAY, FRIDAY, SUNDAY -> 6;
            case TUESDAY                -> 7;
            case THURSDAY, SATURDAY     -> 8;
            case WEDNESDAY              -> 9;
            default -> throw new IllegalStateException("Invalid day: " + day);
        }
    );    

 새로운 case 레이블은 아래와 같은 형식을 갖는다.

case label_1, label_2, ..., label_n -> expression;|throw-statement;|block 

case의 label에 매치가 되면 -> 이후의 코드를 실행시키고 switch문을 빠져 나간다. 

그럼 -> 다음의 코드는 switch 표현식의 값이다. 

 

아래의 예제는 변수에 값을 할당하는 예제이다.

    int numLetters = 0;
    Day day = Day.WEDNESDAY;
    switch (day) {
        case MONDAY, FRIDAY, SUNDAY -> numLetters = 6;
        case TUESDAY                -> numLetters = 7;
        case THURSDAY, SATURDAY     -> numLetters = 8;
        case WEDNESDAY              -> numLetters = 9;
        default -> throw new IllegalStateException("Invalid day: " + day);
    };
    System.out.println(numLetters);

 

 

아래의 예제는 yield라는 키워드를 사용했다. 

yield 는 한개의 인자를 받아와서 switch 표현식의 값으로 제공한다.

    int numLetters = switch (day) {
        case MONDAY, FRIDAY, SUNDAY -> {
            System.out.println(6);
            yield 6;
        }
        case TUESDAY -> {
            System.out.println(7);
            yield 7;
        }
        case THURSDAY, SATURDAY -> {
            System.out.println(8);
            yield 8;
        }
        case WEDNESDAY -> {
            System.out.println(9);
            yield 9;
        }
        default -> {
            throw new IllegalStateException("Invalid day: " + day);
        }
    };  

 

728x90
반응형

블로그의 정보

What doing?

Roel Downey

활동하기