[4일차 과제]
2026. 5. 22. 17:42ㆍKDT/과제
1. 컴퓨터에서 음수를 표현하는 방법
- 부호 비트(Sign Bit)란 무엇인가?
- 컴퓨터가 이진수로 숫자의 양수와 음수를 구분하기 위해 사용하는 가장 왼쪽 (최상위) 비트
- MSB : Most Significant Bit로 최상위 비트값을 의미하고 2의 보수에서는 부호 비트를 의미
- LSB : Least Significant Bit로 최하위 비트값을 의미
- 0은 양수(+) / 1은 음수(-)
- signed : 부호비트를 포함한 데이터 형태. 양수와 음수 모두 표현
- unsigned : 부호비트를 포함하지 않음. 부호가 없는 만큼 양수 표현 범위가 2배 (0포함)
- 컴퓨터가 이진수로 숫자의 양수와 음수를 구분하기 위해 사용하는 가장 왼쪽 (최상위) 비트
- 보수란?
- 두 수의 합이 진법의 밑수(N)이 되게 하는 수
ex. 10진수 4의 보수는 6이고, 10진수 2의 보수는 8 - 보수는 컴퓨터에서 음의 정수를 표현하기 위해 고안됨
- 컴퓨터 내부에서 사칙연산을 할 때, 덧셈을 담당하는 가산기(Adder)만 이용하기 때문에 뺄셈을 덧셈 형식으로 변환하여 계산해야함
즉, A - B는 A + (-B)로 계산
- 두 수의 합이 진법의 밑수(N)이 되게 하는 수
- 1의 보수(One's Complement)란 무엇인가?
- 각 자리 수의 합이 모두 1인 수에서 주어진 2진수를 빼면 1의 보수를 얻을 수 있음
- 컴퓨터 연산으로는 NOT연산
ex. 2진수 1010의 1의 보수는 0101 - 양수와 음수를 대칭적으로 만들고 싶었음
- 1의 보수의 문제점 :
- 0이 두 개 존재 : +0 (00000000), -0 (11111111)
- 덧셈이 이상 : 5+ (-5) = 00000101 + 11111010 = 11111111(=-0)
(end-around carry 같은 추가 작업 필요) - 사칙연산 과정에서 오버플로우가 발생할 수 있음
ex. 양수 7과 6의 1의 보수로 음수를 구한 후 각각 구해서 더하여라 (단, 7과 6을 4bit로 표현해서 진행)
7 = 0111 (2) -> 1의 보수 : 1000 (2) = -7
6 = 0110 (2) -> 1의 보수 : 1001 (2) = -6
두 수의 합은 -13이 나와야하지만 2진수 합은 10001로 4bit 범위를 초과하여 오버플로우
- 2의 보수(Two's Complement)란 무엇인가?
- 1의 보수의 한계를 극복한 계산 방법 (0이 하나만 존재)
- 1의 보수에 1을 더한 값과 같음
ex. 2진수 1010에 대한 1의 보수 0101을 구한 후, 1을 더해 0110 - 물론 2의 보수도 오버플로우가 발생할 수 있지만 1의 보수보다는 경우의 수를 훨씬 더 줄여줌
ex. 양수 7과 음수 6의 2의 보수로 음수를 바꾼 후 각각 구해서 더하여라 (단, 7과 6을 4bit로 표현해서 진행)
7 = 0111 (2)
6 = 0110 (2) -> 2의 보수 : 1010 (2) = -6 (1이 왼쪽으로 넘어간다. 캐리라고 함)
0111 (2) + 1010 (2) = 0001 (2) = 1 (캐리된 것은 버림)
- 1의 보수와 2의 보수의 차이점
| 구분 | 1의 보수 | 2의 보수 |
| 변환 방법 | 각 자리의 비트 반전 (NOT) | 1의 보수에 1을 더함 |
| 0의 표현 | +0 (0000)와 -0 (11111)로 0이 두 개 | 0000으로 0이 하나만 존재 |
| 연산 효율성 | 0이 두 개이기 때문에 연산 회로 복잡 | 0이 하나이므로 회로 단순, 연산속도 빠름 |
- 왜 현대 컴퓨터는 대부분 2의 보수를 사용하는가?
- 우선 보수를 사용하는 이유 :
- 가산기 레지스터 때문
(보수 설명 시 언급했듯이 컴퓨터 내부에서 사칙연산을 할 때, 가산기만 이용하기 때문) - 양수, 음수의 표현 때문
- 가산기 레지스터 때문
- 1의 보수를 사용하면 비트 전환만 수행하면 되기 때문에 더 빠르고 효율적이라고 생각할 수 있지만
0을 표현하는 과정에서 문제가 발생함- 0101 - 0101 -> 0101 + 1010 = 1111
- 0000, 1111 두 가지 모두 0을 표시하는 방법이 됨
- 프로그램 코드 중 두 값을 비교하는 과정에서 비트를 비교하는 방식이라면
- 0000 == 1111
- 결과값이 False로 나올 수도 있고, 한 쪽의 값을 보수 취해서 같다는 것을 판별해야하는 번거로운 상황이 발생할 수 잇음
- 2의 보수를 사용한다면?
- 0101 - 0101 -> 0101 + 1011 = 10000
- 최상위 캐리비트 1을 저장하지 않고 버리면 결과가 0000
- 우선 보수를 사용하는 이유 :
2. 1.1 + 0.1 == 1.2 가 False가 나오는 이유
- 부동소수점(Floating Point)이란 무엇인가?
- 컴퓨터에서 실수를 근사하여 표현하는 방식
- 부동은 한자로 떠다닌다( 浮 )는 뜻. 영어로는 Float
- 즉, 소수점이 고정되지 않고 데이터의 크기에 따라 좌우로 유동적으로 움직일 수 있다는 의미

- IEEE 754 표준이란 무엇인가?
- 컴퓨터 프로세서와 하드웨어에서 소수(실수)를 표현하고 연산하기 위해 제정된 가장 널리 쓰이는 국제 표준
- 현대 컴퓨터는 부동 소수점을 표현할 때 국제 표준인 IEEE 754를 주로 사용
- 하나의 데이터를 세 부분으로 나누어 저장
- 부호부(Sign) : 양수(0)와 음수(1)을 결정하는 1bit
- 가수부(Mantissa) : 실질적인 유효숫자를 기록하는 23bit (float 기준)
- 지수부(Exponent) : 소수점의 위치를 결정하는 8bit (float 기준)

- 컴퓨터는 왜 10진수를 2진수로 변환해서 저장하는가?
- 컴퓨터가 전기적 신호의 ON, OFF만 구별할 수 있는 하드웨어(트랜지스터)로 구성되어 있기 때문
- 인간은 10진수를 사용하기 때문에 처음 컴퓨터를 만들었을 때 전기 신호로 10진수를 나타내기 위한 시도가 있었다. 그러나 진공관에서의 10진수 표기는 굉장히 까다로웠다. 최초의 컴퓨터인 ENIAC(에니악)이다. 어느 위치에 있어야 0, 1, 2 등을 나타낼 수 있는데 (전압의 높고 낮음을 구별해야) 이를 안정적으로 유지하기에는 어려움이 있었다. 이를 개선하여 만든 것이 폰노이만의 컴퓨터이다. 진공관에서 흐른다, 흐르지 않는다라는 개념에서 시작한 2진법은 굉장히 오류를 최소화 할 수 있었다. 그렇기 때문에 지금의 2진법으로 이루어진 컴퓨터가 만들어 진 것이다.
- 왜 일부 10진수는 2진수로 정확하게 표현되지 않는가?
- 10진수 소수는 유한한 자리 수로 떨어지더라도, 2진수로는 무한 소수가 되어 컴퓨터에서 정확하게 표현할 수 없는 경우가 있음. 그 이유는 각 진법에서 값을 나타내는 '소수(Fraction)'의 원리 때문.
- 10진수 소수 : 10^(-1), 10^(-2) 등 10의 거듭 제곱으로 표현
- 2진수 소수 : 2^(-1), 2^(-2) 즉 0.5. 0.25 등 2의 거듭 제곱으로 표현
- 정확히 표현할 수 없는 이유
- 10진수에서 간단한 분수인 0.1을 2진수로 변환하려고 하면
0.1 x 2 = 0.2 -> 0
0.2 x 2 = 0.4 -> 0
0.4 x 2 = 0.8 -> 0
0.8 x 2 = 1.6 -> 1 (정수부 추출)
0.6 x 2 = 1.2 -> 1
0.2 x 2 = 0.4 -> 0 (다시 0.4로 돌아감)
=> 이 과정이 끊임없이 반복되기 때문에 2진수 0.1은 0.0001100110011... 과 같이 무한 소수가 됨
(유한한 공간에 값을 욱여넣다보니 미세한 오차 발생)
- 10진수에서 간단한 분수인 0.1을 2진수로 변환하려고 하면
- 해결 방식 (부동소수점 오차)
- 컴퓨터(CPU)는 메모리 한계 때문에 무한 소수를 끝까지 저장하지 못하고, 정해진 자리수 (보통 32, 64bit)에서 반올림하여 값을 잘라낸 후 저장
- 이로 인해 미세한 오차가 발생하는데 이를 부동소수점 오류(Floating-point error)라고 함
- 10진수 소수는 유한한 자리 수로 떨어지더라도, 2진수로는 무한 소수가 되어 컴퓨터에서 정확하게 표현할 수 없는 경우가 있음. 그 이유는 각 진법에서 값을 나타내는 '소수(Fraction)'의 원리 때문.
- 부동소수점 오차는 실제 개발에서 어떤 문제를 발생시키는가?
- 무한 루프 및 조건문 버그 : A == B 형태의 단순 비교가 예상대로 작동하지 않음. 겉으로 같아보여도 두 값의 부동 소수점 비트가 미세히 달라 무한 루프에 빠지거나 잘못된 분기문 실행
- 소액 결제나 세금 계산 시 이러한 오차가 누적되면 기업과 고객 간의 금전적 손실이나 신뢰도 하락을 초래
- 게임 3D 그래픽 및 물리 연산 오류 : 캐릭터가 공중에 뜨거나 맵을 뚫고 떨어지거나 벽에 부딪혔을 때 부자연스럽게 떨리는 현상 발생. 좌표와 충돌 판정(히트박스)에 소수점 연산이 개입하기 때문
- 금융/게임/AI 분야에서 소수 오차를 어떻게 처리하는가?
- 정수(Integer) 단위로 변환하여 연산
- 고정밀 라이브러리 사용 : 자바의 BigDecimal, 파이썬의 decimal, 자바스크립트의 BigNumber.js등 십진법 연산을 정확히 지원하는 전용 객체/라이브러리 활용
- 허용 오차 (Epsilon) : ' 두 값이 완전 같은가' 대신에 '두 값이 차이가 허용할 만큼 아주 작은가'를 비교하여 오차를 제어
- 결국 1.1 + 0.1 == 1.2가 False가 나오는 이유는
- 컴퓨터는 10진수가 아닌 2진수를 사용함
- 2진수 소수는 무한 소수 발생
- 컴퓨터의 메모리는 한정되어 있기 때문에 무한 소수를 저장하지 못하고 정해진 자리수에서 반올림하여 저장
- 위 과정에서 미세한 오차 발생
[4일차 과제 후기]
부호비트, 1의 보수, 2의보수에 대한 내용을 대학 수업에서 들었었다. 오랜만에 보는 내용이라 반갑기도 하면서 듣기만 했던 내용을 직접 찾아보니 더 기억에 남을 것 같다. 대학 수업에서는 직접 찾기보다는 교수님의 말을 듣기만해서 + 처음 듣는 내용이라 어렵다고만 생각했었다. 지금 과제로 몰랐던 내용들을 찾아보며 (단순히 GPT를 돌리기보다는 구글링) 모르는 것을 잘 찾는 것도 스킬이라고 생각하며 과제를 수행했다.
특히나 컴퓨터는 2진수로 저장하는 이유는 대학에서 흥미롭게 들었던 내용이라 찾아보기 전에 적어본 후, 서치해보니 이 내용이야말로 정말 반가웠다. 부동소수점의 오차가 개발에 어떤 문제를 발생시키는지는 생각해본적이 없었는데 이 미세한 오차들이 모이면 정말 커다란 문제를 발생시킬 수 있다고 생각하니 앞으로의 개발에서는 조심해야겠다는 생각이 들었다.
아무리 메모리가 커졌다고 해도 정확한 계산을 해내지 못하는 바보 컴퓨터. 나중에는 부동 소수점의 오차도 없앨 수 있는 방법 또는 메모리가 만들어지려나
'KDT > 과제' 카테고리의 다른 글
| [12일차 과제] 시간복잡도, 공간복잡도 (0) | 2026.06.07 |
|---|---|
| [11일차 과제] 자료구조(해시 테이블) (0) | 2026.06.04 |
| [10일차 과제] 자료구조(트리) (0) | 2026.06.03 |
| [9일차 과제] 자료구조(연결 리스트, 이중 연결 리스트) (0) | 2026.06.01 |
| [8일차 과제] 자료구조(배열, 스택, 큐) (0) | 2026.05.31 |