Thứ Ba, 14 tháng 5, 2019

[아두이노 강좌] 54. Bit 연산 (3) - ^(XOR) : 네이버 블로그

xor 연산 진리표,xor 연산 복호화,xor 연산 c,xor 연산,xor 연산 java,xor 연산 계산기,xor 연산 특징,xor 연산 기호,xor 연산 활용,xor 연산 프로그램,

xor 연산 진리표,xor 연산 복호화,xor 연산 c,xor 연산,xor 연산 java,xor 연산 계산기,xor 연산 특징,xor 연산 기호,xor 연산 활용,xor 연산 프로그램,

[아두이노 강좌] 54. Bit 연산 (3) - ^(XOR)

xor 연산 진리표,xor 연산 복호화,xor 연산 c,xor 연산,xor 연산 java,xor 연산 계산기,xor 연산 특징,xor 연산 기호,xor 연산 활용,xor 연산 프로그램,

2017. 9. 1. 19:40

이웃추가

이번엔 ^(XOR) 연산에 대해 알아보자. 

xor 연산 진리표,xor 연산 복호화,xor 연산 c,xor 연산,xor 연산 java,xor 연산 계산기,xor 연산 특징,xor 연산 기호,xor 연산 활용,xor 연산 프로그램,
비트 연산의 종류


지난 포스팅에서 알아봤던 &(AND) 연산과 |(OR) 연산에 대한 내용은 아래 링크를 참조.

^(XOR) 연산

'^(XOR)' 연산은 "엑스-오아ㄹ(ㄹ은 따로 써줘야 하는 발음)"이라고 쉽게 발음하기도 하지만 정식 명칭은 "Exclusive OR(익스클루시브 오아ㄹ)" 이다. 그래서 예전 회로책에서는 'EOR'라 하기도 한다.

^(XOR) 연산은 대응되는 두 비트가 같을 때, 즉 둘 다 '0'의 값을 가지거나 둘 다 '1'의 값을 가질 때 결과 값이 '0'이 되고, 두 비트가 서로 다를 때 결과 값이 '1'이 된다. 

xor 연산 진리표,xor 연산 복호화,xor 연산 c,xor 연산,xor 연산 java,xor 연산 계산기,xor 연산 특징,xor 연산 기호,xor 연산 활용,xor 연산 프로그램,
^(XOR) 연산 결과


예를 들어보자. 숫자 '100'과 '200'을 ^(XOR) 연산 하면 아래와 같은 결과가 나온다.

xor 연산 진리표,xor 연산 복호화,xor 연산 c,xor 연산,xor 연산 java,xor 연산 계산기,xor 연산 특징,xor 연산 기호,xor 연산 활용,xor 연산 프로그램,
100 ^ 200 = 172


이제 비트 별로 연산된다는 것이 무슨 뜻인지는 설명 안해도 알테고, 여기서 두 비트가 서로 다른 곳만 결과가 '1'이라는 것을 기억하자.


하나 더 예를 들어볼까? 항상 예로 들던 거.

xor 연산 진리표,xor 연산 복호화,xor 연산 c,xor 연산,xor 연산 java,xor 연산 계산기,xor 연산 특징,xor 연산 기호,xor 연산 활용,xor 연산 프로그램,
100 ^ 240 = 148

왜인지는 모르겠지만 여기서 특이한 점을 찾아야겠다는 느낌적인 느낌. 찾으셨나요?


함께 연산되는 2진수 '11110000'의 비트 값이 '1'인 곳과 '0'인 곳의 차이를 보자. '0'인 곳은 '100'의 비트가 그대로 결과로 나오고, '1'인 곳은 비트가 반대로 나온다. 즉, '0'은 '1'로 바뀌고, '1'은 '0'으로 바뀐다.

그럼 전부 '1'과 ^(XOR) 연산하면?

xor 연산 진리표,xor 연산 복호화,xor 연산 c,xor 연산,xor 연산 java,xor 연산 계산기,xor 연산 특징,xor 연산 기호,xor 연산 활용,xor 연산 프로그램,
100 ^ 255 = 155


전체 비트가 반대로 바뀌는 것을 볼 수 있다. 이것을 '반전'이라고 하며, '~(NOT) 연산'과 같은 기능을 한다. ~(NOT) 연산은 다음 포스팅 주제.

^(XOR) 연산의 사용 예

1. Toggle

^(XOR) 연산이 가장 많이 사용될 때는 Toggle 기능을 만들 때이다. 

|(OR) 연산에서 예로 들었던 비트 플래그를 생각해보자.

#define LED_FLAG 0x01 // 00000001 #define MOTOR_FLAG 0x02 // 00000010 #define BUZZER_FLAG 0x04 // 00000100 byte sensorState = 0;


버튼을 한번 누르면 LED가 켜지고, 한번 더 누르면 꺼지는 것을 반복하는 동작을 구현한다고 하면,  sensroState의 LED_FLAG가 현재 '0'인지, '1'인지 확인해서 값을 넣어줄 필요 없이 ^(XOR) 연산으로 간단하게 구현할 수 있다. 

void swInterrupt() { sensorState = sensorState ^ LED_FLAG; }

원하는 비트의 값을 반전시켜 주니까.


2. Parity Bit

또 한 가지, ^(XOR) 연산은 주로 기기 간의 통신 오류를 검출할 때 자주 사용된다.

어떤 통신 방법이던지 간에 , 모든 통신에는 오류 또는 누락이 발생할 수 있다. 중간에 하나의 비트가 누락될 수도 있고, 노이즈 등의 이유로 '0'인 신호가 '1'로 읽혀져 수신될 수도 있다. 그래서 데이터 통신에는 '오류 검출' 단계가 포함되는 경우가 많은데, 대표적인 예로 ^(XOR) 연산을 이용한 '패리티 비트'를 추가하는 방법이다. 

패리티 비트는 '홀수 패리티 비트(Odd Parity Bit)'와 '짝수 패리티 비트(Even Parity Bit)'가 있는데, ^(XOR) 연산을 사용하는 것은 '홀수 패리티' 방법으로, '1'의 개수가 홀수일 때 패리티 비트는 '1', 짝수 일 때 패리티 비트가 '0'이 되는 방법이다. 

총 8비트의 데이터 중에서 상위 7비트는 데이터로, 하위 1비트는 홀수 패리티 비트로 구성된다고 정해졌을 때, 7비트 데이터 중 '1'인 비트가 홀수이면 최하위 비트는 '1', 짝수면 '0'이 되는 것이다. 

다음은 '100'이라는 7비트 값에 패리티 비트를 붙인 예이다.

xor 연산 진리표,xor 연산 복호화,xor 연산 c,xor 연산,xor 연산 java,xor 연산 계산기,xor 연산 특징,xor 연산 기호,xor 연산 활용,xor 연산 프로그램,
홀수 패리티 비트 생성 예

'100'은 2진수로 '1100100(7비트)'이므로, '1'의 개수가 3개라 패리티 비트는 '1'이 된다. 사람이야 눈으로 '1'이 몇개인지 세면 되지만, 컴퓨터는 눈으로 못 센다. 카운트 변수를 이용해서 '1'일 때마다 1씩 증가하고, 결국 최종 합이 짝수인지 홀수인지 계산해도 되지만, ^(XOR) 연산을 이용하면 훨씬 쉽게 패리티 비트를 구할 수 있다. 모든 비트를 ^(XOR) 연산하면 됨.

소스 코드로 구현해보자. 

byte data = 100; byte parity = 0; for (int i=0; i<7; i++) { if (data & (0x40 >> i)) parity ^= 1; else parity ^= 0; } data = (data << 1) + parity;


좀 복잡해 보이긴 하지만, data의 최상위 비트(7비트 데이터이므로, 6번 비트)부터 하나씩 검사해서 '1'이면 parity 값을 '1'과 ^(XOR) 연산하고, '0'이면 '0'과 ^(XOR) 연산한다. 사실 '0'과 ^(XOR) 연산하는 것은 값이 그대로 나오기 때문에 별 의미없는 코드이긴 하지만, 원칙적으로 모든 비트를 ^(XOR) 연산해야 하는 것이기 때문에 넣어두었다.

그래서 나온 결과 값은 data의 최하위 비트로 들어가게 된다. ('<<(왼쪽 시프트)' 연산은 다다음 포스팅에서 자세히 설명할 예정)

처음 data 변수에는 '100'이라는 값, 2진수로 '01100100'이라는 값이 들어가 있으므로 parity는 '1'이 될 것이고, 시프트된 후 parity와 합해지면 결국 data라는 변수에는 2진수 값 '11001001'이 들어가게 된다. 

이 데이터를 수신하는 측에서는 수신되는 데이터의 전체의 패리티 비트를 계산하고, 계산된 결과가 '0'일 경우 오류 없음, '1'일 경우 오류 발생으로 판단하게 된다.

byte data = Serial.read(); byte parity = 0; for (int i=0; i<8; i++) { if (data & (1 << i)) parity ^= 1; else parity ^= 0; } if (parity != 0) { // Error 발생 }


왜냐. 홀수 패리티는 '1'의 값이 홀수일 경우 패리티 비트가 '1'이 되는데, 그럼 결국 '1'의 개수가 짝수가 된다는 뜻이다. '1'의 값이 짝수라면 패리티 비트가 '0'이므로 그대로 짝수가 되는거고.

때문에 전체 비트를 검사해서 홀수 패리티를 구하게 되면, 오류가 없을 경우 패리티 값은 '0', 오류가 발생한 경우에는 '1'이 된다는 말. 


이 외에도 패킷 단위로 데이터를 주고받을 때, 데이터의 모든 바이트를 ^(XOR) 연산하여 마지막 바이트로 붙여보내는 방법도 자주 사용된다.



음. 원래는 ~(NOT) 연산이랑 한번에 끝내려고 했는데, 역시나 길어지는 바람에 둘로 나눠야겠다. 
다음 포스팅에선 ~(NOT) 연산으로 만나요. 안녕!

Link Source : http://m.blog.naver.com/yuyyulee/221087067663

Không có nhận xét nào:

Đăng nhận xét