실수 형식 double, float 표현과 출력 [언제나 C언어]

안녕하세요. 언제나 휴일에 언휴예요.

이번 강의에서는 실수 형식 강의예요. 실수 형식을 표현하는 방법과 출력하는 방법을 알아봅시다.

1. 실수 형식의 메모리 크기
2. 실수 리터럴 표현
3. 실수 출력 - 소숫점 이하 출력할 자리 표현
4. 실수 출력 포멧  %f %g %e
5. 실수 사용에서 주의할 점

1. 실수 형식의 메모리 크기

먼저 sizeof로 실수 형식의 메모리 크기를 알아보아요.

#include  //표준 입출력 헤더

int main(void)
{       
    printf("sizeof(double):%d bytes, sizeof(float):%d bytes\n", sizeof(double),sizeof(float));
    return 0;
}

실행 결과를 보면 dobule 형식은 8bytes, float 형식은 4바이트인 것을 알 수 있어요.

sizeof(double):8 bytes, sizoeof(float):4 bytes

2. 실수 리터럴 표현

이번에는 실수 값을 표현하는 방법을 알아봅시다.

먼저 일반적으로 표현하는 실수는 double 형식으로 취급하는지 float 형식으로 취급하는지 sizeof를 통해 알아봅시다. 만약 8바이트라면 double, 4바이트라면 float이겠죠.

#include  //표준 입출력 헤더

int main(void)
{       
    printf("sizeof(0.1):%d bytes\n", sizeof(0.1));
    return 0;
}

결과를 보면 8bytes입니다.

이로써 일반적인 실수 표현은 double 형식으로 취급하는 것을 알 수 있어요.

sizeof(0.1):8 bytes

C언어에서 실수 표현은 디폴트로 double 형식으로 취급합니다.

float 형식의 실수를 표현할 때는 뒤에 f를 붙여서 표현합니다.

참고로 실수 형식 사이에 알아서 형식 변환(묵시적 형식 변환) 해 주어 크게 신경 쓸 일은 없어요.

#include  //표준 입출력 헤더

int main(void)
{       
    printf("sizeof(0.1):%d bytes\n", sizeof(0.1));
    printf("sizeof(0.1f):%d bytes\n", sizeof(0.1f));
    return 0;
}

실행 결과를 보면 0.1f 표현의 메모리 크기는 4바이트인 것을 알 수 있어요. float 형식임을 알 수 있죠.

sizeof(0.1):8 bytes
sizeof(0.1f):4 bytes

실수를 표현할 때 123.45 처럼 표현하는 것을 부동 소수점 표기법이라고 말합니다.

C언어에서는 1.2345e+2 처럼 지수 표기법으로도 표현할 수 있어요. 지수 부분은 알파벳 e와 지수를 나타내는 것이죠.

이 외에도 소수점 이하 자리가 없을 때 정수 부분 뒤에 점(.)만 찍어도 실수 표현으로 취급합니다.

정수 부분이 없을 때 점(.) 앞에 0을 생략하여 표현하는 것도 가능합니다.

#include  //표준 입출력 헤더
int main(void)
{       
    double df = 3.4; //실수 표현 디폴트 형식은 double
    float f = 123.45f;// float 형식 실수는 f를 뒤에 붙임
    float f2 = 123.45f;//부동 소수점 표현
    float f3 = 1.2345e+2f;//지수 표현
    float f4 = 7.f;  //소숫점 이하 자리가 없을 때 점(.)만 찍어도 실수 표현으로 취급
    float f5 = .05f; //정수 부분이 0일 때 0을 생략할 수 있다.
    return 0;
}

3. 실수 출력 – 소숫점 이하 출력할 자리 표현

실수를 출력할 때 가장 흔하게 사용하는 것이 %f 포멧을 사용하는 것입니다.

%f 포멧을 사용하면 소숫점 이하 6자리까지 출력합니다.

scanf_s로 입력받을 때는 double 형식은 %lf로 입력받습니다.

#include  //표준 입출력 헤더

int main(void)
{       
    double df = 3.4;
    float f = 3.4f;
    printf("df:%f\n",df);
    printf(" f:%f\n",f);
    return 0;
}

출력 결과는 다음과 같습니다.

df:3.400000
 f:3.400000

출력하고 싶은 소숫점 이하 자리수를 지정하려면 %와 f 사이에 .n 을 표시합니다. (n은 자릿수)

다음은 12.3456을 소숫점 이하 2자리까지 출력한 예입니다.

#include  //표준 입출력 헤더

int main(void)
{       
    printf("%.2f\n", 12.3456);
    return 0;
}

실행 결과를 보면 12.35로 소숫점 이하 3번째 자리에서 반올림하는 것을 알 수 있어요.

12.35

4. 실수 출력 포멧 %f %g %e

실수를 출력할 때 포멧은 %f외에 %g와 %e가 있어요.

%e는 지수 표기로 출력하는 것입니다.

#include  //표준 입출력 헤더

int main(void)
{       
    printf("%e\n", 12.3456);
    return 0;
}

출력 결과를 보면 1.234560e+01로 지수 표기로 출력하는 것을 알 수 있어요.

1.234560e+01

%g는 가장 간단하게 출력할 수 있는 방법으로 출력합니다. 이 때 소숫점 이하 자리도 값이 없으면 출력하지 않습니다.

#include  //표준 입출력 헤더

int main(void)
{       
    printf("%g\n", 13.4);//13.4
    printf("%g\n", 0.00000012);//1.2e-07
    return 0;
}

실행 결과를 보면 13.4일 때 13.4 그대로 출력합니다. 소수점 이하 자리에 값이 있는 부분까지만 출력하고 있어요.

그리고 0.00000012 는 지수 표기가 간단하여 1.2e-07로 출력하는 것을 알 수 있어요.

13.4
1.2e-07

5. 실수 사용에서 주의할 점

0에서 1 사이에도 실수는 무수히 많습니다.

메모리에 0에서 1 사이의 모든 실수를 표현하는 것은 불가능하다는 것이죠.

이러한 이유로 실수 표현에는 오차가 있을 수 있습니다.

다음은 실수 0에 0.1씩 더하는 코드입니다.

#include  //표준 입출력 헤더

int main(void)
{     
    float f = 0.0f;
    f += 0.1f;
    printf("%.20f\n", f);
    f += 0.1f;
    printf("%.20f\n", f);
    f += 0.1f;
    printf("%.20f\n", f);

    double df = 0.0;
    df += 0.1;
    printf("%.20f\n", df);
    df += 0.1;
    printf("%.20f\n", df);
    df += 0.1;
    printf("%.20f\n", df);
    return 0;
}

실행 결과를 보면 오차가 발생하는 것을 알 수 있어요.

그리고 double 형식의 오차가 float보다 오차가 작네요.

0.10000000149011611938
0.20000000298023223877
0.30000001192092895508
0.10000000000000000555
0.20000000000000001110
0.30000000000000004441

*다음 동영상 강의는 4바이트 실수(float)을 메모리에 표현하는 방법에 관한 것입니다. 왜 오차가 발생하는지 알 수 있어요.*