C언어 컴파일러별 long double형 출력

C언어에는 4배 정도 실수형이라고 long double형이 있습니다. C언어의 자료형은 C#, Java와 같은 고급언어와 달리 int형은 4바이트라는 식으로 정확히 정해져 있지 않고 C언어 표준에서는 자료형의 정의가 하위 자료형보다 같거나 크다라는 식으로 정의되어 있다 보니 이러한 일이 발생합니다. 그래서 돌다리도 두들겨보자는 생각으로 컴파일러나 플랫폼이 바뀌면 한번 정도는 sizeof() 연산자로 자료형의 크기를 알아두는 것이 좋습니다. 여기서는 long double형의 출력에 대해서 몇 가지 확인해 보겠습니다.

<그림1> 부동소수점 크기 (출처 : 위키북)

 

위 내용은 위키북에서 제공한 자료로 long double형은 16바이트로 되어있는데 과연 그런지 확인해 보겠습니다. 아래의 코드는 자료형의 크기를 알기 위한 예제 소스입니다.

#include <stdio.h>
int main(void)
{
    int size = 0;
    double d = 3.141592653589793;
    long double ld = 3.141592653589793238462643383279502L;
    size = sizeof(d);
    printf("double size:%d, pi(double):%17.15f\n", size, d);
    size = sizeof(ld);
    printf("long double size:%d, pi(double):%35.33Lf\n", size, ld);
    getchar();
}

 

C언어 책 1/3만 공부해도 충분히 알 수 있는 간단한 코드로 자료형의 크기와 원주율을 보여주는 것입니다. 우선 Visual Studio 2017에서 실행하면 <그림 2>와 같이 출력됩니다.

 

<그림2> Visual Studio 실행 화면

 

보면 표시는 길게 했지만, 소수점 16자리 이후의 숫자는 전혀 맞지 않은 숫자이고 왼쪽의 자료형 크기를 봐도 double형과 long double형의 자료형 크기가 동일합니다. 그러다 보니 유효 자릿수 15자리까지는 정확하지만 이후 숫자는 맞지 않게 표시되고 있습니다. 그런데 이렇게 나왔다고 해서 Visual Studio 2017이 표준에 맞지 않다고 할 수는 없습니다. long double형도 double형과 크기가 같거나 큰 것으로 되어 있기 때문입니다. Visual Studio 2017에서 32비트와 64비트 실행파일 모두 동일합니다. 

이번에는 MinGW64로 컴파일 후 실행해 봤습니다. 결과는 아래 <그림 3>과 같이 출력됩니다. 단, 소스 코드를 수정해야 하는데 첫 줄에 아래의 define문을 추가해야 정상적으로 출력을 합니다. define문이 없으면 long double형은 0.0으로 출력합니다. 

#define _POSIX_C_SOURCE 201901L 

 

<그림3> MinGW-W64 실행 화면

 

위 <그림3>을 보면 long double형이 16바이트로 표시되는데 19번째 이후는 오차가 큽니다. 리눅스에 있는 GCC도 같은 결과를 보이는 것으로 봐서는 MinGW-W64의 버그는 아닌 듯합니다. 이 문제는 추후 원인이 확인되면 해당 포스팅을 수정하겠습니다. 실행결과를 올리지는 않았지만, Pelles C의 경우에도 위 Visual Studio 2017과 같이 double, long double형 모두 8바이트로 처리하고 있습니다. 아마도 윈도우즈에서는 Visual Studio가 가장 대중적인 개발 툴이라 동일하게 맞춘 듯합니다.  

마지막으로 32비트 MCU인 ST사 Cortex-M시리즈 개발툴인 TrueSTUDIO에서 동일한 코드를 실행해 봤습니다.

 

<그림4> STM32F767 출력 화면

<그림 4>는 시리얼 통신으로 받은 데이터입니다. MCU의 경우 PC와 같은 디스플레이가 없어 통신을 통해서 데이터를 받아야 합니다. 이 개발 툴에서 사용하는 컴파일러도 GCC 기반인데 Visual Studio와 같이 double형과 long double형 크기가 동일하게 8바이트입니다.

 

댓글(0)

Designed by JB FACTORY