부동 소수점 수치 이해

개시하다
현재 부동 소수점 수치를 설명합니다.
부동 소수점 수치는 컴퓨터 내부에서 소수점 수를 처리하는 방식 중의 하나다.
IEEE754 사양화.
표식
여기에 사용된 표지를 설명한다.
십진수와 이진수를 구분하기 위해 이진수 뒤에 b를 붙인다.
예.11b = 3
기호의 아래 첨자 숫자는 대응하는 비트를 나타낸다.
예제f_0달러는 f의 0위를 나타낸다.
format
부동점수를 나타내는bit열을 기호s, 지수e, 유효숫자 f 세 부분으로 나눈다.
e/f의bit length에 따라format가 몇 개 있습니다.bias는 잠시 후에 설명합니다.
format
s
e
f
s+e+f
bias
half
1
5
10
16
15
single
1
8
23
32
127
double
1
11
52
64
1023
quad
1
15
112
128
16383
format의 차이는 e/f의bit length만 다르다
생각이 같기 때문에 앞으로는 싱글만 설명한다.
s/e/f의 비트 분배는 다음과 같다.

다음 공식을 사용하여 비트열과 소수점을 맞춥니다.두 가지 방법이 있다.
그것들은 각각 정규화수와 비정규화수라고 불린다.127은 비스다.
$(-1)^s(1.f_{22}f_{21}...f_0)_b 2^{(e-127)}$ ... 귀일화수
$(-1)^s(0.f_{22}f_{21}...f_0)_b 2^{-126}$ ... 비정규화수
s는 기호입니다.
s=0은 정수이고, s=1은 마이너스이다.

e/f의 조합에 따라bit열의 뜻이 바뀔 수 있습니다.
대응 관계는 다음과 같다.e=0/e=255는 특별한 뜻이 있습니다.
e
f
비트 열
0
0
+0 또는 -0
0
!0
에서
255
0
표현 + inf or-if
255
!0
나인
1~254
any
에서
f는 유효한 숫자다.
1.5의 경우 f=100만 0000 0000b.
구체적 예
부동 소수점 수치의 표현을 구체적인 예로 이해하자.
소수점은 십진법의 12.375를 나타낸다.
십진수를 이진수로 설정하다.
12.375 = 12 + 0.375 = 1100b + 0.011b = 1100.011b
귀일화수.그러니까 1.xxxx 모양으로 만들어주세요.
1100.011b = 1.100011b*2^11b 변형
근거
f = 100011b
e 는 bias=127 = 1111b
11b=e-127을 위해
e=11b+127=11b+111111b=100000b로 변경됩니다.
결국 다음 바이너리가 될 거예요.
0 10000010 10001100000000000000000 b
0100 0001 0100 0110 0000 0000 0000 0000 b = 0x41460000
sample code
프로그램의 부동 소수점 수치 표현식.
test.c
#include <stdio.h>
#include <stdint.h>

void print_binary(uint32_t val)
{
    int i;
    for (i=0; i<32; i++) {
        uint32_t tmp = ((val>>(31-i))&1);
        printf("%01d", tmp);
        if (i == 0 || i == 8) {
            printf(" ");
        }
    }
}

void print(float f)
{
    float _f = f;
    uint32_t* p = (uint32_t*)&_f;
    print_binary(*p);
    printf(" = 0x%08x = %e ", *p, _f);
    printf("\n");
}

int main()
{
    float f;
    uint32_t* p = (uint32_t*)&f;
    printf("s eeeeeeee fffffffffffffffffffffff b\n");
    print(12.375f);
    print(1.f);
    print(-1.f);
    // +0 s=0 e=0 f=0
    *p = 0x00000000;
    print(f);
    // +inf s=0 e=ff f=0
    *p = 0x7f800000;
    print(f);
    // NaN s=0 e=ff f=1
    *p = 0x7f800001;
    print(f);
    // largest  s=0 e=fe f=7fffff
    *p = 0x7f7fffff;
    print(f);
    // smallest s=0 e=00 f=000001
    *p = 0x00000001;
    print(f);

    return 0;
}
console
gcc test.c && ./a.out
s eeeeeeee fffffffffffffffffffffff b
0 10000010 10001100000000000000000 = 0x41460000 = 1.237500e+01
0 01111111 00000000000000000000000 = 0x3f800000 = 1.000000e+00
1 01111111 00000000000000000000000 = 0xbf800000 = -1.000000e+00
0 00000000 00000000000000000000000 = 0x00000000 = 0.000000e+00
0 11111111 00000000000000000000000 = 0x7f800000 = inf
0 11111111 00000000000000000000001 = 0x7f800001 = nan
0 11111110 11111111111111111111111 = 0x7f7fffff = 3.402823e+38
0 00000000 00000000000000000000001 = 0x00000001 = 1.401298e-45  

좋은 웹페이지 즐겨찾기