double 데이터 타입으로 표현할 수 있는 수의 크기

rgbi3307의 이미지

궁금하여 아래 코드를 실행해 봤습니다.

#include <stdio.h>
 
main()
{
    int i;
    double result;
 
    //result 데이터 타입 크기
    printf("size of double = %d\n", sizeof(result));
 
    result = 1;
    for (i = 0; i < 64; i++)
	result = result * 2;  //2의 64승(8바이트)
    printf("result64=%f\n", result);
 
    result = 1;
    for (i = 0; i < 128; i++)
	result = result * 2;  //2의 128승(16바이트)
    printf("result128=%f\n", result);
}

리눅스에서 cc로 컴파일하여 실행한결과
(Linux 2.4.20-8 #1 Thu Mar 13 17:54:28 EST 2003 i686 i686 i386 GNU/Linux)

size of double = 8
result64=18446744073709551616.000000
result128=340282366920938463463374607431768211456.000000

윈도우즈 XP에서 Microsoft Visual C++ 2005(Visual Studio 2005)에서 실행한 결과

size of double = 8
result64=18446744073709552000.000000
result128=340282366920938460000000000000000000000.000000

위의 결과가 다르게 나오는 이유가 뭘까요?
저도 확신이 없어서 KLDP에 올려봅니다.

또한, Linux에서 아래 코드를 실행했을때, 어떤 결과가 나올까요?

    result = 1;
    for (i = 0; i < 512; i++)
	result = result * 2;  //2의 512승(64바이트)
    printf("result512=%f\n", result);
 
    result = 1;
    for (i = 0; i < 1024; i++)
	result = result * 2;  //2의 1024승(128바이트)
    printf("result1024=%f\n", result);

ifree의 이미지

double 에서는 유효숫자가 15 개 까지죠.
그 이하는 의미가 없는 수입니다.

winner의 이미지

VC++는 의미있는 수 아래는 그냥 0으로 출력하는 듯...

dg의 이미지

'의미있는 수' 라는 말이 좀 혼동을 일으킬거 같은데요.
이 경우에서는 1의 자리까지 다 의미있잖아요.

newpolaris의 이미지

gcc는 1의자리까지 일치합니다.

그런데 윈도우의 gcc (mingw)의 printf는 VC와 같은 결과를 출력하네요;
윈도우것을 쓰는지는 잘모르겠습니다만,

double값 자체에는 문제가 없습니다.

#include <iostream>
#include <stdio.h>
 
int main()
{
   using std::cout;
   using std::endl;
 
   double result=1;
 
   for (int i = 0; i< 128; i++)
      result *= 2;
 
   printf("%f\n", result);
 
   cout.precision(50);
   cout << result << endl;
}

결과: mingw

340282366920938460000000000000000000000.000000
340282366920938463463374607431768211456

결과: vc

340282366920938460000000000000000000000.000000
3.402823669209384600000000000000e+038

이상해서 double 변수 값에 접근하여보았습니다.
결과: mingw == vc
47f0 0000 0000 0000 0000 0000 0000 0000

sign bit___exponent
0__________100010001111111
faction
0000000000000000000000000000000000000000000000000000

조합하면
1.faction * 2^(expoent - 1023) = 1.0 * 2^128

입니다.

결과적으로
VC GCC 모두 double은 정확히 같은 값을 표시하고 있었습니다.
다만 다른것은 printf의 구현인것 같습니다.

cout 부분은 잘 몰라서 자신이 없네요. 머가 빠졌나;
nEW

nEW

rgbi3307의 이미지

특정 데이터 타입의 크기로 표현할 수 있는 수의 크기가 궁금해서 실습해본 코드입니다.
데이터 타입의 크기는 머신과 컴파일러에 의존적이지만, 일반적으로,

sizeof(char)   == 1바이트( 8비트) == 2의 8승 == 256 
sizeof(short)  == 2바이트(16비트) == 2의16승 == 65536 (6만5천..)
sizeof(int)    == 4바이트(32비트) == 2의32승 == 4294967296 (42억..)
sizeof(double) == 8바이트(64비트) == 2의64승 == 18446744073709551616 (천문학적인 숫자)
 
??             ==16바이트(128비트) == 2의128승 == 340282366920938463463374607431768211456 (우주에 있는 별들의 수?)
 
??             ==64바이트(512비트) == 2의512승 == 13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084096 (우주의 넓이?)
 
??             ==128바이트(1024비트) == 2의1024승 == ??

위에서 double의 데이터 타입 크기는 8바이트(64비트) == 2의64승 == 18446744073709551616으로 리눅스 cc에서는 이렇게 계산되었지만,
윈도우의 VC에서는 18446744073709552000(오른쪽 끝에서 3자리가 0으로 처리됨) 으로 계산되었다는 것입니다.

그리고, 현재의 컴파일러 중에서 16바이트(128비트) 이상의 데이터를 나타내기 위한 데이터 타입은 없는것으로 알고 있었으나
리눅스의 cc는 64바이트(512비트)까지 계산해 내는 것으로 결과가 나왔고, 그 이유가 궁금합니다.
리눅스 cc가 어디까지 숫자를 나타내는지 계속 돌려 보았더니,
128바이트(1024비트)는 나타내지 못하는듯 하네요...

From:
*알지비 (메일: rgbi3307(at)nate.com)
*학창시절 마이크로마우스를 만들었고, 10년동안 IT관련 개발자로 일하고 있음.
*틈틈히 커널연구회(http://www.kernel.bz/) 내용물들을 만들고 있음.
*((공부해서 남을 주려면 남보다 더많이 연구해야함.))

From:
*알지비 (메일: rgbi3307(at)nate.com)
*커널연구회(http://www.kernel.bz/) 내용물들을 만들고 있음.
*((공부해서 남을 주려면 남보다 더많이 연구해야함.))

klara의 이미지

C의 double은 부동소수점 방식입니다. 지수부와 가수부에 따로따로 비트가 할당되있어요....

sizeof(double) == 8바이트(64비트) == 2의64승 == 18446744073709551616 (천문학적인 숫자)

적으신건 정수형에만 해당되는 이야기입니다. 부동소수점과 유효숫자에 대해서 찾아보세요.

더불어 정수형이라고 해도 일반적으로 n비트의 정수형은, 부호비트로 1비트가 빠지고, 가장 큰 수는 2^(n-1) - 1 입니다.
부호없는 1비트 정수형의 최대값이 얼마일지 생각해보세요.

mithrandir의 이미지

2**64 라고 해도, 실제로 유효자리수는 한자리 입니다. float/double이 실수부를 십진수로 들고 있는게 아니라 이진수로 들고 있죠.
따라서 gcc의 double은 정상입니다. 또한 윈도와 리눅스에서 float를 똑같이 IEEE754를 쓰고 있다면, 차이는 printf구현 뿐입니다.

언제나 삽질 - http://tisphie.net/typo/
프로그래밍 언어 개발 - http://langdev.net

언제나 삽질 - http://tisphie.net/typo/
프로그래밍 언어 개발 - http://langdev.net

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.