👨🏻‍🏫Lecture/게임 프로그래머 입문 올인원

Section 1-3. 데이터와 로직 - 정수의 원리

Sugar0810 2023. 8. 21. 23:00
Inflearn Rookiss님의 [게임 프로그래머 입문 올인원] C++ & 자료구조/알고리즘 & STL & 게임 수학 & Windows API & 게임 서버 강의를 보고 정리한 포스팅입니다.
👨🏻‍🏫강의 보러 가기
 

[게임 프로그래머 입문 올인원] C++ & 자료구조/알고리즘 & STL & 게임 수학 & Windows API & 게임 서버 -

어디부터 시작할지 막막한 게임 프로그래밍 입문자를 위한 All-In-One 커리큘럼입니다. C++, 자료구조/알고리즘, STL, 게임 수학, Windows API, 게임 서버 입문으로 이어지는 알찬 커리큘럼으로 게임 프

www.inflearn.com

 

 

 

☑️데이터 단위

컴퓨터 시스템에서 데이터를 저장하고 처리하는 데 사용되는 기본적인 크기 단위들을 나타내며, 각각의 단위는 정보의 크기와 처리 능력을 나타내는 중요한 역할

 

✔️Bit(비트)

비트는 정보를 저장하거나 표현하는 최소 단위로, 0 또는 1의 두 가지 상태를 나타냅니다. 컴퓨터는 이진 시스템을 기반으로 동작하기 때문에 모든 데이터는 비트 형태로 저장되고 처리됩니다. 하나의 비트는 전기적으로 스위치가 켜진 상태(1) 또는 꺼진 상태(0)를 나타냅니다.

 

✔️Byte(바이트)

바이트는 일반적으로 8개의 비트로 구성되며, 컴퓨터 메모리에 데이터를 저장하는 기본 단위입니다. 바이트는 문자, 숫자, 기호 등을 표현하는데 사용됩니다. 예를 들어, ASCII 코드에서 각 문자는 하나의 바이트로 표현됩니다.

 

✔️Word(워드)

워드는 프로세서가 한 번에 처리하는 데이터의 크기를 의미합니다. 워드 크기는 컴퓨터 아키텍처에 따라 다르며, 일반적으로 16비트, 32비트, 64비트 등이 있습니다. 16비트 워드는 2바이트로, 32비트 워드는 4바이트로, 64비트 워드는 8바이트로 표현됩니다. 워드의 크기는 프로세서의 데이터 버스 크기와 연관이 있으며, 한 번에 전송하거나 처리할 수 있는 비트 수를 나타냅니다.

 

✔️Double Word(더블 워드 또는 DWord)

더블 워드는 워드의 두 배 크기를 의미하며, 주로 32비트 아키텍처에서 4바이트로 표현됩니다. 더블 워드는 주로 정수 데이터나 메모리 주소를 저장하는데 사용되며, 데이터의 크기가 워드보다 큰 경우에 유용합니다.

 

 

 

☑️음수 표현

컴퓨터에서 음수를 표현하는 방법에는 여러 가지가 있지만, 가장 흔히 사용되는 방법은 2의 보수를 사용하는 방법입니다. 다른 방식으로는 1의 보수와 부호 절대값 방식 등이 있지만, 2의 보수 방식이 효율적으로 덧셈 및 뺄셈을 처리할 수 있어 많이 사용됩니다.

 

✔️2의 보수 원리

2의 보수 방식은 음수 값을 표현하기 위해 양수 값의 이진 표현을 반전하고 1을 더하는 방법입니다. 이 방식으로 음수를 나타내면, 덧셈 및 뺄셈 연산에서 동일한 방식으로 처리할 수 있습니다.

  1. 양수를 이진 표현합니다.
  2. 각 비트를 반전시킵니다. (0을 1로, 1을 0으로)
  3. 마지막 비트에 1을 더합니다.

예를 들어, 8비트로 -5를 나타내는 과정은 다음과 같습니다:

  1. 5를 이진으로 표현하면: 0000 0101
  2. 각 비트를 반전시키면: 1111 1010
  3. 마지막 비트에 1을 더하면: 1111 1011

따라서 -5는 8비트 2의 보수로 표현하면 1111 1011입니다.

이 방식은 덧셈과 뺄셈을 효율적으로 수행할 수 있도록 해줍니다. 양수와 음수를 동일한 방식으로 다루며, 덧셈과 뺄셈의 결과도 이진 연산으로 처리할 수 있습니다.

 

 

 

☑️진법

진법은 수를 표현하는 데 사용되는 기수(system of numeration)로, 숫자들을 나타내는 기본 단위와 그에 대한 규칙을 나타냅니다. 가장 잘 알려진 진법은 10진법(십진법)이지만, 컴퓨터 과학과 다양한 수학적 응용에서는 2진법, 8진법, 16진법 등도 흔히 사용됩니다.

 

📝10진수가 아닌 다른 진수로 저장 또한 가능합니다.

 

✔️2진법

2진법은 0과 1의 두 숫자만을 사용하는 진법입니다. 컴퓨터에서 정보를 처리하는 기본 단위로 사용되며, 0과 1은 컴퓨터 내에서 전기 신호의 켜짐과 꺼짐을 나타내는데 사용됩니다.

 

✔️4진법

8진법은 0부터 7까지의 8개의 숫자를 사용하여 수를 표현하는 진법입니다. 3비트의 2진수를 한 자리로 나타낼 수 있어서 컴퓨터 프로그래밍에서 종종 사용됩니다.

 

✔️8진법

10진법은 우리가 일상 생활에서 사용하는 진법입니다. 0부터 9까지의 10개의 숫자로 이루어져 있으며, 각 자릿수의 위치에 따라 숫자의 가치가 10의 거듭제곱 형태로 증가합니다.

 

✔️16진법

16진법은 0부터 15까지의 16개의 숫자를 사용하여 수를 표현하는 진법입니다. 각 자리는 0부터 15까지의 값을 가질 수 있으며, 컴퓨터에서 메모리 주소나 데이터를 나타내는 데 사용됩니다. 16진법은 2진법을 간결하게 표현할 수 있는 점에서 유용합니다.

 

 

 

☑️진법 변환

진법 변환은 한 진법의 수를 다른 진법의 수로 바꾸는 과정입니다. 보통 10진법 수를 다른 진법으로 변환하거나, 다른 진법의 수를 10진법으로 변환하는 작업이 필요합니다.

예를 들어, 10진법 수 13을 2진법으로 변환하는 과정은 다음과 같습니다:

  1. 13을 2로 나눈 몫과 나머지를 구합니다. 13 ÷ 2 = 6 (나머지 1)
  2. 6을 2로 나눈 몫과 나머지를 구합니다. 6 ÷ 2 = 3 (나머지 0)
  3. 3을 2로 나눈 몫과 나머지를 구합니다. 3 ÷ 2 = 1 (나머지 1)
  4. 1을 2로 나눈 몫과 나머지를 구합니다. 1 ÷ 2 = 0 (나머지 1)

나머지를 역순으로 나열하면 13의 2진법 표현인 1101이 됩니다.

진법 변환은 주어진 숫자와 변환할 진법에 따라 연산 과정이 달라지며, 각 진법의 규칙을 이해하고 숙지하는 것이 중요합니다.

 

 

 

☑️비트플래그(Bit Flag)

비트 플래그(bit flag)는 프로그래밍에서 비트 연산을 사용하여 여러 가지 상태를 표현하고 관리하는 데 사용되는 효과적인 방법입니다. 비트 플래그는 주로 정수 변수의 비트를 사용하여 여러 상태 또는 옵션을 표현하며, 각 비트의 위치가 특정 상태를 나타냅니다.

비트 플래그는 다양한 응용 분야에서 사용됩니다. 예를 들어, 옵션 설정, 플래그 상태, 조건 검사 등에서 사용될 수 있습니다.

 

다음은 비트 플래그를 사용하는 예시입니다

예시)파일 접근 권한 플래그
파일 접근 권한을 표현하기 위해 3개의 비트를 사용하는 경우를 생각해봅시다. 각 비트는 읽기, 쓰기, 실행 권한을 나타냅니다.

1번 비트: 읽기 권한 (1: 허용, 0: 거부)
2번 비트: 쓰기 권한 (1: 허용, 0: 거부)
3번 비트: 실행 권한 (1: 허용, 0: 거부)
만약 읽기와 쓰기 권한을 허용하고 실행 권한을 거부하려면, 이를 이진 표기법으로 110으로 표현할 수 있습니다.

 

✔️비트 플래그 사용의 장점

  • 메모리 절약
    여러 개의 상태를 하나의 정수 변수에 저장하므로써 메모리 공간을 절약할 수 있습니다.
  • 빠른 처리
    비트 연산은 하드웨어에서 매우 빠르게 처리될 수 있으므로, 여러 상태를 동시에 확인하거나 변경하는 작업이 효율적으로 수행됩니다.
  • 가독성 향상
    단일 정수 변수에 여러 상태를 표현할 수 있어 코드의 가독성을 향상시킬 수 있습니다.


✔️주의사항

비트 플래그를 사용할 때에는 다음과 같은 주의사항을 고려해야 합니다.

  • 코드 가독성 유지
    비트 연산은 복잡한 비트 조작을 포함하므로 코드의 가독성을 유지하는 것이 중요합니다.
  • 유지보수성
    비트 플래그를 사용할 때는 해당 비트의 의미를 주석으로 설명하거나 상수로 정의하여 코드의 의도를 명확히 해야 합니다.

 

 

 

☑️쉬프트 연산(Shift Operation)

쉬프트 연산(Shift Operation)은 비트들을 왼쪽 또는 오른쪽으로 이동시키는 연산입니다. 이동된 비트는 새로운 비트 값으로 채워지며, 쉬프트 연산은 주로 비트 조작이나 데이터 처리에 사용됩니다. 주로 사용되는 쉬프트 연산은 논리 쉬프트(Logical Shift)와 산술 쉬프트(Arithmetic Shift)입니다.


✔️논리 쉬프트(Logical Shift)

논리 쉬프트는 비트들을 주어진 방향으로 이동시키고, 빈 비트 자리를 0으로 채우는 연산입니다. 양수와 음수에 상관없이 동일한 동작을 수행합니다.

 

  • 왼쪽 쉬프트 (<<)
    비트들을 왼쪽으로 이동시킵니다. 오른쪽에서 빠지는 비트는 버려집니다.
  • 오른쪽 쉬프트 (>>)
    비트들을 오른쪽으로 이동시킵니다. 왼쪽에서 빠지는 비트는 버려집니다.

 

예를 들어, 8비트 이진수 00101010을 왼쪽으로 2칸 쉬프트하면 10101000이 되고, 오른쪽으로 1칸 쉬프트하면 00010101이 됩니다.


✔️산술 쉬프트(Arithmetic Shift)

산술 쉬프트는 비트들을 주어진 방향으로 이동시키며, 왼쪽 또는 오른쪽 빈 비트 자리를 기존의 최상위 비트 값으로 채웁니다. 이로써 음수 값을 가지는 2의 보수 표현에서는 음수의 부호를 유지하면서 쉬프트할 수 있습니다.

 

  • 왼쪽 산술 쉬프트 (<<)
    비트들을 왼쪽으로 이동시키고, 오른쪽 빈 자리를 최상위 비트 값으로 채웁니다.
  • 오른쪽 산술 쉬프트 (>>)
    비트들을 오른쪽으로 이동시키고, 왼쪽 빈 자리를 최상위 비트 값으로 채웁니다.

 

예를 들어, 8비트 이진수 11011010을 왼쪽으로 2칸 산술 쉬프트하면 10101000이 되고, 오른쪽으로 1칸 산술 쉬프트하면 11101101이 됩니다.


쉬프트 연산은 비트 조작이나 데이터 처리에서 매우 유용하며, 비트 플래그를 조작하거나 정수 값을 빠르게 2의 거듭제곱으로 나누거나 곱할 때 등에 활용됩니다.

 

 

 

☑️정수 오버플로우(Integer Overflow)

정수 오버플로우(Integer Overflow)는 컴퓨터에서 정수 값의 표현 범위를 벗어나는 연산이나 할당이 발생할 때 발생하는 문제입니다. 정수 타입은 표현 가능한 값의 범위가 한정되어 있기 때문에, 특정 범위를 초과하거나 미달할 경우 오버플로우가 발생합니다.

✔️정수 오버플로우의 종류

  • 양수 오버플로우
    양수 변수의 값이 해당 데이터 타입이 표현 가능한 최대값을 초과하여 음의 값으로 회귀하는 상황을 말합니다.
  • 음수 오버플로우
    음수 변수의 값이 해당 데이터 타입이 표현 가능한 최소값을 미달하여 양의 값으로 회귀하는 상황을 말합니다.

 

✔️정수 오버플로우의 원인

  • 덧셈 및 뺄셈 연산
    두 정수를 더하거나 뺄 때, 결과 값이 해당 데이터 타입의 최대값 또는 최소값을 넘어가는 경우 오버플로우가 발생합니다.
  • 곱셈 연산
    두 정수를 곱할 때 결과 값이 해당 데이터 타입의 표현 범위를 벗어나는 경우 오버플로우가 발생합니다.
  • 비트 쉬프트 연산
    쉬프트 연산으로 인해 최상위 비트가 변경되어 양수 값이 음수 값으로 바뀌거나, 음수 값이 양수 값으로 바뀌는 경우 오버플로우가 발생할 수 있습니다.

 

✔️정수 오버플로우의 영향

정수 오버플로우는 예상치 못한 결과를 가져올 수 있습니다. 컴퓨터에서는 연산 결과의 오버플로우를 감지하기 어려

울 수 있어서 잘못된 결과가 발생할 수 있습니다. 이로 인해 프로그램의 동작이 예상과 다르게 되거나, 시스템의 불안정성

이 발생할 수 있습니다.

 

✔️정수 오버플로우 방지 방법

  • 타입 선택
    표현 범위를 넘어서는 값이 발생할 가능성이 있는 경우, 큰 범위의 데이터 타입을 선택하여 사용합니다.
  • 범위 검사
    연산을 수행하기 전에 결과 값이 허용 가능한 범위 내에 있는지 검사합니다.
  • 자료 크기 고려
    데이터의 크기가 적절하게 고려되도록 설계합니다. 필요한 경우 데이터를 잘리거나 확장하지 않고 적절한 크기로 관리합니다.
  • 예외 처리
    오버플로우가 발생할 가능성이 있는 연산에서 예외 처리를 수행하여 프로그램의 안정성을 유지합니다.


정수 오버플로우는 프로그래밍에서 자주 발생할 수 있는 문제 중 하나이므로, 데이터 타입과 연산의 선택범위 검사예외 처리 등을 통해 이를 방지하고 관리해야 합니다.

 

 

 

☑️스크립트

📝10진수가 아닌 다른 진수로 저장

#include <iostream>
using namespace std;

int hp;
short mp;

int main()
{
    hp  = 0b1100; // → 12(2진법 = 0b)
    mp  = 0x1100; // → 4352(16진법 = 0x)
    dex = 0xF;    // → 15(16진법)
    
    cout << hp;
    // Resulut is :: 12
}