비트 연산자는 정수타입의 데이터를 2진수로 계산하는 연산자이다. ( ※ 우리가 평소 사용하는 숫자는 10진수이다. )
컴퓨터는 모든 정보를 2진수로 표현하는데, 2진수는 1과 0으로만 표현된다.
이때 1이나 0을 비트(bit) 라고 한다. 그리고 비트가 8 개가 모인 것을 바이트(byte) 라고 한다.
즉, 1byte = 8 bit
바이트(byte) 는 의미 있는 정보 하나를 표현하는 최소단위이다.
그럼 우리가 사용하는 숫자 10진수를 컴퓨터가 받아들일 수 있는 2진수로 표현할 수는 없을까?
표현할 수 있다.
다음은 10진수인 숫자 20을 2진수로 표현하는 과정이다.

위의 결과로 나온 2진수 10100을 표현할 때 의미있는 최소단위 1byte(8bit)로 아래와같이 표현한다.

위처럼 10100 은 5비트 이므로 1바이트(8비트) 를 채우기 위해 나머지 3비트는 0으로 채운다.
이때 맨 앞 첫번째 비트는 부호를 나타내는데, 0이면 양수, 1이면 음수 이다.
양수의 비트값을 변환하여 음수로 나타낼 수 있다.
아래의 예시를 보자.

양수의 이진수를 음수로 변환하는 방법
1. 0을 1로, 1을 0으로 뒤집는다.
2. 1을 더한다.
결과 : 이진수 00010100 의 음수값은 11101100 이다.
이렇게 구한 음수의 이진수를 아래와같이 직접 적용해보았다.

분명히 변환한 음수의 이진수 11101011 을 변수 b 에 초기화 했는데
오른쪽 console창을 보면 -20 이 아닌 235라는 값이 출력되었다.
어떻게 된 일일까?
이유는 다음과같다.
int 타입은 4byte의 저장공간을 가진다.
4byte는 32비트이며, 이진수는 32비트를 꽉 채운다.
숫자 한 개당 1비트 이다.
예를들어,
int a = 0b00010100; 은 1바이트 로만 표현한 것이며, 이것은 사실
int a = 0b00000000000000000000000000010100; 이다. (0b 뒤로 총32개의숫자 = 32비트)
그런데 int a = 0b00010100; 으로만 표현해도 20이라는 수가 정상 출력되는 이유는,
00010100 앞에 남은 24개의 비트공간에 0이 자동으로 채워지기 때문이다.
하지만 음수의 경우를 생각해보자.
사실 우리가 1바이트짜리의 이진수를 음수변환하면서 0은 1로, 1은 0으로 바꿀때
남은 3바이트를 채우는 24개의 0들도 전부 1로 바꿔준것이다.
그런데 int a = 0b11101011; 로만 저장한다면, 이것은 앞에있는 24비트가 모두 0으로 저장되어
음수가 아닌 그냥 이진수 int a = 0b00000000000000000000000011101011; 한 값이 나오는것이다.
음수의 값이 정상적으로 출력되게 하기 위해서는
int a = 0b11111111111111111111111111101100; 으로 표현해야한다.
따라서 음수로 출력하려면 아래와 같이 작성해야한다.

int 타입 변수 b를 음수의 형태인 011111111111111111111111111101100; 으로 초기화하여
콘솔창에 b = -20 이 정상 출력 된 모습이다.
이제 비트연산자 에 대해 알아볼 것이다.
비트 연산이라는 것은 비트 단위로 연산한다는 뜻으로, 2진수 표현 방법만 안다면 어렵지 않다.
지금부터 알아볼 비트연산자는 AND연산자, OR연산자, NOT연산자 그리고 XOR연산자이다.
그런데 앞의 논리연산자 에서 봤던 낯익은 연산자들도 보인다.
AND,OR,NOT 이것들을 비트 논리 연산자라고 하는데, 비트 논리 연산자는 논리연산자와는 다르게 결과가 true, false로만 나오지는 않는다.
비트 논리 연산자 AND : &
비트단위로 AND연산을 한다.
둘 다 1일 때 결과가 1이고, 하나라도 1이 아니면 결과가 0이다.
(논리연산자의 조건식이 전부 true일 때 true를 반환했던 점과 의미적으로 흡사하다.)
다음은 00001101 과 00011011 을 AND 연산한 결과이다.

Integer.toBinaryString() 은 십진수를 이진수로 변환해주는 static함수이다.
그냥 이진수의 값을 출력하면 실행시 십진수로 자동 변환되어 출력된다.
이진수로 출력하고싶다면 메서드를 사용해야한다.
어떤 과정을 거쳐 도출 된 결과일까?
& 연산은 둘다 1일때만 1이다.
0 0 0 0 1 1 0 1
0 0 0 1 1 0 1 1
↓
0 0 0 0 1 0 0 1
위의 연산 과정을 거쳐 00001001 이 도출된다.
비트 논리 연산자 OR : |
비트단위로 OR 연산을 한다.
둘중 하나라도 1이면 결과가 1이다. 둘다 0일때만 결과가 0이다.
(논리연산자의 조건식중 하나라도 true이면 true를 반환했던 점과 의미적으로 흡사하다.)
다음은 00001001 과 00011011 을 OR 연산한 결과이다.

| 연산은 둘 중 하나만 1이어도 1이고, 둘다 0 일때만 0이다.
0 0 0 0 1 0 0 1
0 0 0 1 1 0 1 1
↓
0 0 0 1 1 0 1 1
위의 연산 과정을 거쳐 00011011 이 도출된다.
비트 부정 연산자 NOT : ~
비트 부정 연산자 라고 합니다.
~ 연산자는 ( ~ 는 '틸드' 라고 부른다 ) 비트값이 1이면 0으로, 0이면 1로 변환한다.
(논리연산자에서 true이면 false를 반환하고 false이면 true를 반환했던 점과 의미적으로 흡사하다.)
다음은 00011011을 비트 부정 연산 한 결과이다.

이진수 00011011 을 비트 부정 연산 했더니 11111111111111111111111100011011 이라는 결과가 도출되었다.
이진수 00011011 은 사실 앞에 보이지않는 24비트의 자리에 0이 채워진 형태이다.
그렇기 때문에 부정 연산 시 앞의 24개의 0이 1로 변환되어 출력되는것이다.
~ 연산은 1은 0이 되고 0은 1이 된다.
0 0 0 1 1 0 1 1
↓
1 1 1 0 0 1 0 0
위의 연산 과정을 거쳐 11100100 이 도출된다.
비트 연산자 XOR : ^
^ 연산자는 ( ^ 는 '캐럿' 이라고 부른다 ) 비트값이 서로 다를때 결과가 1이다.
다음은 서로 다른 이진수 00010011 과 00001010 을 XOR 연산 한 예시이다.

^ 연산은 서로 다른 비트값일 때 1이 된다.
0 0 0 1 0 0 1 1
0 0 0 0 1 0 1 0
↓
0 0 0 1 1 0 0 1
위의 연산 과정을 거쳐 00011001 이 도출된다.
비트 이동 연산자 : <<, >>, >>>
시프트(shift) 연산자라고도 한다.
시프트 연산자는 비트의 위치를 이동시키는 연산자이다.
표로 정리하면 다음과 같다.
Shift 연산자 | 내용 |
<< | 왼쪽으로 비트 이동 후 이동된 곳은 0으로 채운다. |
>> | 오른쪽으로 비트 이동 후 이동된 곳은 해당 부호비트로 채운다 |
>>> | 오른쪽으로 비트 이동 후 이동된 곳은 무조건 0으로 채운다. |
비트 이동 연산을 하면 이동 연산 후, 값은 어떻게 변할까?
<< 의 경우
00000001 을 왼쪽으로 1만큼 비트이동 한다고 가정하자.

0000001 은 십진수로 1 이다.
<< 시프트 연산 1만큼 한다면 ( 왼쪽으로 한 번 이동한다는 의미 )
0000010 은 십진수로 2 이다.
<< 시프트 연산을 2만큼 한다면 ( 왼쪽으로 두번 이동한다는 의미 )
0000100 은 십진수로 4 이다.
<< 시프트 연산을 n 번 하면 값은 2의 n승 만큼 곱해진다는 것을 알 수 있다.
>> 의 경우
00000001 을 오른쪽으로 1만큼 비트이동 한다고 가정하자.

여러번 시프트 연산하기 위해서 이진수 00001000 을 시프트연산하겠다.
00001000 은 십진수로 8 이다.
>> 시프트 연산 1만큼 한다면 ( 오른쪽으로 한 번 이동한다는 의미 )
00000100 은 십진수로 4 이다.
>> 시프트 연산 2만큼 한다면 ( 오른쪽으로 두 번 이동한다는 의미 )
00000010 은 십진수로 2 이다.
>> 시프트 연산을 n 번 하면 값은 2의 n승 만큼 나눗셈 된다는 것을 알 수 있다.
'Java' 카테고리의 다른 글
조건문 if~else 와 switch~case (0) | 2020.06.18 |
---|
비트 연산자는 정수타입의 데이터를 2진수로 계산하는 연산자이다. ( ※ 우리가 평소 사용하는 숫자는 10진수이다. )
컴퓨터는 모든 정보를 2진수로 표현하는데, 2진수는 1과 0으로만 표현된다.
이때 1이나 0을 비트(bit) 라고 한다. 그리고 비트가 8 개가 모인 것을 바이트(byte) 라고 한다.
즉, 1byte = 8 bit
바이트(byte) 는 의미 있는 정보 하나를 표현하는 최소단위이다.
그럼 우리가 사용하는 숫자 10진수를 컴퓨터가 받아들일 수 있는 2진수로 표현할 수는 없을까?
표현할 수 있다.
다음은 10진수인 숫자 20을 2진수로 표현하는 과정이다.

위의 결과로 나온 2진수 10100을 표현할 때 의미있는 최소단위 1byte(8bit)로 아래와같이 표현한다.

위처럼 10100 은 5비트 이므로 1바이트(8비트) 를 채우기 위해 나머지 3비트는 0으로 채운다.
이때 맨 앞 첫번째 비트는 부호를 나타내는데, 0이면 양수, 1이면 음수 이다.
양수의 비트값을 변환하여 음수로 나타낼 수 있다.
아래의 예시를 보자.

양수의 이진수를 음수로 변환하는 방법
1. 0을 1로, 1을 0으로 뒤집는다.
2. 1을 더한다.
결과 : 이진수 00010100 의 음수값은 11101100 이다.
이렇게 구한 음수의 이진수를 아래와같이 직접 적용해보았다.

분명히 변환한 음수의 이진수 11101011 을 변수 b 에 초기화 했는데
오른쪽 console창을 보면 -20 이 아닌 235라는 값이 출력되었다.
어떻게 된 일일까?
이유는 다음과같다.
int 타입은 4byte의 저장공간을 가진다.
4byte는 32비트이며, 이진수는 32비트를 꽉 채운다.
숫자 한 개당 1비트 이다.
예를들어,
int a = 0b00010100; 은 1바이트 로만 표현한 것이며, 이것은 사실
int a = 0b00000000000000000000000000010100; 이다. (0b 뒤로 총32개의숫자 = 32비트)
그런데 int a = 0b00010100; 으로만 표현해도 20이라는 수가 정상 출력되는 이유는,
00010100 앞에 남은 24개의 비트공간에 0이 자동으로 채워지기 때문이다.
하지만 음수의 경우를 생각해보자.
사실 우리가 1바이트짜리의 이진수를 음수변환하면서 0은 1로, 1은 0으로 바꿀때
남은 3바이트를 채우는 24개의 0들도 전부 1로 바꿔준것이다.
그런데 int a = 0b11101011; 로만 저장한다면, 이것은 앞에있는 24비트가 모두 0으로 저장되어
음수가 아닌 그냥 이진수 int a = 0b00000000000000000000000011101011; 한 값이 나오는것이다.
음수의 값이 정상적으로 출력되게 하기 위해서는
int a = 0b11111111111111111111111111101100; 으로 표현해야한다.
따라서 음수로 출력하려면 아래와 같이 작성해야한다.

int 타입 변수 b를 음수의 형태인 011111111111111111111111111101100; 으로 초기화하여
콘솔창에 b = -20 이 정상 출력 된 모습이다.
이제 비트연산자 에 대해 알아볼 것이다.
비트 연산이라는 것은 비트 단위로 연산한다는 뜻으로, 2진수 표현 방법만 안다면 어렵지 않다.
지금부터 알아볼 비트연산자는 AND연산자, OR연산자, NOT연산자 그리고 XOR연산자이다.
그런데 앞의 논리연산자 에서 봤던 낯익은 연산자들도 보인다.
AND,OR,NOT 이것들을 비트 논리 연산자라고 하는데, 비트 논리 연산자는 논리연산자와는 다르게 결과가 true, false로만 나오지는 않는다.
비트 논리 연산자 AND : &
비트단위로 AND연산을 한다.
둘 다 1일 때 결과가 1이고, 하나라도 1이 아니면 결과가 0이다.
(논리연산자의 조건식이 전부 true일 때 true를 반환했던 점과 의미적으로 흡사하다.)
다음은 00001101 과 00011011 을 AND 연산한 결과이다.

Integer.toBinaryString() 은 십진수를 이진수로 변환해주는 static함수이다.
그냥 이진수의 값을 출력하면 실행시 십진수로 자동 변환되어 출력된다.
이진수로 출력하고싶다면 메서드를 사용해야한다.
어떤 과정을 거쳐 도출 된 결과일까?
& 연산은 둘다 1일때만 1이다.
0 0 0 0 1 1 0 1
0 0 0 1 1 0 1 1
↓
0 0 0 0 1 0 0 1
위의 연산 과정을 거쳐 00001001 이 도출된다.
비트 논리 연산자 OR : |
비트단위로 OR 연산을 한다.
둘중 하나라도 1이면 결과가 1이다. 둘다 0일때만 결과가 0이다.
(논리연산자의 조건식중 하나라도 true이면 true를 반환했던 점과 의미적으로 흡사하다.)
다음은 00001001 과 00011011 을 OR 연산한 결과이다.

| 연산은 둘 중 하나만 1이어도 1이고, 둘다 0 일때만 0이다.
0 0 0 0 1 0 0 1
0 0 0 1 1 0 1 1
↓
0 0 0 1 1 0 1 1
위의 연산 과정을 거쳐 00011011 이 도출된다.
비트 부정 연산자 NOT : ~
비트 부정 연산자 라고 합니다.
~ 연산자는 ( ~ 는 '틸드' 라고 부른다 ) 비트값이 1이면 0으로, 0이면 1로 변환한다.
(논리연산자에서 true이면 false를 반환하고 false이면 true를 반환했던 점과 의미적으로 흡사하다.)
다음은 00011011을 비트 부정 연산 한 결과이다.

이진수 00011011 을 비트 부정 연산 했더니 11111111111111111111111100011011 이라는 결과가 도출되었다.
이진수 00011011 은 사실 앞에 보이지않는 24비트의 자리에 0이 채워진 형태이다.
그렇기 때문에 부정 연산 시 앞의 24개의 0이 1로 변환되어 출력되는것이다.
~ 연산은 1은 0이 되고 0은 1이 된다.
0 0 0 1 1 0 1 1
↓
1 1 1 0 0 1 0 0
위의 연산 과정을 거쳐 11100100 이 도출된다.
비트 연산자 XOR : ^
^ 연산자는 ( ^ 는 '캐럿' 이라고 부른다 ) 비트값이 서로 다를때 결과가 1이다.
다음은 서로 다른 이진수 00010011 과 00001010 을 XOR 연산 한 예시이다.

^ 연산은 서로 다른 비트값일 때 1이 된다.
0 0 0 1 0 0 1 1
0 0 0 0 1 0 1 0
↓
0 0 0 1 1 0 0 1
위의 연산 과정을 거쳐 00011001 이 도출된다.
비트 이동 연산자 : <<, >>, >>>
시프트(shift) 연산자라고도 한다.
시프트 연산자는 비트의 위치를 이동시키는 연산자이다.
표로 정리하면 다음과 같다.
Shift 연산자 | 내용 |
<< | 왼쪽으로 비트 이동 후 이동된 곳은 0으로 채운다. |
>> | 오른쪽으로 비트 이동 후 이동된 곳은 해당 부호비트로 채운다 |
>>> | 오른쪽으로 비트 이동 후 이동된 곳은 무조건 0으로 채운다. |
비트 이동 연산을 하면 이동 연산 후, 값은 어떻게 변할까?
<< 의 경우
00000001 을 왼쪽으로 1만큼 비트이동 한다고 가정하자.

0000001 은 십진수로 1 이다.
<< 시프트 연산 1만큼 한다면 ( 왼쪽으로 한 번 이동한다는 의미 )
0000010 은 십진수로 2 이다.
<< 시프트 연산을 2만큼 한다면 ( 왼쪽으로 두번 이동한다는 의미 )
0000100 은 십진수로 4 이다.
<< 시프트 연산을 n 번 하면 값은 2의 n승 만큼 곱해진다는 것을 알 수 있다.
>> 의 경우
00000001 을 오른쪽으로 1만큼 비트이동 한다고 가정하자.

여러번 시프트 연산하기 위해서 이진수 00001000 을 시프트연산하겠다.
00001000 은 십진수로 8 이다.
>> 시프트 연산 1만큼 한다면 ( 오른쪽으로 한 번 이동한다는 의미 )
00000100 은 십진수로 4 이다.
>> 시프트 연산 2만큼 한다면 ( 오른쪽으로 두 번 이동한다는 의미 )
00000010 은 십진수로 2 이다.
>> 시프트 연산을 n 번 하면 값은 2의 n승 만큼 나눗셈 된다는 것을 알 수 있다.
'Java' 카테고리의 다른 글
조건문 if~else 와 switch~case (0) | 2020.06.18 |
---|