C의 부동 소수점 데이터 유형 범위는?
저는 C 책을 읽고 부동소수점의 범위에 대해 이야기하고 있습니다. 저자는 테이블을 주었습니다.
Type Smallest Positive Value Largest value Precision
==== ======================= ============= =========
float 1.17549 x 10^-38 3.40282 x 10^38 6 digits
double 2.22507 x 10^-308 1.79769 x 10^308 15 digits
가장 작은 양의 값과 가장 큰 값 열의 숫자가 어디에서 온 것인지 알 수 없습니다.
32비트 부동 소수점 숫자는 23 + 1비트의 가수를 가지며 8비트 지수(-126 ~ 127)를 사용하므로 표시할 수 있는 가장 큰 숫자는 다음과 같습니다.
(1 + 1 / 2 + ... 1 / (2 ^ 23)) * (2 ^ 127) =
(2 ^ 23 + 2 ^ 23 + .... 1) * (2 ^ (127 - 23)) =
(2 ^ 24 - 1) * (2 ^ 104) ~= 3.4e38
이러한 숫자는 부동 소수점 숫자의 표준 표현을 정의하는 IEEE-754 표준에서 가져온 것입니다.링크의 위키피디아 기사는 부호, 가수 및 지수에 사용되는 비트 수를 알고 이러한 범위에 도달하는 방법을 설명합니다.
float 데이터 유형의 값은 다음과 같이 할당된 숫자를 나타내기 위해 총 32비트를 갖는 것에서 유래합니다.
1비트: 부호 비트
8비트: 지수 p
23비트: 맨티사
지수는 다음과 같이 저장됩니다.p + BIASBIAS가 127인 경우, 가수는 23비트와 1로 가정되는 24번째 숨겨진 비트를 가집니다.이 숨겨진 비트는 가수 중 가장 중요한 비트(MSB)이며 지수가 1이 되도록 선택해야 합니다.
이것은 당신이 나타낼 수 있는 가장 작은 숫자는01000000000000000000000000000000어느 것이1x2^-126 = 1.17549435E-38.
가장 큰 값은011111111111111111111111111111111가수는 2 * (1 - 1/65536)이고 지수는 127입니다.(1 - 1 / 65536) * 2 ^ 128 = 3.40277175E38.
비트가 다음과 같은 경우를 제외하고는 동일한 원리가 이중 정밀도에 적용됩니다.
1비트: 부호 비트
11비트: 지수 비트
52비트: 가수 비트
바이어스: 1023
따라서 기술적으로 한계는 부동 소수점 번호를 표현하기 위한 IEEE-754 표준에서 나온 것이며, 위의 내용은 한계가 발생하는 방식입니다.
무한대, NaN 및 하위 정규 분포
지금까지 다른 답변이 언급하지 않은 중요한 주의 사항입니다.
IEEE 754 및 정상 이하의 숫자에 대한 이 소개를 먼저 읽으십시오.비정규 부동 소수점 수는 무엇입니까?
단일 정밀 부동 소수점(32비트)의 경우:
IEEE 754는 지수가 모두 1이면 다음과 같이 말합니다.
0xFF == 255), 그런 다음 NaN 또는 Infinity를 나타냅니다.이것이 무한하지 않은 가장 큰 숫자가 지수를 갖는 이유입니다.
0xFE == 254그리고 아닌0xFF.그 다음 편향을 사용하면 다음과 같습니다.
254 - 127 == 127FLT_MIN는 가장 작은 정규 숫자입니다.하지만 더 작은 정상 이하의 것들도 있습니다!그것들이 차지합니다.-127지수 슬롯
다음 프로그램의 모든 assert는 Ubuntu 18.04 및 64에 전달됩니다.
#include <assert.h>
#include <float.h>
#include <inttypes.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
float float_from_bytes(
uint32_t sign,
uint32_t exponent,
uint32_t fraction
) {
uint32_t bytes;
bytes = 0;
bytes |= sign;
bytes <<= 8;
bytes |= exponent;
bytes <<= 23;
bytes |= fraction;
return *(float*)&bytes;
}
int main(void) {
/* All 1 exponent and non-0 fraction means NaN.
* There are of course many possible representations,
* and some have special semantics such as signalling vs not.
*/
assert(isnan(float_from_bytes(0, 0xFF, 1)));
assert(isnan(NAN));
printf("nan = %e\n", NAN);
/* All 1 exponent and 0 fraction means infinity. */
assert(INFINITY == float_from_bytes(0, 0xFF, 0));
assert(isinf(INFINITY));
printf("infinity = %e\n", INFINITY);
/* ANSI C defines FLT_MAX as the largest non-infinite number. */
assert(FLT_MAX == 0x1.FFFFFEp127f);
/* Not 0xFF because that is infinite. */
assert(FLT_MAX == float_from_bytes(0, 0xFE, 0x7FFFFF));
assert(!isinf(FLT_MAX));
assert(FLT_MAX < INFINITY);
printf("largest non infinite = %e\n", FLT_MAX);
/* ANSI C defines FLT_MIN as the smallest non-subnormal number. */
assert(FLT_MIN == 0x1.0p-126f);
assert(FLT_MIN == float_from_bytes(0, 1, 0));
assert(isnormal(FLT_MIN));
printf("smallest normal = %e\n", FLT_MIN);
/* The smallest non-zero subnormal number. */
float smallest_subnormal = float_from_bytes(0, 0, 1);
assert(smallest_subnormal == 0x0.000002p-126f);
assert(0.0f < smallest_subnormal);
assert(!isnormal(smallest_subnormal));
printf("smallest subnormal = %e\n", smallest_subnormal);
return EXIT_SUCCESS;
}
GitHub 업스트림.
컴파일 및 실행 방법:
gcc -ggdb3 -O0 -std=c11 -Wall -Wextra -Wpedantic -Werror -o subnormal.out subnormal.c
./subnormal.out
출력:
nan = nan
infinity = inf
largest non infinite = 3.402823e+38
smallest normal = 1.175494e-38
smallest subnormal = 1.401298e-45
dasblinkenlight가 이미 답했듯이, 그 숫자들은 IEEE-754에서 부동소수점 숫자가 표현되는 방식에서 나온 것이고, Andreas는 수학에 대한 멋진 분석을 가지고 있습니다.
그러나 IEEE-754 숫자의 정밀도는 유의한 이진 숫자의 수에 따라 달라지므로 부동 소수점 숫자의 정밀도가 표에서 제시하는 것처럼 정확하게 6자리 또는 15자리 유의한 소수점 숫자가 아닙니다.
float에는 24개의 유효한 이진 숫자가 있습니다. 이 숫자는 표시된 숫자에 따라 6-8개의 소수 자릿수 정밀도로 변환됩니다.double에는 53개의 유효한 이진 숫자가 있으며, 이는 약 15개의 소수 자릿수입니다.
관심이 있으시다면 제 다른 답변에 더 자세한 설명이 있습니다.
예를 들어 IEEE 754와 같이 유형의 지수 부분의 크기에 따른 결과입니다.float.h의 FLT_MAX, FLT_MIN, DBL_MAX, DBL_MIN으로 크기를 검사할 수 있습니다.
언급URL : https://stackoverflow.com/questions/10108053/ranges-of-floating-point-datatype-in-c
'programing' 카테고리의 다른 글
| Mysql/Mariadb 사용자가 여러 데이터베이스에 부여 (0) | 2023.07.22 |
|---|---|
| 장고 프로젝트에서 from django.conf 가져오기 설정과 가져오기 설정의 차이점은 무엇입니까? (0) | 2023.07.22 |
| 한 열에서 고유한 열을 선택하고 다른 모든 열을 반환합니다. (0) | 2023.07.22 |
| 함수 arg에 액세스하기 위해 x86 스택을 popping할 때의 세그먼트화 오류 (0) | 2023.07.22 |
| SpringBoot - HTTP 요청 헤더 구문 분석 오류 (0) | 2023.07.22 |