티스토리 뷰

Academy

[210114]연산자

VIRGIL ABLOH 2021. 1. 14. 23:08
반응형

- 자바 언어 기초(com.eomcs.lang)


- ex05 : 연산자 사용법


- 실습 프로젝트 : mini-pms(프로젝트 관리 시스템)


- 3 단계: 변수와 키보드 입력 다루기 (해설)


- 학습 목표 달성 확인 목록


- [] 자바에서 제공하는 연산자를 사용할 수 있는가?

# 연산자 우선 순위
괄호: ()
후위 연산자: a++, a--
전위 연산자: ++a, --a, 단항 연산자(+, -)
*, /, %
+, -
비트이동 연산자: <<, >>, >>>
관계 연산자: <, >, <=, >=, instanceof
등위 연산자: ==, !=
&
^
|
논리 연산자 AND: &&
논리 연산자 OR: ||
삼항 연산자: (조건) ? :
할당 연산자: =, +=, -=, *=, /=, %=, &=, ^=, |=, <<=, >>=, >>>=


- [] 정수 연산에서 최소 연산 단위가 int임을 이해하는가?

byte/short와는 성능차이가 별로없기 때문이다.

(연산하면 암시적 형변환으로 int형으로 변환된다.)


- [] 연산 우선 순위를 이해하는가?

산술 연산자에서는 *,/,%이 +,-보다 먼저 계산하며

사용자가 선택한 식을 먼저 계산하고 싶으면 ()괄호를 이용하여 적용해준다.


- [] 연산은 같은 타입이어야만 수행할 수 있다는 것을 아는가?

int+int = int

float+float = float

두 식을 보듯이 연산 결과는 피연산자의 타입과 같다

그래서 두 값을 계산했을때 결과 메모리를 초과할 경우

값이 짤릴 수 있다!

그래서 계산결과가 크게 나올거 같으면 처음부터 피연산자의 값을 더 큰 메모리에 담아서 연산해야된다.


- [] 연산의 결과는 피연산자의 타입과 같다는 것을 아는가?

int+int = int

float+float = float

double+double = double


- [] 암시적 형변환을 설명할 수 있는가?

정수의 경우 기본단위는 int이다

따라서 int보다 작은 크기의 메모리값을 다룰때는 내부적으로 int로 자동 형변환이되어 연산을 수행한다

이렇게 내부적으로 자동 형변환하는 것을 암시적 형변환이라고 한다.


- [] 명시적 형변환을 사용할 수 있는가?

큰 메모리의 값을 작은 메모리에 넣으려고 형변환을 사용하기도 하는데

다만 형변환하더라도(즉 작은 메모리에 넣더라도) 값이 잘리지 않을 때만 하는것을 추천한다.

한마디로 형변환하더라도 값이 소실되지 않을 때만 명시적 형변환을 하는것을 추천한다.


- [] 부동소수점의 값을 비교할 때 극소수의 값을 고려해야 함을 이해하는가?

컴퓨터가 부동소수점 값을 연산할 때는 IEEE 754 명세에 따라 작업을 수행한다

이 과정에서 값의 왜곡이 발생할 수 있다.이문제는 모든 컴퓨터에서 발생하는 문제이다.

따라서 부동소수점은 비교연산자를 사용하여 비교할 때

극소수값을 처리해주는 코드가 따로 필요하다

 double EPSILON = 0.00001;
 System.out.println(Math.abs((d1 + d2) - (x + y)) < EPSILON);
  1. EPSILON 값을 선언한다.
  2. 각각 연산에서 계산한 값의 오차를 구한다.
  3. Math.abs() 메소드를 사용하여 오차에 절대값을 구한다.
  4. 이 오차의 절대값이 EPSILON보다 작다면 두 결과값을 같은 값으로 취급한다.

- [] 관계 연산자(>, >=, <, <=, ==, !=)를 다룰 수 있는가?

관계 연산자(relational operators: <, <=, >, >=)

등위 연산자(equality operators: ==, !=)

비교결과는 boolean값으로 나온다.


- [] 부동소수점의 값을 비교할 때 주의할 사항이 무엇인가?

부동소수점 값을 연산할 때는 IEEE 754 명세에 따라 작업을 수행하는데

여기서 값의 왜곡이 발생한다.그래서 위의 코드처럼 비교군을 만들어서 비교해준다.


- [] 논리 연산자(&&,||,!,^,&,|)를 다룰 수 있는가?

// AND 연산자
// - 두 개의 논리 값이 모두 true일 때 결과가 true가 된다.

System.out.println(true && true);
System.out.println(true && false);
System.out.println(false && true);
System.out.println(false && false);

//결과
true
false
false
false

 

// OR 연산자
// - 두 개의 논리 값 중 한 개라도 true이면 결과는 true가 된다.

System.out.println(true || true);
System.out.println(true || false);
System.out.println(false || true);
System.out.println(false || false);

//결과
true
true
true
false


// NOT 연산자
// - true false false true로 바꾼다.

System.out.println(!true);
System.out.println(!false);

//결과
false
true


// exclusive-OR(XOR)연산자
// - 배타적 비교 연산자라 부른다.
// - 두 개의 값이 다를 때 true이다.

System.out.println(true ^ true);
System.out.println(false ^ false);
System.out.println(true ^ false);

//결과
false
false
true

 

- [] &&&, ||| 논리 연산자의 차이점을 아는가?

&&,||는 앞의 피연산자의 값으로 결과를 알 수 있다면 뒤의 명령은 실행하지 않는다

&,|는 앞의 피연산자로 결과를 알더라도 뒤의 명령까지 모두 실행한다.


- [] 비트 연산자(&,|,^,~)를 다룰 수 있는가?

AND연산자

자릿수가 서로 1로 일치할때만 1이 되며

그외의 경우엔 모두 0이 된다

(여기서 1이란 참,0이란 거짓으로 봐도 무방하다)

         0   0   1   0   1

AND  0   1   0   1   0

-----------------------

        0   0   0   0   0

 

         0   0   1   0   1

AND  0   1   1   1     1

-----------------------

        0   0   1   0  1

 

OR연산자

이 녀석은 단 하나라도 자리에 1이 있으면 연산되는 해당 자리수의 값을 1로 만든다

or 연산자의 기호는 파이프 기로하 부르는데

엔터 위에 \를 쉬프트와 같이 누르면 된다

    00101

or 01010

----------

    01111

 

    00100

or 01110

----------

    01110

 

    00101

or 01110

----------

    01111

 

XOR연산자

^ 같은 갈매기 표시는 6과 시프트를 같이 누른다

같은 자리에 배치된 값이 서로 다른 경우에만 1이 된다

      00101

xor 01010

-----------

       01111

 

      00100

xor 01 1 10

-----------

       01010

 

not연산자 ~

모든것을 반전한다

단순한 방법:not의 대상이 되는 값 +1을 하고 부호를 반전한다


- [] 비트 연산자로 % 연산을 수행하는 방법을 아는가?

어떤 값에 대해 4로 나눈 나머지 값을 구하고 싶다면,
& 연산자를 이용하여 그 값의 하위 2비트 값만 추출하면 된다.
주의!
=> & 연산자를 사용해서 나머지 값을 구하려면
나누는 값이 2의 제곱수여야 한다.
=> 2의 제곱수로 나눈 나머지 값을 구하는 경우에는
% 대신 비트 연산자 &를 사용하면 계산 속도가 빠르다.


- [] 비트 연산자를 활용하여 특정 값만 추출하는 방법을 아는가?

int data = 0b1111_1001_0111_1111;
System.out.println(Integer.toBinaryString(data & 0b0000_1111_1100_0000));
   1111_1001_0111_1111
 & 0000_1111_1100_0000
 -----------------------
   0000_1001_0100_0000


- [] 비트 연산자를 활용하여 여러 개의 true/false 값을 한 변수에서 다룰 수 있는가?

 

 // 특정 비트의 값을 설정할 때
    // 0x01, 0x02, 0x04, 0x08 처럼 직접 숫자를 사용하면
    // 코드를 읽고 이해하기가 쉽지 않다.
    // 해결책?
    // - 각각의 값을 의미있는 이름을 가진 변수에 저장한 후 사용하라.
    // - 또한 조회용으로 사용할 변수이므로 상수로 선언하라.
    //
    //
    final int CSS           = 0x01; // 0000 0001
    final int HTML          = 0x02; // 0000 0010
    final int PHP           = 0x04; // 0000 0100
    final int PYTHON        = 0x08; // 0000 1000
    final int JAVASCRIPT    = 0x10; // 0001 0000
    final int JAVA          = 0x20; // 0010 0000
    final int CPP           = 0x40; // 0100 0000
    final int C             = 0x80; // 1000 0000

    // Java와 C, C++, JavaScript를 할 줄 아는 개발자의 정보를 설정하라!
    int lang = C | JAVA | PYTHON | HTML;
    //   1000 0000 (C)
    // | 0010 0000 (JAVA)
    // | 0000 1000 (PYTHON)
    // | 0000 0010 (HTML)
    // -------------------
    //   1010 1010
    //

    System.out.println(Integer.toBinaryString(lang));


- [] 비트 이동 연산자(<<, >>, >>>)를 다룰 수 있는가?

연산식 설명
x << y 정수 x의 각 비트를 y만큼 왼쪽으로 이동시킨다. (빈자리는 0으로 채워진다.)
x >> y 정수 x의 각 비트를 y만큼 오른쪽으로 이동시킨다. (빈자리는 정수 a의 최상위 부호비트와 같은 값으로 채워진다.) 
x >>> y 정수 x의 각 비트를 y만큼 오른쪽으로 이동시킨다. (빈자리는 0으로 채워진다.)

2 << 3

16 >> 3

-16 >> 3

-16 >>> 3


- [] 비트 이동 연산자를 사용하여 2의 배수를 곱하고 나누는 방법을 아는가?

<< 1비트 이동은 곱하기 2를 한 것과 같은 효과이다.

int i = 1;
    //      [00000000000000000000000000000001] = 1

    System.out.println(i << 1);
    //     0[0000000000000000000000000000001 ]
    //      [00000000000000000000000000000010] = 2

    System.out.println(i << 2);
    //    00[000000000000000000000000000001  ]
    //      [00000000000000000000000000000100] = 4

    System.out.println(i << 3);
    //   000[00000000000000000000000000001   ]
    //      [00000000000000000000000000001000] = 8

    System.out.println(i << 4);
    //  0000[0000000000000000000000000001    ]
    //      [00000000000000000000000000010000] = 16

    i = 11; // [00000000000000000000000000001011]
    System.out.println(i << 1); //   0[00000000000000000000000000010110] => 22
    System.out.println(i << 2); //  00[00000000000000000000000000101100] => 44
    System.out.println(i << 3); // 000[00000000000000000000000001011000] => 88

 

>>1비트 이동은 나누기 2 한 것과 같은 효과이다.

int i = 105; // [00000000000000000000000001101001]

    System.out.println(i); //                   => 105

    System.out.println(i >> 1);
    // [ 0000000000000000000000000110100]1
    // [00000000000000000000000000110100]       => 52

    System.out.println(i >> 2);
    // [  000000000000000000000000011010]01
    // [00000000000000000000000000011010]       => 26

    System.out.println(i >> 3);
    // [   00000000000000000000000001101]001
    // [00000000000000000000000000001101]       => 13

    System.out.println(i >> 4);
    // [    0000000000000000000000000110]1001
    // [00000000000000000000000000000110]       => 6


- [] 조건 연산자(?:)를 다룰 수 있는가?

// 조건연산자
    // => 조건 ? 표현식1 : 표현식2
    // => 조건이 참이면 표현식1을 실행하고,
    //    조건이 거짓이면 표현식2를 실행한다.
    int age = 20;
   
    String message = (age > 18) ? "성년" : "미성년";
    System.out.printf("나이 %d는(은) %s이다.\n", age, message);
    
    //결과
나이 20는(은) 성년이다.


- [] ++/-- 후위 연산자 및 전위 연산자를 다룰 수 있는가?

int i = 1;
System.out.println(i);//1
i++;
System.out.println(i);//2
++i;
System.out.println(i);//3

 

쉽게 설명하면 변수가 부호를 앞으로 지나가는가 뒤로지나가는가에 따라 값이 달라진다.

 

- [] 복합 할당 연산자(+=, -=, *=, /=, %= )를 다룰 수 있는가?

int i = 1;
i+=1;

int j = 2;
j*=2;

i는 1씩 더해서 축적된다.1->2->3...

j는 2씩 곱해서 축적된다.2->4->8...

반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2026/06   »
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
글 보관함