컴퓨터에서 수를 계산하는 개념
컴퓨터는 사람이 읽을 수 있는 수를, 비트로 변환하여 0과 1로 저장한 후 이를 계산합니다.
예를들어 5의 숫자는 컴퓨터는 101 로 변환 후 계산합니다.
컴퓨터는 숫자를 비트로 반환한 후 계산하는 방식이기 때문에,
비트를 이동하는 방식의 시프트 연산 방식이 일반적인 연산보다 빠르게 동작합니다.
시프트 연산자
시프트 연산자는 이렇게 비트로 저장된 0과 1의 수를 왼쪽과 오른쪽으로 한칸씩 미는 방식입니다.
밀면서 새로운 자릿수는 0으로 채워지고, 벗어나는 자릿수는 값이 없어집니다.
왼쪽 시프트 연산 ( x << y )
x 의 값을 y 자리수만큼 왼쪽으로 시프트 합니다.
왼쪽으로 시프트 하던 중에 가장 앞의 자리수가 1이 되면 음수로 변경됩니다.
오른쪽 시프트 연산 ( x >> y )
x 의 값을 y 자리수만큼 오른쪽으로 시프트 합니다.
부호없는 오른쪽 시프트 연산 ( x >>> y )
x 의 값을 y 자리수만큼 오른쪽으로 시프트 합니다. 이 때 부호는 의미가 없습니다.
일반적인 오른쪽 시프트 연산인 경우 가장 앞의 자릿수가 1이면, 오른쪽으로 시프트 되면서 채워지는 값이 1이지만
부호없는 오른쪽 시프트인 경우에는 앞의 자리가 0으로 채워지게 됩니다.
시프트 연산 예제
왼쪽, 오른쪽 시프트 연산
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public class ShiftTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
byte shift=5;
System.out.println(shift);
shift >>= 1;
System.out.println(shift);
shift <<= 1;
System.out.println(shift);
}
}
|
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
28
|
public class ShiftTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
int shift;
shift=-127;
System.out.println(shift);
shift >>= 1;
System.out.println(shift);
shift=-127;
System.out.println(shift);
shift >>>= 1;
System.out.println(shift);
}
}
|
cs |
시프트 연산의 주의점
int 타입보다 작은 정수형 타입은 int 로 변환되어 shift 된다는 점
위에서 작성한 오른쪽 시프트 코드와 똑같지만 변수의 타입만 int 에서 byte 로 바꿔보았습니다.
타입만 바꿨을 뿐인데 결과가 변경되었습니다.
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
|
public class ShiftTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
byte shift;
shift=-127;
System.out.println(shift);
shift >>= 1;
System.out.println(shift);
shift=-127;
System.out.println(shift);
shift >>>= 1;
System.out.println(shift);
}
}
|
cs |
왜?
아래처럼 byte 단위로만 시프트 된다면 부호없는 시프트(>>>)인 경우에는 64 값이 나와야 합니다.
그렇지만 실제로는 -64 값이 나왔습니다.
1
2
3
4
5
|
10000001 // -127
11000000 // >> -64
01000000 // >>> 64
|
cs |
위에서 작성한 것처럼 shift 시에는 int 형으로 변환되어 동작합니다.
즉, 내부적으로 앞의 32비트에는 -127의 값을 맞추기 위해 1의 값이 채워지게 되고
이 값에서 shift 되게 되는 겁니다.
이후에 다시 byte 단위로 마지막 8자리가 계산되어 출력되게 됩니다.
1
2
3
4
5
|
11111111 11111111 11111111 10000000 // -127
11111111 11111111 11111111 11000000 // -64
01111111 11111111 11111111 11000000 // -64
|
cs |
'Computer Language > JAVA' 카테고리의 다른 글
[JAVA] 자바 문자열 일부가 포함되었는지 확인하는 방법 ( contains, indexOf, matches ) (0) | 2020.10.29 |
---|---|
[JAVA] 자바 if 문으로 조건 여러개 사용하기 (if, else if, else) (0) | 2020.10.29 |
[JAVA] 자바 증감연산자의 전위와 후위 계산법 (0) | 2020.10.26 |
[JAVA] 자바 키보드로 문자열 입력받아 출력하는 Scanner 와 BufferedReader 방법 (1) | 2020.10.25 |
[JAVA] 자바 기본형 타입 별 최소 최대 값 범위와 고찰 (0) | 2020.10.25 |