'쉬프트 연산자'에 해당되는 글 1건

  1. 2007.07.18 연산자의 우선 순위 (2)

3. 산술연산자
산술연산자는 말그대로, 산술하는 연산자로, 우리가 수학에서 흔히 쓰는, +, -, /, %, * 등이 이에 해당한다.
1//    class Exam05_04 {
2//        public static void main(String[] args) {
3//           byte a = 10;
4//           byte b = 20;
5//           byte c = a + b;         // 에러
6//           short d = a + b;         // 에러
7//           int e = a + b;
8//
9//           long f = 10L;
10//           int g = 10;
11//           int h = f + g;         // 에러
12//           long i = f + g;
13//
14//           float j = 10.3f;
15//           long k = 10L;
16//           float l = j + k;
17//        }
18//    }
위 의 코드는 몇가지 산술 연산을 적용시킨 코드이다. 뎃셈이나, 뺄셈, 혹은 곱셈, 나눗셈 등의 연산을 모르는 이도, 없고, 나머지 구하는 것도 모르는 이가 없으니, 이에 대한 설명은 넘기고, 그것보다도 자료형이라는 것에서 오는 약간은 헷갈리는 몇가지가 있다.

3번째 라인 ~ 7번째 라인
: 3번째 라인과 4번째 라인은, byte 형으로 변수를 선언, 값을 저장시켰다. 그런데, byte 형으로 저장된 값을, 서로 산술연산을 시키면 어떻게 될까? 그에 대한 해답은, 5번째 라인에서 보듯이 에러가 발생하게 된다.

기본적으로 자바에서는 int 라는 자료형보다 낮은 자료형이 산술 연산을 할때는, 자동적으로 int 형으로 변환되어 연산이 되고, 따라서, 값은, int 형으로 저장이 되어야 한다. short 라는 자료형도, int 형이라는 자료형보다는, 낮은 자료형이기에, 6번째 라인도 에러가 발생하며, 이렇기에, 7번째 라인처럼, int 형의 연산값을 저장할 변수를 선언, 저장해주어야 한다.

9번째 라인 ~ 12번째 라인
: 그렇다면, 이 반대의 상황은 어떨까? int 형보다 큰 자료형과 int 형의 산술 연산은, 당연히, 큰 자료형을 따라가 연산이 되고, 그렇기에, 저장될 변수도, 큰 자료형으로 선언을 해주어야 한다. 11번째 라인은, int 형과 long형의 연산을 int형에다가 저장하려고 하니까 에러가 발생했다. 12번째 라인처럼, long 형으로 변수를 선언, 저장시켜야 한다.

14번째 라인 ~ 16번째 라인
: 실수형과 정수형의 계산도 마찬가지다. 실수형이 무조건, 정수형보다 크기때문에, 실수형과 정수형의 연산에서, 실수형으로 변수를 선언, 저장해주어야 한다. 16번째 라인이, 그렇게 한 경우이다.


4. 쉬프트 연산자
쉬프트 연산자를 비트를 이용한 연산으로, 값을 비트로 변환하여, 계산한후, 다시 값으로 변환시켜주는 과정을 지니고 있다. <<, >>, >>> 등이 있다.

1//    class Exam05_05 {
2//        public static void main(String[] args) {
3//           int i = 1 << 3;
4//           int j = 8 >> 3;
5//
6//           System.out.println("I = " + i);
7//           System.out.println("J = " + j);
8//
9//           int k = -9 >>> 3;
10//           System.out.println("K = " + k);
11//        }
12//    }

위 코드는 쉬프트 연산자를 사용한 코드이다. << 의 의미는 연산할 2진 비트를 왼쪽으로 해당 비트만큼 이동시키라는 이야기다. >> 의 의미는 오른쪽으로 이동시키라는 이야기며, >>> 역시, 오른쪽으로 이동시키라는 의미를 기본적으로 가지고 있다.

3번째 라인
: 1 바이트만으로 놓고 봤을때(실제로 위의 예제는 4바이트), 3번째 라인에서, 1에 해당하는 2진 비트는 다음과 같다.
0000 0001
이 비트를 왼쪽으로 3비트 만큼 이동시키라는 의미가 << 에 들어 있으며, 이렇게 되면 다음과 같이 비트가 변하게 된다.
0000 1XXX
이동한 후에는, 1뒤에 남은 자리가 존재하게 되는데, 이곳에다가는, 0이라는 비트를 채워주게 되고, 이렇게 되면, 다음과 같은 결과가 된다.
0000 1000
이는 결국 8이 되고, 6번째 라인에서의 출력은 8이 된다. 여기에 해당되는 공식은 다음과 같다.
연산할 값 * (2의 이동시킬 비트 수제곱)
3번째 라인을 예로 들면, 1*2의 3제곱 = 1 * 8 = 8 이 된다.

4번째 라인
: 역시 1 바이트만으로 놓고 봤을때, 8에 해당되는 2진 비트는 다음과 같다.
0000 1000
여기서 >> 에 의해, 오른쪽으로 3비트를 이동시키면, 다음과 같다.
XXX0 0001
이동한 후, 여기에서도, 남는 자리가 존재하게 되는데, 이때는 3번째 라인과는 달리, XXX 라는 자리는 원래의 수가 가지는 비트중 최상위 비트에 따라 달라지게 되어있다.
0000 1000   // 최상위 비트가 0   ☞   0000 0001 // 이런식으로 변환

1000 1000   // 최상위 비트가 1   ☞   1111 0001 // 이런식으로 최상위 비트에 따라 달라진다.
여기서 착각하지 말아야 할 부분은, 지금 예로 든 것이 1바이트 안에서 예를 든 것이지, 실제 int 형은 4바이트이므로, 실제 확인을 할때는 이 점을 고려해야 한다. 아무튼 여기서도 공식이 존재한다.
연산할 값 * (1 / 2의 이동 시킬 비트 수제곱)
4번째 라인을 예로 들면, 8 * 1 / 2의 3제곱 = 8 * 1/8 = 1 이 된다.

고로, 7번째 라인은 1이 출력된다.

9번째 라인
: 여기서 사용된 >>> 는 >> 과 마찬가지로 우측으로 비트를 이동하는 것인데, 다만 차이점은, 최상위 비트에 의해 좌우가 되없던 남은 자리의 비트가, 여기서는 그런것에 상관없이 무조건 0으로 집어넣는다.

9번째 라인은, int 형 4바이트의 음수 이므로 다음과 같이 표현이 된다.
1111 1111 1111 1111 1111 1111 1111 0111
여기서 3비트를 >>> 연산 시키면 다음과 같이 바뀌게 된다.
0001 1111 1111 1111 1111 1111 1111 1110
답은,  536870910 (ㅡ.ㅡ)이 된다. >>> 연산은 따로 공식이 존재하지 않으므로, 이런 부분이 나온다면, 계산기를 두들겨야 하...는 건가.. -0-

참고로, 이러한 쉬프트 연산자 역시, 산술 연산자처럼 int 형보다 작은 자료형으로 연산시에는 int 형으로 변환되어 연산이 되어, 저장이 되므로, 저장 역시, int 형 변수로 선언해주어야 한다.


p.s 위의 글들은, 김승현 강사님열혈강의 Java Programming 의 Round 5-3, 동영상 강좌에 기초한 내용입니다.
:

BLOG main image
아무거나 공부하자!!! by Young79

공지사항

카테고리

분류 전체보기 (79)
Programing (29)
English (31)
Graphic (4)
Saying on T"We"tter (15)

최근에 올라온 글

최근에 달린 댓글

글 보관함

달력

«   2024/05   »
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
Total :
Today : Yesterday :