[1주1장 CS] 논리 연산 2편: 컴퓨터에서 논리 연산이 실제로 어떻게 쓰일까?
한 주에 한 장씩 읽는 컴퓨터과학. 이번 주는 논리 연산의 후속편, 컴퓨터에서 불 대수가 쓰이는 실제를 알아봅니다. 복잡한 논리를 어떻게 나타내는지, 비트 단위 연산이 무엇인지 다룹니다.
chevron_right 목차
서론
저번 시간에는 불 대수와 여러 논리 연산에 대해 알아보았습니다. 이번에는 이 연산들이 컴퓨터에서 활용되는 모습을 살펴봅시다. 그리고 비트 단위 연산 에 대해서도 알아보겠습니다.
활용의 실제
윤년
태양년(365.2422일)과 달력의 1년의 오차를 보정하기 위해 윤일이 추가되는 해를 윤년[1]. 이를 판단하는 조건을 정리해 볼까요?
이라고 합니다. 우리가 현재 사용하는 그레고리력에서는 4년마다 윤년을 추가하는데, 100으로 나누어떨어지지만 400으로 나누어떨어지지 않는 해를 평년으로 지정했습니다먼저 조건을 다시 정리해 봅시다. 윤년일 조건은 다음과 같습니다:
- 4로 나누어떨어지고, 100으로 나누어떨어지지 않는 경우
- 400으로 나누어떨어지는 경우
이를 조건으로 나타내 볼까요? 연도를 year
라고 합시다.
int is_leap_year = (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
물론, 다른 방식으로 나타낼 수도 있습니다. 400으로 나누어떨어지는 경우는 당연히 4로 나누어떨어지므로, 조건을 이렇게 쓸 수도 있죠:
- 4로 나누어떨어지고,
- 100으로 나누어떨어지지 않는 경우
- 400으로 나누어떨어지는 경우
int is_leap_year = year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
이렇게 한 조건을 여러 방법으로 표현할 수 있습니다. 그 중에서도 조건을 명확하게 나타내는 방법을 고민해보면, 나중에 조건을 해석할 때도 도움이 됩니다. 아니면, 조건을 여러 단계로 나누어 표현할 수도 있습니다. 변수에 이름을 붙여서 보다 명확하게 무슨 조건인지를 나타낼 수 있죠.
int is_divisible_by_4 = year % 4 == 0;
int is_divisible_by_100 = year % 100 == 0;
int is_divisible_by_400 = year % 400 == 0;
int is_leap_year = (is_divisible_by_4 && !is_divisible_by_100) || is_divisible_by_400;
지금은 간단한 예시이므로 그 장점이 크지 않지만, 복잡한 조건을 다룰 때에는 가독성을 높이는 데 큰 도움이 됩니다. 성능이나 메모리 사용량은 걱정하지 않아도 됩니다. 나머지 연산이 수행되는 횟수는 어차피 같고, 이런 연산은 컴파일러가 잘 최적화할 수 있으니까요.
청년도약계좌 조건
청년도약계좌 개설의 조건은 다음과 같습니다[2]:
- 계좌개설일(가입일 포함) 기준 만 19세 이상 34세 이하인 자
- 병역이행기간(최대 6년)은 연령 계산 시 빼고 계산
- 개인 소득: 직전 과세기간의 총급여액이 7,500만원 이하이며, 종합소득과세표준에 합산되는 종합소득금액이 6,300만원 이하인 경우 (단, 육아휴직급여(육아휴직수당), 군 장병급여 외에 비과세 소득만 있는 경우는 제외)
- 가구 소득: 가구원 수에 따른 기준 중위소득 250% 이하에 해당하는 자
- 금융소득종합과세: 가입일이 속한 과세기간의 직전 3개년도 중 1회 이상 금융소득종합과세 대상자에 해당하지 않는 자
이런 예시는 확실히 조건이 복잡하죠. 먼저 입력 정보를 정리해 봅시다. 육아휴직급여와 군 장병급여 관련 조건은 생략하겠습니다.
age
: 나이military_service_period
: 병역 이행 기간personal_income
: 개인 소득total_personal_income_taxable
: 종합소득과세표준에 합산되는 종합소득금액household_income
: 가구 소득median_income
: 기준 중위소득is_financial_income_taxable
: 지난 3개년도 중 1회 이상 금융소득종합과세 대상자 여부
int is_eligible =
((age - military_service_period) >= 19 && (age - military_service_period) <= 34) // 나이 조건
&& (personal_income <= 75000000 && total_personal_income_taxable <= 63000000) // 개인 소득 조건
&& (household_income <= median_income * 2.5) // 가구 소득 조건
&& (!is_financial_income_taxable); // 금융소득종합과세 조건
주석을 달아도 단번에 이해하기는 어렵습니다. 앞서 설명한 것처럼 조건을 나누어 표현해 보겠습니다.
int age_to_calc = age - military_service_period;
int is_age_eligible = age_to_calc >= 19 && age_to_calc <= 34;
int is_personal_income_eligible = personal_income <= 75000000 && total_personal_income_taxable <= 63000000;
int is_household_income_eligible = household_income <= median_income * 2.5;
int is_financial_income_eligible = !is_financial_income_taxable;
int is_eligible = is_age_eligible && is_personal_income_eligible && is_household_income_eligible && is_financial_income_eligible;
이런 상황에서는 조건 나누기가 빛을 발합니다. 각각의 조건 의미를 나눠서 표현했으므로, 나중에 코드를 읽을 때도 이해하기 쉽습니다. 코드가 길어지기는 했지만, 주석보다 강력하게 의미를 전달할 수 있죠. 나중에 조건을 바꾸기에도 좋습니다.
비트 단위 연산
비트 단위로 논리 연산을 수행하는 것을 비트 단위 연산이라고 합니다. 비트 단위 연산은 비트 단위로 논리 연산을 수행합니다. 예를 들어, 8비트 정수 a
와 b
가 있다고 합시다. 이 두 수에 대해 AND 연산을 수행하면, 각 비트에 대해 AND 연산을 수행한 결과를 얻습니다.
기호는 논리 연산과 유사한 기호가 주로 사용됩니다.
- AND:
&
. 논리 연산&&
와 달리, 비트 단위로 AND 연산을 수행합니다. - OR:
|
. 논리 연산||
와 달리, 비트 단위로 OR 연산을 수행합니다. - XOR:
^
. 비트 단위로 XOR 연산을 수행합니다. - NOT:
~
. 논리 연산!
와 달리, 비트 단위로 NOT 연산을 수행합니다.
아래 두 기호는 비트 시프트 연산으로, 2배씩 곱하거나 나누는 데 사용하기도 합니다.
<<
. 비트 단위로 왼쪽으로 이동합니다.>>
. 비트 단위로 오른쪽으로 이동합니다.
const char a = 0b01111100;
const char b = 0b00011010;
printf("%d %d\n", a, b);
printf("%d %d\n", a & b, 0b00011000);
printf("%d %d\n", a | b, 0b01111110);
printf("%d %d\n", a ^ b, 0b01100110);
printf("%d %d\n", ~a, (char)0b10000011);
printf("%d %d\n", b<<1, (char)0b00110100);
printf("%d %d\n", b>>1, (char)0b00001101);
124 26
24 24
126 126
102 102
-125 -125
52 52
13 13
이를 제대로 활용하는 방법은 비트 마스크가 있는데, 이는 이 글에서 다루지 않겠습니다.
정리
- 불 대수 → 컴퓨터에서도 널리 활용
- 활용 예시
- 윤년
- 청년도약계좌 조건
- 복잡한 조건은 나누어 표현하기
- 비트 단위 연산
- 비트 단위 AND, OR, XOR, NOT, 시프트 연산
참고 자료
- [1] 김민재. "우주와 인간의 약속, 윤년." 사이언스타임즈. Accessed: Apr. 26, 2025. [Online]. Available: https://www.sciencetimes.co.kr/nscvrg/view/menu/248?searchCategory=220&nscvrgSn=255586[↑]
- [2] "청년도약계좌 상품 안내." 서민금융진흥원. Accessed: Apr. 26, 2025. [Online]. Available: https://ylaccount.kinfa.or.kr/main[↑]
용어
- label비트 단위 연산
- Bitwise Operation
- label윤년
- Leap Year
인용하기
@misc{devngho202520250426weeklycslogic2,
author = {Yu, Dongho},
title = {논리 연산 2편: 컴퓨터에서 논리 연산이 실제로 어떻게 쓰일까?},
howpublished = {\url{https://ngho.dev/posts/20250426-weekly-cs-logic-2}},
year = {2025},
month = {apr},
note = {Accessed: 2025-05-04}
}
APA 유동호. (2025년 4월 26일). 논리 연산 2편: 컴퓨터에서 논리 연산이 실제로 어떻게 쓰일까?. devngho 블로그. https://ngho.dev/posts/20250426-weekly-cs-logic-2
Chicago 유동호. “논리 연산 2편: 컴퓨터에서 논리 연산이 실제로 어떻게 쓰일까?.” devngho 블로그, 2025년 4월 26일, https://ngho.dev/posts/20250426-weekly-cs-logic-2.
MLA 유동호. “논리 연산 2편: 컴퓨터에서 논리 연산이 실제로 어떻게 쓰일까?.” devngho 블로그, 2025년 4월 26일, https://ngho.dev/posts/20250426-weekly-cs-logic-2.