일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- C++
- float
- ft_server
- 함수
- 동적할당
- Double
- nginx
- 42
- 구조체
- python
- phpmyadmin
- 2차원배열
- 42서울
- While
- else if
- 패킹
- iF
- jupyter 단축키
- 42cursus
- C언어
- 포인터
- Class
- 자료형
- vs코드 단축키
- docker
- 42Seoul
- for
- cout
- list
- libft
- Today
- Total
Developer
7.(C언어) 실수 자료형의 표현 방법_부동소수점 본문
컴퓨터에서 0과 1로 소수를 표현하는 방식을 부동소수점 표현 방식이라고 한다.
이에 관한 규약은 IEEE 754라는 표준으로 정해져 있다.모든 소수를 표현할 수 없으므로 근사치를 사용해야 하기때문에 이러한 방법을 사용한다. 이 부분은 나도 배운지 오래되어서 완벽하게 알려줄 수 없으며 관심이 있는 사람만 재미로 보기를 바란다.
IEEE 부동소수점 표준은 수를 $$V= (-1)^{s} * M * 2^{E}$$ 형태로 나타낸다.
1. S는 부호를 나타내며 1이면 음수 0이면 양수 이다.
2. M은 유효숫자로 1과 2-ε사이 또는 0과 1-ε 사이의 값을 갖는다.
3. E는 지수로 2의 제곱으로 자리값을 제공한다.
그러면 이를 컴퓨터에서 어떻게 저장하는지 알아보자
위의 값들을 인코딩하기 위해 3개의 필드로 bit를 나눈다.
부호 비트 S는 한개의 비트로 직접 표현된다.
k비트의 지수 필드 exp는 지수 E를 인코딩한다.
n비트의 비율 필드 frac는 유효숫자 M을 인코딩한다.
이렇게 말해봤자 무슨말인지 나도 모른다. float를 예를 들어 살펴보자
float는 단일-정밀도 부동소수점 형식이다.
float는 4byte 즉 32bit이다.
s = 1bit (부호 비트)
k = 8bit (지수 필드,exp)
n = 23bit (비율 필드=가수 필드, frac)
필드는 위에 작성된 것처럼 나뉘게 된다.
MSB부터 s, k, n 순서로 생각하면 된다.
자 이제 시작이다. 우리는 계속 float를 기준으로 알아가 보자
float값은 exp값에 따라 3가지 경우가 존재한다.
정규화 값, 비정규화 값, 특수 값 3가지 이다. 정규화 값 부터 살펴보자
1.정규화 값(Normalized Values)
exp의 비트 패턴이 모두 0이거나 모두 1이 아닌 경우이다. 이를 정규화 값이라고 한다. 정규화란 쉽게 말하면 1.xxxx * 2^E 형태로 바꾼것을 말하며 xxxxx비트의 표현이 frac에 들어있고 E은 exp 필드를 이용해 구할 수 있다.
정규화 값에서 지수 E=e-Bias 이다. e는 exp필드의 비트 패턴으로 계산하고 Bias 는 2^(k-1)-1 이다. 따라서 float에서 지수는 -126에서 127의 범위를 가진다.
이를 지수의 초과 표현이라고 한다.지수부 8bit를 그냥 사용하게 되면 0~2^255의 지수만 표현할 수 있다. 하지만 작은수를 표현할 수없다. 따라서 00000000을 -127로 정의하고 , 2의 0승을 01111111, 11111111을 128로해 작은 수도 표현할 수 있도록 한것이다. 다음은 가수부인데 M=1+frac(비트순 나열) 로 정의된다. 1을 더해주는 이유는 하나의 비트를 얻기 위함인데 frac에 유효비트를 늘려 더 정밀하게 나타 내기 위함이다. 따라서 앞에는 항상 1이라고 생각하고 조절은 지수 필드에서 수행한다.
한번 정규화 값을 직접 표현해 보자
83.25 라는 값을 표현해보자
우선 2진수로 변환해야 한다. 소수를 2진수로 변환하는것은 정수부와 소수부를 따로 생각하면 된다. 정수부는 2로 계속 나누어주고 소수부는 2를 계속 곱해주면 된다.
2를계속 곱해 소수점 밑이 0이 되도록 한다.
0.25*2=0.5
0.5 *2 =1.0
계산된 결과의 1의 자리를 역순으로 작성하면 2진수 소수 부분이된다.
따라서
83.25
= 0101 0011.01 이 된다.
이제 부동 소수점 형태로 나타내보자
1.xxxx * 2^E승 형태로 만들어 주어6야한다.
1.01001101 * 2^6 이 된다.
따라서 M=1.01001101 이고 frac에는 01001101
E는 6이므로 exp에는 133이 2진수로 들어가게 된다.
83.25를 비트단위로 출력한 결과 화면이다. 우리가 계산한대로 숫자들이 들어있는것을 확인할 수 있다.
2.비정규화 값(Denormalized Values)
exp필드가 모두 0일때 나타낸 수는 비정규화 형태를 가진다.
이경우 지수값 E=1-Base 이고 유효숫자 M=frac이다.
정규화 값과 다르게 유효비트에 1이 없는 수이다.
정규화 숫자는 항상 M이 1보다 같거나 큰 수이므로 0을 나타낼 수 없기때문에 비정규화 값은 숫자 0을 표시하는 방법을 제공한다. 모든 비트가 0이면 +0이며, 부호비트만 1이고 모든 비트가 0이면 -0을 나타낸다. 대충 생각해보면 알겠지만 비 정규화 값은 0.0에 매우 가까운 값을 나타낸다.
3.특수값(Special Values)
위의 경우는 부호비트에 따라 -∞와 ∞를 나타내며 오버플로를 나타낼 수 있다.
아래의 경우 NaN(Not a Number)이라 하며 ∞-∞ 나 √ -1 등의 연산 결과로 리턴한다.
위에서는 float를 예로 들었지만 double도 방식은 똑같으며
s = 1bit (부호 비트)
k = 11bit (지수 필드,exp)
n = 52bit (비율 필드=가수 필드, frac)
만 다르다 .
'Programming Language > C' 카테고리의 다른 글
9.(C언어) scanf, 입력받기 (0) | 2020.08.01 |
---|---|
8.(C언어) 상수 (0) | 2020.08.01 |
6.(C언어) 진법, 음수표현 (0) | 2020.08.01 |
5.(C언어) 자료형_문자 (0) | 2020.08.01 |
4.(C언어) 자료형_실수 (0) | 2020.08.01 |