C의 float
유형 설명은 유효 자릿수가 6
임을 나타냅니다. 그러나 부동 소수점 유형의 유효 자릿수
float f = 12345.6;
다음은
12345.6
을 인쇄하지 않습니다()의 printf를 사용하여 인쇄, 그것은
12345.599609
를 인쇄합니다. 따라서 "6 자리 숫자"(또는
double
의 경우 "15")는 부동 소수점 유형을 의미합니까?
C의 float
유형 설명은 유효 자릿수가 6
임을 나타냅니다. 그러나 부동 소수점 유형의 유효 자릿수
float f = 12345.6;
다음은
12345.6
을 인쇄하지 않습니다()의 printf를 사용하여 인쇄, 그것은
12345.599609
를 인쇄합니다. 따라서 "6 자리 숫자"(또는
double
의 경우 "15")는 부동 소수점 유형을 의미합니까?
standard에 따르면 모든 십진수가 정확하게 메모리에 저장 될 수있는 것은 아닙니다. 표현의 크기에 따라 오류는 특정 최대 값을 가질 수 있습니다. float
의 경우 이것은 0.0001%
(6 자리 유효 숫자 = 10^-6
= 10^-4 %
)입니다.
오류가 float에 대한 최대 오류보다 훨씬 낮은 (12345.6 - 12345.599609)/12345.6 = 3.16e-08
입니다.
유효 숫자 6은 최대 오류가 약 +/- 0.0001 %임을 의미합니다. 단일 부동 소수점 값은 실제로 약 7.2 자리의 정밀도 (source)를가집니다. 즉, 오류는 약 +/- 12345.6/10^7 = 0.0입니다. 오류의 순서 (0.000391)입니다.
여기서 문제는 플로트에 숫자를 저장할 수 없다는 것입니다. IEEE 754이 설명하는 것처럼 가수, 밑수 및 지수로이 숫자를 나타낼 필요가 있습니다. 숫자 printf(...)
은 사용자가 저장된 실제 실수 번호를 보여줍니다. 부동 소수점 숫자의 유효 숫자는 유효하지 않습니다.
중요한 숫자는 실제로 문제가되지 않지만 컴퓨터의 숫자는 2 진수로 저장되며 3/5 (= 0.6)의 유한 이진 표현은 없습니다. 바이너리로 3/5는 0.100110011001 ...처럼 보이고, "1001"패턴은 영원히 반복됩니다. 이 시퀀스는 반복되는 0.599999 ...와 같습니다. 정밀도와 관련된 오류가 발생하기 전에 실제로 소수점 오른쪽에 소수점 세 자릿수가 생깁니다.
이것은 1/3의 유한 기수 10 표현이없는 것과 유사합니다. 우리는 영원히 반복하는 0.3333있다.
부동 소수점 형식은 10 진수로 저장되지 않으므로 중요한 * 소수점 이하 자릿수는 반드시 근사값입니다. –
실제로는 exp에는 8 비트, frac에는 23 비트가 있습니다. – halfelf