내가 보려고 만든 CS지식

고정소수점과 부동소수점, 정규화,비정규화

study note 2025. 8. 3. 19:30
반응형

❰고정소수점과 부동소수점, 오버플로와 스케일 팩터❱

-고정 소수점과 부동소수점(floating point)에 대해 알아보며 

부동소수점에서의 정규화와 비정규화에 대해 알아 보겠습니다.

 

▶ 고정소수점이란?

고정소수점은 실수(소수 포함)위치가 미리 고정된 수의 표현 방식입니다. 즉, 정수 부분과 소수 부분의 자릿수를 미리 정해놓고 해당 자릿수 내에서만 값을 표현합니다. 16비트 고정 소수점 표현 방식에서 8비트를 정수 부분, 8비트를 소수 부분으로 할당하는 경우, 정수 부분은 -128부터 127까지 표현 가능하며, 소수 부분은 1/256 단위로 표현 가능합니다.

부동소수점보다 연산 속도는 빠르지만 표현 범위는 좁고, 오버플로에 민감합니다.

조금 더 쉽게 말하자면, 실수의 소수점은 '코드나 설계자가 고정'을 하며 실수를 정수값으로 변환해서 저장하는 방식입니다.

1.5라는 소수점을 예로 들어서 계산 해보겠습니다.

스케일 팩터를 소수 8비트(x256배율)로 고정하여 소수점을 표현 해보겠습니다.

계산식 : 1.5x256 = 384

저장값 : 384(정수형으로 저장)

다시 정수를 실수로 해석 할 때  : 384 / 256 = 1.5

이 과정에서 1.5라는 실수는 정수값으로 저장되고,  
소수점의 위치는 항상 8비트(1/256 단위) 뒤에 있다고 가정합니다.  
즉, 소수점의 “값”은 고정되지 않지만, “위치”는 변하지 않습니다.

그리고 스케일 팩터는 꼭 256으로 고정할 필요없이 1024, 65536등으로 설계목적에 따라 변경하셔도 상관없습니다.

스케일이 클수록 표현 단위는 더 세밀해져 정밀도는 높아지지만,  동시에 표현할 수 있는 값의 범위는 좁아지고 오버플로우의 위험성은 증가합니다.

 

▶부동 소수점이란?

부동 소수점은 실수(소수 포함)를 표현 할 수 있도록 만든 표준 방식(IEEE 754)으로 소수점 위치가 '유동적' 입니다.

부동이라고 하여서 不(아닐부) 動(움직일동)이 아닌 浮(뜰부)動(움직일동)을 사용하여 "떠나니는 수" 라고도 불립니다.

고정 소수점과 비교하면 이해가 쉽습니다.

소수점 설명
고정 소수점 소수점의 위치가 코드 설계에 따라 '고정'되어 있습니
부동 소수 소수점의 위치가 숫자의 크기에 따라 '변경 가능'하다는 특징이 있습니다.

컴퓨터에서 부동 소수점을 표현할 때  지수와 기수를 나누어 저장합니다. 이 구조를 통해 넓은 범위의 수를 표현할 수 있으며, 상대적으로 오차도 줄일 수 있습니다.

✿IEEE754?
IEEE 754란부동 소수점 연산을 위한 이진 표현, 정밀도, 반올림 방식, 예외 처리등을 정의한 국제 표준입니다.
1985년 미국 전기전자기술자협회(IEEE)가 처음 제정하였고 현재까지 가장 널리 사용되는 부동 소수점 표현 방식 입니다.
현대의 대부분의 프로그래밍 언어나 하드웨어(FPU)는 IEEE754 형식에 기반하여 실수형을 처리합니다.

 

▶부동소수점 계산법

부동소수점을 계산법(IEEE 754 방식)을 단계 별로 정리 하여 보겠습니다.

 

📌먼저 1단계 입니다.

IEEE 754는 위 설명도 있지만 짧게 설명하면 부동소수점을 비트 단위로 나누어(분해하여) 저장하는 표준 방식 입니다.

대표적으로 32비트(float)와 64비트(double) 방식이 사용되며, 각 비트는 다음 세 가지 요소로 나뉩니다.

먼저, 32비트(float)에 기준입니다.

요소 비트 수 설명
부호(Sign) 1비트 0 = 양수, 1=음수
지수(Exponent) 8비트(0~255) Bias = 127, 실지수 = 저장값 -127
가수(Mantissa) 23비트 소수부 정밀도(약 소수점 7자리 정확도)

그리고 64비트(double)의 기준입니다.

요소 비트 수 설명
부호(Sign) 1비트 0 = 양수, 1=음수
지수(Exponent) 11비트(0~2047) Bias = 1023, 실지수 = 저장값 -1023
가수(Mantissa) 52비트 소수부 정밀도
(약 소수점 15~17자리 정확도)
✿Bias(편향값)란?
지수 표현 범위를 음수까지 확장하기 위해 사용하는 보정 값 입니다.
컴퓨터가 음수 지수를 직접 저장하지 못하기 때문에 사용 하며 일단 다 +127(또는 1023등)을 더해서 양수처럼 저장해놓고 나중에 다시 계산할 땐 그냥 127을 빼서 원래 값으로 돌리는 역할을 합니다.
즉, 컴퓨터는 지수를 저장할 때 01111111(127), 10000000(128) 이렇게 비트를 부호 없는 정수로 해석 하며 양의 정수로만
저장하는데 이 때문에  -127, -128, 2⁻³ = 0.125, 2⁰ = 1, 2³ = 8 이런 표현이나 음수의 수를 직접 저장하지 못합니다 그래서 이걸 어떻게 저장할지 생각하다가 해결책으로 나온게 Bias(편향값)입니다. 
편향값에서 32bit는 127, 64bit는 1023이 고정된 상수로 적용 됩니다.
예를 들어 2³ = 8을 표현하려면실제 지수는 3이지만저장할 때는3 + 127 = 130이 저장됩니다.이 130이 바로 "가짜 지수값"이며계산 시에는 다시130 - 127 = 3으로Bias를 빼서 복원합니다.

각 요소 역할을 설명 하겠습니다

부호(Sign) :

숫자가 양수(0) 또는 음수(1) 인지를 나타내며 부동소수점 비트의 가장 앞에 위치합니다.

 

지수(Exponent):

수의 크기(범위) 를 결정하며, 소수점의 위치를 왼쪽/오른쪽으로 얼마나 이동할지를 뜻합니다.  
저장될 때는 Bias(편향값)를 더해 저장됩니다.  예: 32비트(float)에서는 실제 지수 +127, 64비트(double)에서는 +1023

 

 

가수(Mantissa):

유효숫자부, 즉 `1.101101...` 처럼 정규화된 실수에서 소수부만 저장 됩니다.  조금 쉽게 설명하면  1.xxxxx 중 xxxxx 부분만 저장된다는 겁니다. float에서 23비트, double에서 52비트이며 정확도를 의미 합니다. 맨 앞의 1은 생략(암묵적 정규화, implicit 1) 합니다.

📌2단계는 직접 계산을 해보는 형식으로 실습해보겠습니다.

5.75를 IEEE 754 32bit 부동소수점 형식으로 변환해보겠습니다.

처음에는 부호비트(Sign bit)를 양수인지 음수인지 확인을 합니다.

5.75 양수이며 부호는 0입니다.

그리고 정수 부분 5를 이진수로 변환 하겠습니다.

5 = 101

그 후 소수 부분 0.75도 이진수 변환을 합니다.

0.75x2 = 1.5(1)

0.5 x2 =1.0(1)

따라서,

0.75 = 0.11

전체 이진수 변환 값

101.11

이진부 변환이 완료 되었으면 

정규화를 해주면 되겠습니다.

참고로 이부분에서 0.75소수를 이진수 변환할때 2를 곱하는 이유는 소수점 부분이기도 하며 
정수는 2로 나누고 나머지를 역순으로 쓰지만 소수는 2를 곱하고 정수부분을 순서대로 기록해서 그렇습니다.
즉 처음에 0.75x2를해서 1.5가 나왔으면 정수부 1을 기록 그리고 그 다음 계산에서 남은 소수점 0.5x2를 하여 1.0의 값을 도출하여 1을 기록합니다 그 후 두 수를 이어 붙여 0.11이라는 결과를 도출하는 것 입니다.

해당 값을 정규화 하면 1.0111x2^2가 나옵니다.

이때 소수점이 왼쪽으로 2칸 움직이므로 양수값으로 2의 2지수가 나오는 것입니다.

정규화를 완료 하였으므로 Bias적용하여 지수를 보정하겠습니다.

float는 bias값 127이고 지수의 값이 2이므로 2+127 = 129라는 보정값이 나오며 

129를 float기준으로 8비트 2진수로 변경하면 129 = 10000001이 나옵니다.

이제 부호와 지수의 결정 까지는 완료 하였고 최종적으로 가수를 결정하겠습니다.

처음 부호에서 이진수화된 정규화 값 1.0111의 값에 float가수의 비트 수 인 23비트를 적용시켜 줍니다.

1.은 저장되지 않는 암묵적인 값이니까 0111의 뒤에 23비트를 적용하여 0을 19개 채워 23비트를 만들어 줍니다.

01110000000000000000000이라는 값이 나오며 가수 결정까지 완료입니다.

부호 : 5.75 = 1.0111x2^2

지수 : 1.0111x2^2 = 127(bisa)+2(2^2) = 129 = 10000001

가수 : 01110000000000000000000

최종 결과 값(비트열)은 

0 10000001 01110000000000000000000

사람의 시각에 보기 편하게 한 값은

1. 01000000101110000000000000000000

입니다. 컴퓨터는 IEEE754의 표준 규격에 따라 1이 암묵적으로 있는 값인 걸 알기에 표기는 따로 하지 않습니다.

 

▶정규화와 비정규화

부동소수점에서의 정규화와 비정규화에 대해 알아보겠습니다.

정규화란, 부동소수점 표현에서 정규화란 실수를 항상1.XXX × 2^E 형태로 나타내야 하며 (이걸 "정규화된 부동소수점"이라고 부름)즉, 항상 1.xxx * 2의 지수로 나타내야합니다. 이는 IEEE 754 표준의 규칙으로, 가장 앞에 있는1은 항상 있다고 가정하고,저장할 필요가 없습니다. 따라서, 정규화를 통해소수점 위치를 조정해서 앞에1. 이 오도록 만들어야 함. 134.503이라는 값이 있다고 가정하고 이 부분을 정규화하면 1.34503이라는 정규화된 부동소수점 표현이 나오는것입니다. 그럼 지수 값은 어떻게 구하나? 2의 지수라고만 표시 되있는데? 이 경우 지수 값은 134.503에서 1.까지의 이동한 칸 수를 적용 시키면 됩니다. 
1.34503이 나오기 위해 소수점이 왼쪽으로 이동한 칸수는 2칸이며 지수는 1.34503 x 2^2라고 보시면 됩니다.
그럼 0.011 같은 경우는? 이거는 오른쪽으로 소수점이 이동하여 정규화를 해야하기때문에 1.1이라는 값이 나오고 지수값은 -2입니다. (왼쪽은 양수, 오른쪽은 음수)

꼭 2진수로만 정규화를 하고 부동소수점을 만들어야하는가? 라는 의문도 드실텐데 10진수도 가능하고 16진수도 가능합니다. 범용성이 가장 좋고 넓은게 2진수여서 2진수를 기반으로 학습하는것입니다. 추후 10진수나 16진수가 필요하게 될 경우 따로 정리하겠습니다.

 

비정규화란, 부동소수점 표현에서 정규화 규칙(1.xxx × 2^E)을 따를 수 없을 정도로 작은 값을 표현 할 때 사용하는 방식입니다.

즉, 값이 너무 작아서 정규화 하면 표현 자체가 불가능하거나 정밀도가 크게 손상되는 값을 다룰 때 사용합니다.

0.00000000000000000000000000000000001이라는 값이 있는데 이걸 정규화 하면 지수가 너무 작아 지기 때문에 지수 비트를 전부 0으로 설정하면 비정규화로 간주하고 이때는 정규화의 암묵적 1이 존재하지 않습니다.

수식은 0.xxx... × 2^(1 - Bias)이며 정규화는 1.xxx × 2^(E - Bias)지만, 비정규화는 고정된 지수 값 1 - Bias로 계산한다고 보시면 됩니다.

항목 정규화 비정규화
표현 수식 1.xxx × 2^(E - Bias) 0.xxx × 2^(-126) (float 기준)
지수 값 1~254 0 (고정)
가수 의미 소수부(23비트) 실제 수 전체 (0.xxx)
실지수 E 저장값 - 127 1 - 127 = -126
암묵적 1 1.xxx (있음) 0.xxx(없음)
목적  일반적인 실수 표현 아주 작은 수 표현 (underflow 방지)

비정규화가 왜 필요하고 중요한지 최종 요약은

부동소수점이 0 근처 수를 연속적으로 표현 가능하게 해주며, 만약 비정규화가 없다면, 정규화로 표현 못 하는 작은 수는 그냥 0이 되며, 수치해석, 과학 계산 등에서 연산 연속성 유지에 매우 중요합니다. 다시, 비정규화란 비정규화란, 너무 작아서 정규화 규칙을 따를 수 없는 수를 위해 지수를 0으로 고정하고 암묵적 1 없이 표현하는 방식을 의미하는 것입니다.

 

 

 

 

반응형