Computer CS CASPP

정보의 표현과 처리

비트

  • 컴퓨터는 비트를 저장하고 처리

  • 디지털 혁명의 근원

  • 두개의 값을 갖는 신호.

    • 펀치카드에 구멍이 뚤렸는지 막혔는지
    • 높은 전압이 걸리는지 앉은 전압이 걸리는지
    • 자기장이 시계방향인지 반시계방향인지.
  • 이를 계산하고 저장하기 위한 전자회로는 매우 간단하고 안정적

  • 비트 패턴

    • 비트만으로는 그다지 유용 x
    • 비트들을 묶어서 비트 패턴을 만듦
    • 특정 해석방법을 적용하여 해당 비트패턴에 의미를 부여

컴퓨터의 숫자표현 기초

  • 정수
    • 특징: 작은 범위의 값을 매우 정밀하게
    • 비부호형 인코딩 → 양의 정수
      • 전통적인 이진수 표시
      • 0 이상의 수 표시
    • 2의 보수 인코딩 → 정수
      • 양수와 음수값을 갖는 부호형 정수를 표시하는 가장 일반적 방법
    • 계산의 결과값이 너무 크면 오버플로우 발생
      • 이상한 숫자가 일관되게 나타남
      • 교환법칙, 분배법칙 성립
  • 소수
    • 특징: 넓은 범위의 값을 근사값으로만
    • 부동소수점 인코딩
      • 소수 표시
    • 오버플로우 발생시
      • +∞ 라는 특별한 값 생성
      • 교환 법칙이 성립하지 않음
  • 많은 컴퓨터 보안 취약성은 컴퓨터 연산의 취약성 때문에 생김 → 어떻게 원하지 않은 방향으로 동작하게 될 수 있는 지 이해하고 있어야함.

2.1 정보의 저장

  • 메모리 접근 단위 = 메모리 주소 지정 단위 ⇒ 바이트(Byte)
  • 각 바이트는 주소라고 하는 고유한 숫자로 식별 가능
  • 가상 주소 공간
    • 각 바이트를 식별하는 주소로 표현되는 전체 영역
    • 개념적인 이미지임 → 실제로는 균일하지 않으나, 균일한 것처럼 보이도록 함
  • ex) C에서 어떤 포인터의 값 = 해당 정수가 저장된 메모리 블록의 첫 바이트의 주소

2.1.1 16진수 표시

  • 비트 패턴을 16진수로 표시함

int t = *p

2.1.2 데이터의 크기

  • 모든 컴퓨터는 워드 크기를 규격으로 가짐

  • 주소는 워드 크기로 인코딩됨

  • 이에 따라 가상 주소공간의 최대 크기도 결정됨

  • 적용

    • 워드 크기가 w비트 크기라는 소리는 주소의 길이도 w bit 크기라는 뜻임
    • 주소의 길이가 w bit 길이라는 것은 총 개를 주소로 표현할 수 있다는 의미이며,
    • 이에 따라 가상주소의 범위는 0 ~ 이 된다.
    • 결과적으로 가상주소공간의 크기는 byte 이다. (ex. byte = 4GB)
  • 64비트 머신에서는 32비트로 컴파일된 프로그램과 64비트로 컴파일된 프로그램 모두 잘 작동 하지만, 32비트 머신에서는 그렇지 않다.

다중 데이터 포멧
  • 부호형 / 비부호형
  • char도 숫자표현에 사용될 수 있음. 단, 부호형으로 사용하기 위해서는 signed를 붙여줘야함.
  • short, int, long은 데이터 크기에 따라 구분됨. 각각 2, 4, 8(32bit 프로그램에서는 4) byte의 크기를 가짐.
  • int32_t, int64_t은 컴파일러와 컴퓨터 설정에 관계없이 사용할 수 있는 자료형임
  • T *p는 자료형 T에 대한 포인터 변수로 word 길이의 주소값을 가진다.
  • float, double: 부동 소수점 형식의 소수형 자료형.
    • float: 단일 정밀도 / 4byte
    • double: 이중 정밀도 / 8byte
  • C언어에서는 데이터 타입의 최대값이 시스템(32, 64)마다 달라질 수 있음.
+) ✅ 자바나 파이썬과 비교해 보면?
언어데이터 타입 크기표현 범위
C시스템/컴파일러에 따라 다름❗️상한값이 변할 수 있음
Java타입 크기 고정 (int는 항상 4바이트)✅ 표현 범위 고정
Python정수 타입은 크기 제한 없음 (int는 무한 정밀도)✅ 자동 확장

2.1.3 주소지정과 바이트 순서

  • 여러 바이트에 걸쳐 있는 객체들에 대해,

    1. 객체의 주소가 여러 바이트중 무엇이 되어야 하는지
    2. 객체들을 여러바이트에 어떻게 정렬할 것인지
  • 주소지정: 사용된 바이트의 최소 주소

  • 정렬관습

    • 용어: 중요한 바이트 → 숫자의 경우 얼마나 큰값을 차지하고 있는지.
    • (16진수 값 0x01234567에 대새)
    • 리틀 엔디안
      • 덜 중요한 바이트가 먼저 옴
      • 67 45 32 01
    • 빅 엔디안
      • 중요한 바이트가 먼저옴
      • 01 23 45 67
    • 선택해야하는 기술적 이유는 딱히 없고, 컴퓨터의 타입에 따라 달라짐
      • 대부분의 인텔 호환 머신에서는 리틀 엔디안 사용
      • IBM, Oracle 머신들은 빅 엔디안 사용.
정렬 관련 이슈
  • 네트워크를 통해 다른 컴퓨터로 전송될 때 → 송신시에 네트워크 표준으로 변경하고, 수신시에 내 컴퓨터에 맞게 변환하는 방식 사용
  • 정수 데이터를 나타내는 바이트들을 살펴볼때
    • 예시
      • 4004d3: 01 05 43 0b 20 00
      • add %eax, 0x200b43(%rip)
    • 정수 데이터: 0x200b43 → 어셈블리 명령어 안에 주소, 상수, 오프셋 등으로 사용되는 정수 값(사람이 직접쓴 숫자나, 참조되는 메모리 위치)
    • 정수 데이터를 나타내는 바이트: 43 0b 20 00
    • 이것에 대한 해석을 잘 못하면 완전 다른 값이 도출됨.
  • 프로그램이 정상적인 타입체계를 회피하도록 작성되었을 때

2.1.4 스트링의 표시

  • C에서 스트링은 null1 문자로 졸요하는 문자열로 인코딩 됨.
  • 각 문자열은 표준 인코딩2에 따라 표시됨
  • 텍스트 데이터는 이진데이터에 비해 플랫폼 독립적이다.
    • 이진데이터의 경우 정렬 순서나 워드크기에 따라 값이 변할 수 있지만
    • 텍스트의 경우 각 매칭되는 ascii값과 종료바이트인 0x00으로 이루어져있기 때문.

2.1.5 코드의 표현

  • 인스트럭션들의 인코딩은 컴퓨터 타입과 운영체제 등에 따라 모두 다름
  • 동일한 것은 컴퓨터의 관점에서 프로그램은 단순히 바이트의 연속이라는 점이다.

2.1.6 부울(Boolean) 대수

  • 부울 대수: 논리 값 TRUE(0)와 FALSE(1)를 다루는 이론적체계로, 논리연산을 수학적으로 다루기 위한 체계임.
  • boole이라는 사람이 이진수 값 1과 0을 논리값 TRUE와 FALSE로 인코딩하면, 논리추론의 기본원리들을 수식화 할 수 있다는 것을 발견해서 이런 이름이 붙었음.
논리 연산논리연산자C언어 기호
Not¬~
And&
Or|
Xor^
비트 벡터
  • 0과 1로 이루어진 비트 스트링(배열)
  • 연산
    • 비트벡터간의 연산은 동일한 자리수의 비트간의 연산으로 볼 수 있다.
    • 즉 각 비트 벡터의 i번째 원소를 , 라고 할 때 와 같다.
  • 유한 집합의 원소 포함 여부
    • 각 비트는 어떤 특정 항목의 포함 여부를 나타냄
    • {0, 2, 5}라는 집합을 표현할 때 → 101001
      • 인덱스 0, 2, 5는 1 → 포함
      • 인덱스 1, 3, 4는 0 → 미포함
    • 이에 대해 합집합이나 교집합, 여집합 연산을 하기에 편함
    • 비트 (벡터) 마스크
      • 특정 시그널의 선택적으로 활성화, 비활성화 할 수 있도록 해줌
      • 아래에서 자세히 다룸
    • 장점
      • 메모리 사용이 표율적이고
      • 연산이 빠름

2.1.7 C에서의 비트수준 연산

  • C는 비트들 간의 부울 연산을 지원함(위에 기호 정리해둠.)
  • 일반적으로 마스크 연산을 구현 할 때 사용.
    • x = 0x89ABCDEF일 때 x&0xFF는 맨 우측의 EF 값만 활성화하는데 사용.
    • ~0은 비트가 모두 1인 마스크를 만들 때 사용

2.1.8 C에서의 논리 연산

  • 논리연산자인 ||, &&, !를 제공함
  • 비트수준의 연산과 혼동하지 말것
    • 해당 논리연산이 참인지 거짓인지에 따라 0 또는 1을 리턴함
    • 만일 첫번째 인자를 계산해서 참, 거짓이 결정된다면 뒤의 연산을 하지 않음.
항목비트 연산논리 연산
작동 대상각 비트 단위논리값(True/False)
예시 타입정수 (int, char, unsigned int)조건식 (bool, if문 안)
예시 연산자&, `, ^, ~, <<, >>`
결과값비트값 그대로 (숫자)논리값 (0 또는 1, 참/거짓)
쓰임새마스크, 플래그 제어, 하드웨어 연산조건문, 분기, 참/거짓 판단

2.1.9 C에서의 쉬프트 연산

  • 비트 패턴을 좌우로 이동시키는 연산 (정수를 2로 나눌 때 유용)
  • 좌측연산(x≪k): x를 좌측으로 k비트 이동 / 제일 좌측 비트 k개는 삭제 / 우측은 k개의 0으로 채워짐
  • 우측연산(x≫k): x를 우측으로 k비트 이동 / 제일 우측 비트 k개는 삭제
    • 논리 우측 쉬프트: 좌측 k개가 0으로 채워짐
    • 산술 우측 쉬프트: 좌측 k개가 가장 중요한 비트(원래 제일 왼쪽 비트)로 채워짐 → 부호형 정수 데이터의 연산에서 유용하게 작용.
    • 대부분 산술 우측 쉬프트를 사용, 비부호형 데이터에 대해서 놀니 쉬프트를 적용

2.2 정수의 표시

2.2.1 정수형 데이터 타입

  • char: 1 byte
  • short: 2 byte
  • int: 4 byte
  • long: 4 byte(32-bit) or 8 byte(64-bit) → 컴퓨터에 의존적인 범위
  • int32_t: 4 byte
  • int64_t: 8 byte
  • 각각에 대해 signed한 자료형(기본)과 unsigned한 자료형이 존재함.
  • c표준에서는 각 데이터 타입에서 나타낼 수 있어야하는 최소한의 범위를 정의함.

2.2.2 비부호형의 인코딩

  • 비트 벡터의 각 비트는 0이나 1의 값을 가짐
  • 자리수 i에 대해 비트 값 1을 가진다는 의미 → 값이 숫자의 값을 계산 할 때 포함 되어야한다는 의미
  • 계산: 자릿값() x 1 또는 0을 해서 합함
  • ![|300](20250523_195552.jpg

2.2.3 2의 보수(two’s complement) 인코딩

  • 부호형 숫자를 컴퓨터에서 표시하는 가장 일반적인 방법

  • 가장 왼쪽 비트를 부호 비트로 사용함

    • 1이면 음수
    • 0이면 양수
  • |320

  • 계산 → 4자리 비트에서

    • 부호비트의 자리값은
    • 나머지의 자리값은
    • 각 자리값에 해당하는 비트값(0 or 1)을 곱한 값들의 합합
  • |300

  • 특징

    • 2의 보수의 범위는 비대칭적임.
      • (양수값의 범위) = (음수값의 범위) - 1
      • 비트 패턴의 절반으로 음수를, 나머지 절반으로 비음수(0과 양수)를 표현하기 때문
    • 비부호형의 최대값 = 2의 보수 최대값 * 2 + 1
      • 2의 보수에서 음수를 표시하는 모든 비트 패턴들은 비부호형에서 양수값을 표시하고 있기 때문임.
  • 사용

    • C의 경우 부호형 정수를 2의 보수 형식으로 나타낼 것을 요구하지는 않지만, 거의 모든 컴퓨터에서 요하고 있음.
    • 자바는 64비트의 경우 2의 보수 표시를 요구함

2.2.4 비부호형과 부호형 간의 변환

  • 비트의 값 → 동일하게 유지
  • 비트를 해석하는 방법 → 변경

2.2.5 C에서 부호형과 비부호형의 비교

  • 묵시적으로 부호형 인자를 비부호형으로 변환하고 숫자들이 비음수라고 가정하고 계산
  • 이것은 관계 연산에 대해서 다소 덜 직관적인 결과를 만든다

2.2.6 수의 비트 표시를 확장하기

  • 비부호형 수: 단순히 앞에 0을 추가 → 0의 확장(zero extension)
  • 부호형 수(2의 보수): 부호비트를 복사해서 앞부분 전체에 추가 → 부호 확장(sign extension)

2.2.7 숫자의 절삭

  • 수를 절삭하면 그 값이 바뀔 수 있다. → 일종의 오버플로우
  • 컴퓨터는 그냥 자르지만 우리가 이것을 계산하려면 mod 연산을 하면 된다.
  • 비부호형 수:
    • x’ = x mod
    • k 위로 자를 때, i ≥ k인 모든 의 자리값은 0으로 계산됨.
  • 부호형 수(2의 보수): 똑같이 그냥 자르고 그 값을 부호형 수로 바꿔 줌.
    • x’ = U2T(x mod )
    • 가장 중요한 비트인 이 자리값 대신 을 가짐

Signed와 Unsigned에 대한 조언

  • 부호형과 비부호형 간의 묵시적인 타입변환은 미묘한 에러들을 수반한다.
  • 기왕이면 비부호형 수를 절대로 사용하지 말아라. → C외에 다른 언어들은 비부호형 수를 지원하지 않음.

2.3 정수의 산술 연산

2.3.1 비부호형 덧셈

  • 두 개의 0 이상 미만의 정수 x와 y에 대해 x+y는 최대 개의 비트로 표현 될 수 있음. → 오버플로우 발생
  • 이때 컴퓨터는 넘어간 비트를 절삭
  • |180

2.3.2 2의 보수의 덧셈

  • |250
  • 이 경우도 비슷하게 overflow가 발생할 수 있다.
  • 양의 오버플로우 (case 4):
  • 음의 오버플로우 (case 1):
  • overflow의 판별은 양수끼리 더했을 때 음수가, 음수끼리 더했을 때 양수가 나오는 경우로 판별할 수 있다.
  • 여기도 동일하게 절삭을 진행하고, 그 값은 아래와 같이 계산할 수 있다.
    • 양의 오버플로우:
    • 음의 오버플로우:

2.3.4 비부호형 곱셈 / 2.3.5 2의 보수 곱셈

  • 표시하려면 비트까지 필요할 수 있다.
  • 동일하게 절삭을 진행한다.
  • 2의 보수는 절삭 후 해당 수를 2의 보수로 해석한다.

2.3.6 상수를 사용한 곱셈

  • 컴퓨터에서 정수 곱셈은 매우 느리다.
  • 따라서 곱셈을 대체할 수 있는 방법이 필요하다.
  • 그 방법이 시프트 연산을 하고 그 값을 더하는 것이다.
    • 2의 제곱을 곱하는 경우 → 좌측 시프트
    • 2의 제곱이 아닌 경우
      • 곱하는 수를 2의 제곱들의 합(또는 차)로 표현을 하고 그것을 활용
      • ex) 14 = 8 + 4 + 2
        • (x << 3) + (x << 2) + (x << 1) = x * 14
  • 일반 곱셈기 또한 내부에서 위의 방식으로 작동한다.
구분곱셈 대상자료형 의미연산 방식시점
비부호형 곱셈변수 × 변수unsigned일반 곱셈기곱셈기를 호출
2의 보수 곱셈변수 × 변수signed (2’s comp.)일반 곱셈기 + 부호 보정곱셈기를 호출
상수 곱셈변수 × 상수unsigned or signed시프트 + 덧셈컴파일 시점에서
시프드 + 덧셈으로 수정

2.3.7 2의 제곱으로 나눗셈하기

  • 곱셈보다도 느리다므로 우측 시프트연산을 사용한다.
  • 각각 표현방식에 따라 논리 시프트(비부호형), 산술 시프트(2의 보수)를 사용함
  • 정수의 나눗셈에 대해 소수점 이하는 버린다고 정의했기 때문에 이에 맞추어 컴퓨터가 작동하게 보정을 해줘야함.
  • 기본적으로 시프트 연산을 마치면 결과는 버림이 아닌 내림으로 나옴
    • 양수: 내림 = 버림
    • 음수: 내림 ≠ 버림 → -3.5 = -3 (버림) = -4 (내림)
  • 따라서 이 값을 보정해주기위해 bias값을 사용한다.
    • 가장 큰 오차를 더하는 것임.

2.4 부동소수점

2.4.1 비율 이진수

  •  소수점이 있는 이진수로 2의 음의 거듭제곱이다.
  • 십진수에 무한소수가 있는 것처럼, 비율이진수 또한 무한 소수가 있다
  • 따라서 모든 수를 정확히 표현할 수 없고 근사값을 사용할 때가 많다.

2.4.2 IEEE 부동 소수점 표시

  • 부동소수점: 아주 큰 수 또는 아주 작은 수를 효율적으로 표현하기 위한 범용적인 숫자 표현 방식
  • 기본 공식:
    • S: 부호 비트 → 0이면 양수, 1이면 음수
    • M: 가수
      • 실제 숫자의 유효 자릿수
      • 비율 이진수와 유사
    • E: 지수
      • 2의 몇 제곱인지
      • bias 값을 사용하여 부호 없이 음수, 양수를 모두 표현할 수 있도록함.
  • 종류
    • 정규화 값
      • 가장 일반적인 경우 지수 필드가 모두 0은 아니며, 모두 1이 아니어야 한다.
      • 가수 앞에 암묵적 ‘1.’ 이 존재함
    • 비정규화 값
      • 지수 필드가 모두 0일 때
      • 아주 작은 수를 표현할 때 사용
      • 가수 앞의 암묵적 1. 이 없음 → 0.
    • 특수 값
      • 지수 필드가 모두 1인 경우
      • 숫자가 아닌 것을 표현함
      • NaN이나, 무한대 값을 표현함
구분지수 필드 (8비트)지수 (실제 값)가수(fraction)의미 / 해석
비정규화 수00000000 (0)-126 고정≠ 00.f × 2⁻¹²⁶ (작은 실수)
+0 / -000000000 (0)-126 고정0정수 0 (부호만 다름)
정규화 수00000001 (1)
~ 11111110 (254)
-126 ~ +127임의의 값1.f × 2^{e-127}
+∞ / -∞11111111 (255)N/A0양/음의 무한대
NaN11111111 (255)N/A≠ 0정의되지 않은 수

2.4.4 근사법

이름방향예 (3.5)예 (-3.5)특징
짝수 근사법 (기본)가장 가까운 값,
동점 시 짝수 쪽
4-4통계적 중립성, 기본값
영 방향 근사0을 향해 절삭3-3truncate, 정수 나눗셈처럼
하향 근사-∞ 방향으로3-4항상 아래로
상향 근사+∞ 방향으로4-3항상 위로

2.4.5 부동소수점 연산

  • 정확하지 않은 경우가 많다 → 근사값값
  • 분배, 교환, 결합법칙이 성립하지 않는다

Footnotes

  1. 값 0을 가짐

  2. 대개 ASCII