[1주1장 CS] 논리 연산 2편: 컴퓨터에서 논리 연산이 실제로 어떻게 쓰일까?

태그 1주1장 CS 분류 1주1장 CS

한 주에 한 장씩 읽는 컴퓨터과학. 이번 주는 논리 연산의 후속편, 컴퓨터에서 불 대수가 쓰이는 실제를 알아봅니다. 복잡한 논리를 어떻게 나타내는지, 비트 단위 연산이 무엇인지 다룹니다.


chevron_right

목차


서론

저번 시간에는 불 대수와 여러 논리 연산에 대해 알아보았습니다. 이번에는 이 연산들이 컴퓨터에서 활용되는 모습을 살펴봅시다. 그리고 비트 단위 연산에 대해서도 알아보겠습니다.

활용의 실제

윤년

태양년(365.2422일)과 달력의 1년의 오차를 보정하기 위해 윤일이 추가되는 해를 윤년이라고 합니다. 우리가 현재 사용하는 그레고리력에서는 4년마다 윤년을 추가하는데, 100으로 나누어떨어지지만 400으로 나누어떨어지지 않는 해를 평년으로 지정했습니다[1]. 이를 판단하는 조건을 정리해 볼까요?

먼저 조건을 다시 정리해 봅시다. 윤년일 조건은 다음과 같습니다:

  • 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비트 정수 ab가 있다고 합시다. 이 두 수에 대해 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. [1]
    김민재. "우주와 인간의 약속, 윤년." 사이언스타임즈. Accessed: Apr. 26, 2025. [Online]. Available: https://www.sciencetimes.co.kr/nscvrg/view/menu/248?searchCategory=220&nscvrgSn=255586
    [↑]
  2. [2]
    "청년도약계좌 상품 안내." 서민금융진흥원. Accessed: Apr. 26, 2025. [Online]. Available: https://ylaccount.kinfa.or.kr/main
    [↑]

용어

label
비트 단위 연산
Bitwise Operation
label
윤년
Leap Year

인용하기
BibTeX
@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.