노력과 삽질 퇴적물

2진수와 부동소수점 표현 본문

프로그래밍note/CS 기초

2진수와 부동소수점 표현

MTG 2024. 1. 14. 20:39
목차
 1. 주요 진법
 진수 변환, 정수
 진수 변환, 소수점
 진수 간의 변환
 2. 정수
 부호가 없는 정수
 부호화-크기
 1의 보수
 2의 보수
 3. 실수와 초과 표기법
 주요 개념
 계산법
 미분류






1. 주요 진법
 
-> "컴퓨터에 저장할 수 있는 최소의 데이터 단위로서 비트(bit: binary digit)가 있다. 비트는 0과 1로 구성되는데, 여기서 0과 1은 수치적인 의미가 아니라 단순한 기호에 불과하다. 즉, 두가지 상태중에서 각각의 상태를 표현하기 위한 기호"  (p.15, 컴퓨터과학개론, 2021)
-> 컴퓨터의 모든 명령은 워드(word)단위 일지라도 컴퓨터에서 숫자를 표현하는건 결국 2진수. 16진수는 주소값 표기에서 많이 보긴 했어도 8진수는 무엇에 쓰길래 예제등 주요 진법에 포함되는건가 해서 봤더니만, 미니 컴퓨터에서 쓰였다고 하는걸 봐서는 C드라이브 앞의 영구 결번같은 레거시? 계산 및 연산상 2진법과 16진법 중간 타협안도 가능?
 
 

1) 진수 변환, 정수

예시.
-> 10진수를 변환시키고자 하는 진수로 계속 나눠주는겁니다. 나머지값도 계속 이어질텐데, 더 이상 나눌수 없을때 위의 예시 이미지처럼 가장 마지막으로 나온 나머지가 맨 앞입니다.
-> 16진수는 10=a, 11=b, 12=c, 13=d, 14=e, 15=f
 
 
2) 진수 변환, 소수점
예시.
-> 0보다 큰 수는 변환 시킬 진수의 값으로 계속 나눴으나, 소수점 밑은 반대로 곱해야 합니다.
-> 곱셈 하는 부분을 굳이 저리 한 곳으로 뭉쳐서 예시를 보인 이유는 곱셈을 할 때마다 나오는 값에서 1의 자리만 뽑아다 쓰고, 소수점 밑만 계속 곱셈에 투입하는걸 손계산으로 속도 높여서 하니 저리 됩니다.
 
 
3) 진수 간의 변환
-> 정확히는 10진수를 뺀 2/8/16 진수간의 변환입니다.
-> 역으로 8/16진수에서 2진수로 변환시킬때 각 숫자를 2로 나누되 8진수면 3칸씩 고정, 16진수면 4칸씩 고정시켜서 2진수로 써내면 됩니다. (어찌보면 숫자2를 이용한 압축과 해제가 겹쳐보이는 진수 변환.)





2. 정수
 
-> 게임 클라이언트, 앱, DB 개발에서 흔하게 보는 unsigned와 signed를 비트에서의 연산으로 보는겁니다.

1) 부호가 없는 정수
-> N비트가 있다면 입력 가능한 자릿수도 총 N개. 부호가 있는 정수는 최상위 1비트(MSB. Most Signification Bit)인 부호 비트가 맨 앞에 있어서 나머지 N-1비트로 숫자를 표현. 가령 16비트인 short와 32비트인 int에서 부호 여부에 따라 처리 가능한 숫자 범위가 아래와 같이 달라진다.
  C++ C#
unsigned short
(signed short)
0 ~ 65,535
(-32,768 ~ 32,767)
0 ~ 65,535
(-32,768 ~ 32,767)
unsigned int
(signed int)
0 ~ 4,294,967,295
(-2,147,483,648 ~ 2,147,483,647)
0 ~ 4,294,967,295
(-2,147,483,648 ~ 2,147,483,647)
-> 2^16=65,536와 2^32=4,294,967,296로 계산되는것과 달리
실제 문서에는 65,535와 4,294,967,295로 나오는건 0을 표현해서 범위가 조금 달라 보일뿐 범위에 대한 절대값으로 보면 일치한다. (0~65,535 → 총 65,536개의 숫자값)
-> N비트 정수형 변수의 최대값 = (부호가 없다)? (2^N)-1 : (2^(N-1))-1
 
 
 
2) 부호화-크기
-> 절대값으로 처리하기 때문에 N비트가 주어지면 부호 비트 없이 N칸 전체를 사용한다.
 
 
3) 1의 보수
-> 2진수로 변환하고 부호 표기에 쓰이는 맨 앞자리 비트만 빼고 나머지 비트에서 0은 1로. 1은 0으로 바꿔준다.
-> BUT! +0과 -0이 가능해져 0에 대한 모호성이 발생하는 단점.
예시.
(* 8비트를 기준으로 적용.)
47[10] 0010 1111[2] → (1의 보수 적용) 0101 0000
-47[10] 1010 1111[2] → (1의 보수 적용) 1101 0000
 
 
 
4) 2의 보수
-> '1의 보수' 결과에 +1을 처리.
-> 0에 대한 표헌은 +0만 있고, -0이 없어지면서 음수에서 표현 가능한 가짓수가 하나 더 늘어남. 즉, N비트면 -(2^(N-1)) ~ +(2^(N-1) - 1)의 범위
예시.
(* 8비트를 기준으로 적용.)
47[10] 0010 1111[2] → (1의 보수 적용) 0101 0000 →(+1)→ 0101 0001
-47[10] 1010 1111[2] → (1의 보수 적용) 1101 0000 →(+1)→ 1101 0001
 
 



3. 실수와 초과표기법
 
1) 주요 개념
[그림. 부동 소수점 표현][#출처]
 
(-1)^S x M x 2^E
S:  부호비트 제어 S={0, 1}
M: 가수(mantissa)
E:  지수(exponent)
* 해당 공식은 컴퓨터는 2진법이 기본이라, 기저(base)는 2로 고정.
-> 과학적 표기법을 바탕으로 표현된다.
-> "가수를 표현할 때는 표준화된 형식이 필요하다. ...(중략)... 가수 표현에서 소수점의 위치를 통일시키면 더욱 쉽게 나타낼 수 있으므로 소수점 바로 왼쪽에서 오직 하나의 1만 있도록 소수점의 위치를 조정하는 정규화(normalization)과정을 거친 후에 가수를 저장한다."
(p.29, 컴퓨터과학개론, 2021)
예시. 정규화
0.000011011 → 1.1011         x 2^(-5)
10001.10101 → 1.000110101 x 2^(4)
-> 매직넘버(magic number): '부동소수점'에서 지수 부분을 정수를 표현하는 방법을 말한다. 지수값 표현을 위해 할당된 N비트가 있으면 2^(N-1)이나 (2^(N-1) - 1)가 매직넘버(magic number)값이 된다.
예시. 매직넘버 계산
시스템이 부동소수점을 표현할 16비트중 지수 부분에 4비트를 할당한다.
2^3  or  (2^3)-1 → 초과_8  or  초과_7. 총 2개의 매직넘버가 생성.
 
 
2) 초과표기법 계산
예시.
컴퓨터 시스템이 부동소수점 연산을 위해 16비트중 지수 부분에 지수 부분에 4비트를 할당했고, 매직넘버는 초과_7로 정해졌다. 해당 시스템에서 2.875[10]인 실수를 부동소수점 방식으로 표현하면?
2[10] + 0.875[10] → (2진수) 10.111[2] → (정규화) 1.0111 x (2^1)
지수+매직넘버7=8[10]을 4비트 2진수로 바꾸면 1000[2]. 가수에는 소수점 부분만.
0    1000    01110000000
(+)  4비트   11비트


3) 미분류
-> 이러나 저러나 항공 과학같은 특수한 케이스는 예외로 쳐도 float은 가급적 안 쓰는게 좋습니다. 만약 범위가 큰 수를 다뤄야 하면 double이고, 토이 프로젝트때도 점수 계산을 위해 0으로 초기화 해놓고 계산을 진행해도 어느 순간 값이 딴판이 되더라고요.
-> 혹은 달러와 센트표기처럼 소수점이 필요한 금융권이면 decimal같은걸로 쓰는게.





기타. 읽을거리
 
1996년 아리안5(Ariane 5) 로켓 폭발
-> float에서 int로 캐스팅하면서 발생한 오버플로우로 대규모 예산이 폭발한 사고중 하나.

* 흑백 컴퓨터 시절 쯤 부동소수점 버그가 발견되서 해당 버그에 대한 패치를 적용 한 걸 교환 했던 컴퓨터 역사 항목에 나오는 무슨 사건이 있었는데, 지금 찾으려고 못 찾고 있습니다. 제보 간절히 바랍니다.





기타. 참조자료
 
1) 서적
이관용, 정광식 저. 컴퓨터과학개론, 한국방송통신대학교출판문화원, 2021년.
 

2) 웹페이지-한국어
부동 소수점 수 - tcpschool (접속: 2024-01-13)
부동 소수점의 이해 [#1부] [#2부] - devocean (접속: 2024-01-13)
숫자를 부동소수점 방식으로 표현하기 - codetorial (접속: 2024-01-13)
위키백과
부동소수점 (접속: 2024-01-13)
8 진수 시스템 - riverglennapts (접속: 2024-01-13)
Baekjoon Online Judge
부동소숫점 오류 (접속: 2024-01-13)
 
learn.microsoft.com
C++, C 및 어셈블러/데이터 형식 범위 (접속: 2024-01-13)


3) 블로그
1996년 숫자 전환 버그로 인한 Ariane 5 로켓 폭발 사고 :: 소프트웨어 테스팅 노트 (접속: 2024-01-13)





기타. 변경이력

일자
 변경이력
 2024-01-13  초안 작업 시작.
 2024-01-14  초안 공개 [#blogger] [#티스토리]
 2024-01-24  '초과표기법 계산'의 예시오류 수정