기록공간

[TIL] 이노베이션 캠프 in 동북 Part 02. 연산자 본문

TIL(Today I Learned)

[TIL] 이노베이션 캠프 in 동북 Part 02. 연산자

mkm101 2023. 4. 25. 16:35
반응형
목차
Part 02. 연산자
증감연산자와 부호연산자
부호 연산자
형변환 연산자와 자동 형변환
자동 형변환
산술변환
Math클래스와 나머지 연산자
나머지 연산자 %
문자열의 비교
논리 연산자
비트 연산자
2진수의 음수표현
조건 연산자

 

Part 02. 연산자

우선순위
연산자 설명 결합 방향
[]  첨자 연산자 왼쪽에서 오른쪽으로
  . 멤버 연산자 왼쪽에서 오른쪽으로
2 ++ 후위 증가 연산자 왼쪽에서 오른쪽으로
  -- 후위 감소 연산자 왼쪽에서 오른쪽으로
3 ! 논리 NOT 연산자 오른쪽에서 왼쪽으로
  ~ 비트 NOT 연산자 오른쪽에서 왼쪽으로
  + 양의 부호 (단항 연산자) 오른쪽에서 왼쪽으로
  - 음의부호 (단항 연산자) 오른쪽에서 왼쪽으로
  ++ 전위 증가 연산자 오른쪽에서 왼쪽으로
  -- 전위 감소 연산자 오른쪽에서 왼쪽으로
4 * 곱셈 연산자  왼쪽에서 오른쪽으로
  / 나눗셈 연산자 왼쪽에서 오른쪽으로
  % 나머지 연산자  왼쪽에서 오른쪽으로
5 + 덧셈 연산자(이항 연산자) 왼쪽에서 오른쪽으로
  - 뺄셈 연산자(이항 연산자) 왼쪽에서 오른쪽으로
6 << 비트 왼쪽 시프트 연산자 왼쪽에서 오른쪽으로
  >> 부호 비트를 확장하면서 비트 오른쪽 시프트 왼쪽에서 오른쪽으로
  >>>  부호 비트까지 모두 비트 오른쪽 시프트 왼쪽에서 오른쪽으로
7 관계 연산자 왼쪽에서 오른쪽으로
  <= 관계 연산자(보다 작거나 같은) 왼쪽에서 오른쪽으로
  > 관계 연산자 (보다 큰) 왼쪽에서 오른쪽으로
  <= 관계 연산자(보다 크거나 같은) 왼쪽에서 오른쪽으로
  > 관계 연산자(보다 큰) 왼쪽에서 오른쪽으로
  >= 관계 연산자(보다 크거나 같은) 왼쪽에서 오른쪽으로
  instanceof 인스턴스의 실제 타입 반환 왼쪽에서 오른쪽으로
8 == 관계 연산자(와 같은) 왼쪽에서 오른쪽으로
  != 관계 연산자(와 같지 않은) 왼쪽에서 오른쪽으로
9 & 비트 AND 연산자 왼쪽에서 오른쪽으로
10 ^ 비트 XOR 연산자 왼쪽에서 오른쪽으로
11 | 비트 OR 연산자 왼쪽에서 오른쪽으로
12  && 논리 AND 연산자  왼쪽에서 오른쪽으로
13 || 논리 OR 연산자  왼쪽에서 오른쪽으로
14 ? :  삼항 조건 연산자 오른쪽에서 왼쪽으로
15  대입 연산자 및 복합 대입 연산자 오른쪽에서 왼쪽으로
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Operator1_1 {
    public static void main(String[] args) {
        int x = 10;
        int y = 20;
 
        // + 연산자는 피연산자가 2개인 이항 연산자 임으로 단항 연산자인 -x 의 -가 먼저 실행된다.
        System.out.print("-x + 3 = ");
        System.out.println(-+ 3); // -10 + 3 = -7
 
        System.out.print("x + 3 * y = ");
        System.out.println(x + 3 * y); // 10 + (3 * 20) = 70
 
        System.out.print("x + 3 > y - 2 = ");
        System.out.println(x + 3 > y - 2); // false
        System.out.print("x + 3 < y - 2 = ");
        System.out.println(x + 3 < y - 2); // true
 
        System.out.print("x > 3 && y < 2 = ");
        System.out.println(x > 3 && y < 2); // false
 
        int result = x + y * 3;
        System.out.println("result = " + result); // 10 + (20 * 3), result = 70
    }
}
cs

출력결과

3줄 요약


1. 산술 > 비교 > 논리 > 대입 : 대입이 제일 마지막에 수행됨

2. 단항(1) > 이항(2)>삼항(3) : 단항 연산자의 우선순위가 제일 높다.

3. 단항 연산자와 대입 연산자를 제외한 모든 연산의 진행 방향은 왼쪽에서 오른쪽이다

 

 

"증감 연산자와 부호 연산자

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Operator2_1 {
    public static void main(String[] args) {
        int k = 0, j = 3;
 
        // 후위 형
        k = j++;
        System.out.println("k = j++;, k = " + k);
        System.out.println("k = j++;, j = " + j);
        // 다르게 표현 가능
//        k = j;
//        j++;
//        System.out.println("k = j++;, k = " + k);
//        System.out.println("k = j++;, j = " + j);
 
        // 값 초기화
        k = 0;
        j = 3;
 
        // 전위 형
        k = ++j;
        System.out.println("k = ++j;, k = " + k);
        System.out.println("k = ++j;, j = " + j);
        // 다르게 표현 가능
//        ++j;
//        k = j;
//        System.out.println("k = ++j;, k = " + k);
//        System.out.println("k = ++j;, j = " + j);
        
    }
}
cs

 

출력결과

 

 

 

부호 연산자

 '-' 는 피연산자의 부호를 반대로 변경

 '+'는 아무런 일도 하지 않음.

1
2
3
4
5
6
7
8
9
10
11
12
13
package Innovation;
 
class Variable1_4 {
    public static void main(String[] args) {
        int i = -10;
        i = +i;
        System.out.println("i = +i; = " + i);
 
        i = -10;
        i = -i;
        System.out.println("i = -i; = " + i);
    }
}
cs

 

 

행변환 연산자와 자동 형변환

형변환 이란?

 - 변수 또는 상수의 타입을 다른 타입으로 변환하는 것을 의미함.

 - (타입)피연산자

1
2
3
4
5
6
7
8
9
10
11
12
class Operator3_1 {
    public static void main(String[] args) {
        int i = 65, num = 10;
        char ch = 'A';
        float f = 1.6f;
 
        System.out.println("(char)i = " + (char)i);
        System.out.println("(int)ch = " + (int)ch);
        System.out.println("(int)f = " + (int)f);
        System.out.println("(float)num = " + (float)num);
    }
}
cs

 

출력결과

자동 형변환

float f = 1234;  => int 타입의 값을 float타입의 변수에 저장 ( 상대적으로 int 타입이 float 타입보다 크기가 작기 떄문에 가능)

 

float f = (float)1234; => 변수와 리터럴 타입을 일치 시켜줘야함. 위는 자동으로 컴파일러에 의해 형변환 된것임

 

int i = 3.14f; 오류. 큰 타입을 작은 타입에 저장할 때 Error가 발생. 

          3.14f 가 int 타입으로 변환될 때 소수점이 사라지면서 원래 값이 달라짐.

int i = (int)3.14f; => 수동으로 형변환을 시켜줘야함.

 

"기존의 값을 최대한 보존할 수 있는 타입으로 자동 형변환 된다."

  • 형 변환을 하는 이유는 주로 서로 다른 두 타입을 일치시키기 위해서인데, 형변환을 생략 하려면, 컴파일러가 알아서 자동으로 형변환을 해야함
  • 따라서, 표현범위가 좁은 타입에서 넓은 타입으로 형변환하는 경우에는 값 손실이 없음으로 두 타입 중에서 표현 범위가 더 넓은 쪽으로 형변환됨

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Operator3_2 {
    public static void main(String[] args) {
       // 큰 타입을 작은 타입에 저장!
       // int i = 3.14f; // Error 발생
       int i = (int)3.14f; // 형변환 필요!
       System.out.println("i = " + i);
       
        // 예외 경우 확인
        
        // 100 은 int 타입 따라서 아래 코드는 현재 큰 타입(int)을 작은 타입(byte)에 넣고 있음!
        // 컴퓨터는 byte의 범위가 -128 ~ 127 인 것을 알고 있다.
        // 따라서 100을 byte b 에 집어 넣어도 값 손실이 발생하지 않는 다는 것을 알기 때문에
        // 자동으로 형변환을 해준다.
        // byte b = (byte)100; -> 컴파일러가 자동 형변환
        byte b = 100// OK
        System.out.println("b = " + b);
 
        // 위의 경우는 100 은 리터럴 즉, 상수이기 때문에 컴파일러가 값을 명확하게 알지만
        // 아래 num 은 변수, 따라서 확신할 수 없기 때문에 Error 발생
        int num = 100;
        // byte b2 = num; // Error 발생
        byte b2 = (byte) num; // byte 타입으로 형변환
        System.out.println("b2 = " + b2);
 
        //  byte b3 = 1000; // Error 발생, 범위를 넘어감
        byte b3 = (byte1000;
        // OK, 그러나 값 손실 발생, b3 에는 -24 가 저장됨
        // 즉, 상수여도 값 손실이 일어나면 자동 형변환 불가능!
        System.out.println("b3 = " + b3);
    }
}
cs

출력결과

사칙 연산자와 산술변환

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package Innovation;
 
class Variable1_4 {
    public static void main(String[] args) {
        int a = 10, b = 4;
 
        // 덧셈
        System.out.print("a + b = ");
        System.out.println(a + b);
 
        // 뺄셈
        System.out.print("a - b = ");
        System.out.println(a - b);
 
        // 곱셈
        System.out.print("a * b = ");
        System.out.println(a * b);
 
        // 나눗셈
        // 소수점 이하는 버려진다.
        System.out.print("a / b = ");
        System.out.println(a / b);
 
        // 10 / 4.0f -> 10.0f / 4.0f -> 2.5
        System.out.print("a / (float)b = ");
        System.out.println(a / (float)b);
    }
}
cs

 

산술변환

연산 전에 피연산자의 타입을 일치시키는 것을 의미합니다.

 

1. 두 피 연산자의 타입을 같게 일치시킨다. (보다 큰 타입으로 일치)

  •   long + int -> long + long => long
  •   float + int -> float + float => float
  •  double + float => double + double => double

2. 피연산자의 타입이 int 보다 작은 타입이면 int 로 변환 된다

  • byte + short => int + int => int
  • char + short +> int + int => int
  • 이는 int 보다 작은 타입이 계산을 통해 쉽게 범위가 넘어갈 수 있기 때문에, 오버플로우가 발생해 정확한 계산값을 가져오지 못할 수 있어서 미리 큰 범위인 int 타입으로 변환시킨 후 계산하는 것임.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package Innovation;
 
class Variable1_4 {
    public static void main(String[] args) {
        char ch = '2';
 
        // 문자 '2' 는 숫자로 50, '0' 은 48
        // 따라서 int 타입으로 자동으로 변하기 때문에 50 - 48 = 2
        System.out.print("ch - '0' = ");
        System.out.println(ch - '0');
 
        int a = 1_000_000; // 1백만
        int b = 2_000_000; // 2백만
 
        // a * b = 2_000_000_000_000 -> 10^12
        // long 에 저장하려는 것은 맞지만 a * b 의 결과 타입이 int
        // 따라서 이미 계산을 할 때 오버플로우 발생! -> 따라서 계산을 할 때 형변환 필요!
        // long l = a * b; // -1454759936
 
        long l = (long)a * b;
        // long * int -> long * long => 1_000_000L * 2_000_000 -> 1_000_000L * 2_000_000L
        System.out.println("l = " + l);
    }
}
cs

Math 클래스와 나머지 연산자

Math는 수학과 관련된 메서드를 가지고 있는 클래스이다.

메서드는 ' 특정 기능을 수행하기 위해 코드로 작성된 단위'

 

  • round() : 실수를 소수점 첫 째자리에서 반올림한 정수를 반환
  • ceiol() : 올림값을 double 형으로 반환
  • floor() : 내림값을 double 형으로 반환
  • abs() : int, double 기본형 모두 사용 가능하며 절대값을 얻는다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Operator5_1 {
    public static void main(String[] args) {
        long result = Math.round(3.645678);
        System.out.println("result = " + result);
 
        // 소수점 4째 자리에서 반올림한 값을 구하라!
        double pi = 3.141592;
        // pi * 1000 = 3141.592
        // Math.round(3141.592) = 3142
        // 3142 / 1000.0 = 3.142
        double shortPi = Math.round(pi * 1000/ 1000.0;
        System.out.println(shortPi); // 3.142
 
        // 3.141 구하기!
        double pi2 = 3.141592;
        // pi2 * 1000 = 3141.592
        // (int)3141.592
        System.out.println("(int)(pi2 * 1000) = " + (int) (pi2 * 1000));
        System.out.println("(int)(pi2 * 1000) / 1000.0  = " + (int) (pi2 * 1000/ 1000.0);
    }
}
cs

1
2
3
4
5
6
7
8
9
10
class Operator5_2 {
    public static void main(String[] args) {
        double num = 3.14;
        
        System.out.println("반올림 : " + Math.round(num)); // 반올림 : 3
        System.out.println("올림 : " + Math.ceil(num)); // 올림 : 4.0
        System.out.println("내림 : " + Math.floor(num)); // 내림 : 3.0
        System.out.println("절대값 : " + Math.abs(num*-1)); // 절대값 : 3.14
    }
}
cs

나머지 연산자 % 

  • 오른쪽 피연산자로 나누고 남은 나머지를 반환
  • 나누는 피연산자는 0이 아닌 정수만 허용
  • 부호는 무시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Operator5_3 {
    public static void main(String[] args) {
        int x = 10;
        int y = 8;
 
        System.out.print("x를 y로 나눈 몫 = ");
        System.out.println(x / y);
 
        System.out.print("x를 y로 나눈 나머지 = ");
        System.out.println(x % y);
 
        // 부호 무시 확인
        int n = 3;
        int z = -3;
        System.out.println("x % n = " + x % n);
        System.out.println("x % z = " + x % z);
    }
}
cs

 

 

비교연산자

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Operator6_1 {
    public static void main(String[] args) {
        int n1 = 10, n2 = 6;
        char c1 = 'A', c2 = 'B';
 
        System.out.print("n1 >= n2 = " ); // true
        System.out.println(n1 >= n2);
        System.out.print("n1 <= n2 = " ); // false
        System.out.println(n1 <= n2);
 
        System.out.print("n1 == n2 = " ); // false
        System.out.println(n1 == n2);
        System.out.print("n1 != n2 = " ); // true
        System.out.println(n1 != n2);
 
        // 산술변환 규칙에 의해서 char 타입이 int 타입으로 변환되어 연산됨
        System.out.print("c1 < c2 = "); // true
        System.out.println(c1 < c2); // 65 < 66
        System.out.print("c1 > c2 = "); // false
        System.out.println(c1 > c2); // 65 > 66
    }
}
cs

문자열의 비교

문자열 비교에는 == 대신 equals()를 사용해야함.

  • equals : 비교하고자 하는 두 피연산자의 값 자체를 비교함.
  • == : 비교하고자하는 두 피연산자의 주소값을 비교함.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Operator6_2 {
    public static void main(String[] args) {
        String s1 = "사랑";
        String s2 = "사랑";
 
        System.out.print("s1 == s2 = "); // true
        System.out.println(s1 == s2);
        System.out.println("s1.equals(s2) = " + s1.equals(s2)); // true
 
        // 하지만!
        String s3 = new String("사랑");
        System.out.print("s1 == s3 = "); // false
        System.out.println(s1 == s3);
        System.out.println("s1.equals(s3) = " + s1.equals(s3)); // true
    }
}
cs

 

논리 연산자

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Operator7_1 {
    public static void main(String[] args) {
        boolean result1, result2, result3, result4, reusult5, result6;
 
        char ch1 = 'a', ch2 = 'B';  // 'a' : 97 , 'A' : 65, 'B' : 66, 'C' : 67
 
        result1 = ch1 > 'A' && ch2 < 'C';
        result2 = ch1 == 'A' && ch2 < 'C';
 
        result3 = ch1 > 'A' || ch2 < 'C';
        result4 = ch1 < 'A' || ch2 > 'C';
 
        System.out.println("&& 연산자에 의한 결과 result1 = " + result1); // true
        System.out.println("&& 연산자에 의한 결과 result2 = " + result2); // false
 
        System.out.println("|| 연산자에 의한 결과 result3 = " + result3); // true
        System.out.println("|| 연산자에 의한 결과 result4 = " + result4); // false
 
        System.out.println("! 연산자에 의한 결과 result4 = " + !result4); // true
 
        System.out.println();
 
        int num = 10;
        // num 은 2의 배수 그리고 3의 배수이다.
        reusult5 = num % 2 == 0 && num % 3 == 0;
        System.out.println("num 은 2의 배수 그리고 3의 배수 = " + reusult5); // false
 
        // num 은 2의 배수 또는 3의 배수이다.
        result6 = num % 2 == 0 || num % 3 == 0;
        System.out.println("num 은 2의 배수 또는 3의 배수 = " + result6); // true
    }
}
cs

출력결과

 

비트 연산자

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Operator7_2 {
    public static void main(String[] args) {
        int num1 = 8, num2 = -8;
        System.out.println("8의 2진수 = " + Integer.toBinaryString(num1)); // 0 생략 가능!
        System.out.println("-8의 2진수 = " + Integer.toBinaryString(num2));
        System.out.println("-9의 2진수 = " + Integer.toBinaryString(-9)); // 32bit, int = 4byte
 
        // 00000000000000000000000000001000 ,  8
        // 11111111111111111111111111111000 , -8
System.out.println("& 연산자에 의한 결과 = " + (num1 & num2)); // 00000000000000000000000000001000, 8
System.out.println("| 연산자에 의한 결과 = " + (num1 | num2)); // 11111111111111111111111111111000, -8
System.out.println("^ 연산자에 의한 결과 = " + (num1 ^ num2)); // 11111111111111111111111111110000, -16
 
System.out.println("~ 연산자에 의한 결과 = " + ~num1); // 11111111111111111111111111110111, -9
 
        System.out.println("<< 연산자에 의한 결과 = " + (num1 << 2)); // 32
        System.out.println(">> 연산자에 의한 결과 = " + (num2 >> 2)); // -2
 
        System.out.println(">>> 연산자에 의한 결과 = " + (num2 >>> 2)); // 1073741822
    }
}
cs

 

 

2진수의 음수 표현

진수의 음수를 표현하는 방식에는 부호 절대값, 1의 보수,2의 보수가 있다. 

 

부호절대값

  • 가장 왼쪽에 있는 비트를 부호비트라고 했을 때, 이 부호비트가 '0인지 1인지'에 따라 양수 , 음수로 구분된다.

0일때는 양수, 1일때는 음수

  • 2진수 00000011 = 10진수 : 3
  • 2진수 10000011 = 10진수 : -3

1의 보수? ( 0과 1을 서로 반전 시킴.)

-13을 1의 보수로 표현

 1. 13을 2진수로 표현 : 00001101

 2. 11111111 - x 공식에 대입

 3. 11110010

 

2의 보수

  • 2의 보수는 10000000 - x를 하는 방식
  • 2의 보수 역시, 가장 왼쪽 숫자가 0일 경우 양수, 1일 경우 음수로 표현

 

-13을 2의 보수 방식으로 표현

1. 13을 2진수로 표현 : 00001101

2. 1000000 - x 공식에 대입

3. 결과 : 11110011 ( 쉽게 구하기1의 보수를 구한다음, +1 )

 

-9를 2의 보수 방식으로 표현

1. -9를 1의 보수 방식으로 표현 : 00001001 -> 11110110

2. 111101101 + 1

3. 결과 : 111101111

 

조건 연산자

삼항 연산자 : 조건식 ? 반환값 1 : 반환값 2

 

1
2
3
4
5
6
7
8
9
10
class Operator8_1 {
    public static void main(String[] args) {
        int num1 = 5, num2 = 7;
        int result;
 
        result = num1 - num2 > 0 ? num1 : num2;
 
        System.out.println("두 정수 중 더 큰 수는 " + result + "입니다."); // 7
    }
}
cs

대입 연산자

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Operator8_2 {
    public static void main(String[] args) {
        int num1 = 7, num2 = 7, num3 = 7;
 
        num1 = num1 - 3;
        num2 -= 3;
        num3 =- 3;
 
        System.out.println("- 연산자에 의한 결과 : "+ num1); // 4
        System.out.println("-= 연산자에 의한 결과 : "+ num2); // 4
 
        // = 위치를 주의하셔야 합니다.
        // num3 =- 3; 는 num3 = -3 입니다.
        System.out.println("=- 연산자에 의한 결과 : "+ num3); // -3
    }
}
cs

 

반응형