정보의 표현과 처리
비트
-
컴퓨터는 비트를 저장하고 처리
-
디지털 혁명의 근원
-
두개의 값을 갖는 신호.
- 펀치카드에 구멍이 뚤렸는지 막혔는지
- 높은 전압이 걸리는지 앉은 전압이 걸리는지
- 자기장이 시계방향인지 반시계방향인지.
-
이를 계산하고 저장하기 위한 전자회로는 매우 간단하고 안정적
-
비트 패턴
- 비트만으로는 그다지 유용 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: 단일 정밀도 / 4bytedouble: 이중 정밀도 / 8byte
- C언어에서는 데이터 타입의 최대값이 시스템(32, 64)마다 달라질 수 있음.
+) ✅ 자바나 파이썬과 비교해 보면?
| 언어 | 데이터 타입 크기 | 표현 범위 |
|---|---|---|
| C | 시스템/컴파일러에 따라 다름 | ❗️상한값이 변할 수 있음 |
| Java | 타입 크기 고정 (int는 항상 4바이트) | ✅ 표현 범위 고정 |
| Python | 정수 타입은 크기 제한 없음 (int는 무한 정밀도) | ✅ 자동 확장 |
2.1.3 주소지정과 바이트 순서
-
여러 바이트에 걸쳐 있는 객체들에 대해,
- 객체의 주소가 여러 바이트중 무엇이 되어야 하는지
- 객체들을 여러바이트에 어떻게 정렬할 것인지
-
주소지정: 사용된 바이트의 최소 주소
-
정렬관습
- 용어: 중요한 바이트 → 숫자의 경우 얼마나 큰값을 차지하고 있는지.
- (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 byteshort: 2 byteint: 4 bytelong: 4 byte(32-bit) or 8 byte(64-bit) → 컴퓨터에 의존적인 범위int32_t: 4 byteint64_t: 8 byte- 각각에 대해 signed한 자료형(기본)과 unsigned한 자료형이 존재함.
- c표준에서는 각 데이터 타입에서 나타낼 수 있어야하는 최소한의 범위를 정의함.
2.2.2 비부호형의 인코딩
- 비트 벡터의 각 비트는 0이나 1의 값을 가짐
- 자리수 i에 대해 비트 값 1을 가진다는 의미 → 값이 숫자의 값을 계산 할 때 포함 되어야한다는 의미
- 계산: 자릿값() x 1 또는 0을 해서 합함
-  인코딩
-
부호형 숫자를 컴퓨터에서 표시하는 가장 일반적인 방법
-
가장 왼쪽 비트를 부호 비트로 사용함
- 1이면 음수
- 0이면 양수
-

-
계산 → 4자리 비트에서
- 부호비트의 자리값은
- 나머지의 자리값은
- 각 자리값에 해당하는 비트값(0 or 1)을 곱한 값들의 합합
-

-
특징
- 2의 보수의 범위는 비대칭적임.
- (양수값의 범위) = (음수값의 범위) - 1
- 비트 패턴의 절반으로 음수를, 나머지 절반으로 비음수(0과 양수)를 표현하기 때문
- 비부호형의 최대값 = 2의 보수 최대값 * 2 + 1
- 2의 보수에서 음수를 표시하는 모든 비트 패턴들은 비부호형에서 양수값을 표시하고 있기 때문임.
- 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는 최대 개의 비트로 표현 될 수 있음. → 오버플로우 발생
- 이때 컴퓨터는 넘어간 비트를 절삭함

2.3.2 2의 보수의 덧셈

- 이 경우도 비슷하게 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 고정 | ≠ 0 | 0.f × 2⁻¹²⁶ (작은 실수) |
| +0 / -0 | 00000000 (0) | -126 고정 | 0 | 정수 0 (부호만 다름) |
| 정규화 수 | 00000001 (1)~ 11111110 (254) | -126 ~ +127 | 임의의 값 | 1.f × 2^{e-127} |
| +∞ / -∞ | 11111111 (255) | N/A | 0 | 양/음의 무한대 |
| NaN | 11111111 (255) | N/A | ≠ 0 | 정의되지 않은 수 |
2.4.4 근사법
| 이름 | 방향 | 예 (3.5) | 예 (-3.5) | 특징 |
|---|---|---|---|---|
| 짝수 근사법 (기본) | 가장 가까운 값, 동점 시 짝수 쪽 | 4 | -4 | 통계적 중립성, 기본값 |
| 영 방향 근사 | 0을 향해 절삭 | 3 | -3 | truncate, 정수 나눗셈처럼 |
| 하향 근사 | -∞ 방향으로 | 3 | -4 | 항상 아래로 |
| 상향 근사 | +∞ 방향으로 | 4 | -3 | 항상 위로 |
2.4.5 부동소수점 연산
- 정확하지 않은 경우가 많다 → 근사값값
- 분배, 교환, 결합법칙이 성립하지 않는다