실수 표현 방법
- 컴퓨터에서 실수를 표현하는 방법은 고정 소수점과 부동 소수점 두 가지 방식이 존재한다
고정 소수점(Fixed Point)
- 소수점이 찍힐 위치를 미리 정해놓고 소수를 표현하는 방식
- 정수 + 소수
- 간단히 말하면 10진수를 2진수로 바꿨다면 그대로 박아 넣는 방식
- 7.625라는 실수가 있다면 이를 2진수로 바꾸면 111.101이 될 것
-3.141592는 부호(-)와 정수부(3), 소수부(0.141592) 3가지 요소 필요함
- 장점
- 실수를 정수부와 소수부로 표현하여 단순하다
- 단점
- 표현의 범위가 너무 적어서 활용하기 힘들다.
- 정수부 15bit, 소수부 16bit
부동 소수점(Floating Point)
- 실수를 가수부 + 지수부로 표현한다
- 가수 : 실수의 실제 값 표현
- 지수 : 크기를 표현함. 가수의 어디쯤에 소수점이 있는지 나타냄
- 지수의 값에 따라 소수점이 움직이는 방식을 표현한 실수 표현 방식
- 즉, 소수점의 위치가 고정되어 있지 않는다.
- 장점
- 표현할 수 있는 수의 범위가 넓어진다.
- 현재 대부분 시스템에서 활용 중
- 단점
- 오차가 발생할 수 있다.
- 부동 소수점으로 표현할 수 있는 방법이 매우 다양함
부동 소수점 표현 방식
- 부동 소수점에서는 2진수로 변환한 결과를 그대로 박아넣지 않고 몇가지 방식을 추가로 거친다.
정규화(Normalization)
- 정규화는 수학이나 컴퓨터 분야에서 다양한 의미로 사용된다.
- 부동 소수점에서 정규화는 2진수를 1.xxxxx... * 2^n 꼴로 변환하는 것을 말한다.
- 변환 방식은 간단하다.
- 정수부에 1만 남을 때까지 소수점을 왼쪽으로 이동 시키고 이동한 칸 수 만큼 n자리에 집어 넣으면 된다.
- 예) 111.101을 정규화하면 1.11101 * 2^2
- 소수점을 이동 시키기 때문에 부동 소수점이라는 말이 나온 것
IEEE 754 부동 소수점 표현
- IEEE 표준에 따르면 부동 소수점 방식으로 실수를 저장하는 데는 32bit나 64bit가 사용된다.
- 32bit 기준으로 아래와 같은 구조를 가진다.
- 부호 bit는 0이면 양수 1이면 음수를 의미
- 23bit의 가수부는 정규화 결과 소수점 아래에 있는 숫자들을 왼쪽 그대로 넣으면 된다.
- 이때 남은 자리는 0으로 채운다.
- 8bit의 지수부에는 bias라고 불리는 지정된 숫자를 더한 다음 넣어야한다.
- IEEE 표준에서 32bit의 경우 bias는 127로 규정하고 있다.
- 따라서 2 + 127 = 129를 2진수로 바꾼 10000001이 들어 간다.
- 7.625는 컴퓨터에서 아래와 같이 저장
- bias 값을 사용하는 이유는 지수가 음수가 될 수 있기 때문
- 지수부의 값이 음수가 될 경우 지수용 부호 비트를 사용해야 한다.
- 따라서 8자리로 음수와 양수를 표현하지 않고 0 ~ 127 구간은 음수, 128 ~ 255 구간은 양수로 표현
- 32bit 체계를 32비트 단정도(Single-Precision), 64bit 체계를 64비트 배정도(Double-Precision)이라고 부른다.
- 프로그래밍 언어에서 실수형 타입 float는 전자, double은 후자에 해당한다
Float와 Double
- 코딩 테스트 문제를 풀던 중 나누기 연산을 해야하는 문제가 있었다.
- 나누기 연산 후 소수점 아래 N자리 까지 반올림 연산을 해야하기 때문에 float를 사용하여 문제를 해결하고자 하였다.
- 하지만 예시를 모두 맞췄지만 문제를 해결할 수 없는 상황이 일어났다.
- 여러 고민과 주변인에게 조언을 구한 결과 실수의 자료형에 문제가 있다는 것을 알게 되었다.
- 먼저 float는 6자리까지 표현이 가능한 실수 자료형이다. 또한 double은 15자리까지 표현이 가능한 실수 자료형이다.
- 이러한 차이는 정수 부분이 긴 실수 인 경우 문제가 발생할 수 있다.
- 123456789.123을 두 자료형에 넣는 경우
- float의 경우 123456792.000000이라는 값이 담아진다.
- double의 경우 123456789.123000이 담아진다.
- float의 경우 1bit의 부호 비트와 8bit의 정수부분 23bit의 실수 부분으로 이루어져있다.
- double의 경우 1bit의 부호 비트와 11bit의 정수부분 52bit의 실수 부분으로 이루어져있다.
- 이러한 차이는 float의 경우 값의 길이가 커지는 경우 근사 값을 사용하는 문제가 발생할 수 있다.
- 무한 소수가 변수 공간에 담아지는 경우 자료형 크기에 따른 소수점 절삭으로 인해 오차가 발생할 수 있다.
- 0.1을 예로 들어보면 0.1이라는 값은 보기에는 간단한 값이지만 2진수로 바꾸면
- 0.0001100110011... 인 무한 소수가 된다.
- 물론 기본 출력 시 0.100000이 나오겠지만, 10자리 까지 출력하게 된다면 0.1000000015가 출력된다.
- 무한 소수 문제는 더 큰 자료형인 double을 사용하면 해결할 수 있다.
- 결론적으로 소수점 연산 시 float보다 double을 사용해야한다.
(출처)
https://jimmy-ai.tistory.com/64
https://gsmesie692.tistory.com/94
https://github.com/gyoogle/tech-interview-for-developer/tree/master
'CS > Computer Architecture' 카테고리의 다른 글
[Computer Architecture] 패리티 비트와 해밍 코드 (0) | 2024.03.26 |
---|---|
[Computer Architecture] 캐시 메모리(Cache Memory) (0) | 2024.03.24 |
[Computer Architecture] 중앙처리장치(CPU) 작동 원리 (0) | 2024.03.24 |
[Computer Architecture] 컴퓨터의 구성 요소 (0) | 2024.03.24 |