double 데이터 타입으로 표현할 수 있는 수의 크기
글쓴이: rgbi3307 / 작성시간: 화, 2010/09/07 - 3:16오후
궁금하여 아래 코드를 실행해 봤습니다.
#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);
Forums:
double 에서는
double 에서는 유효숫자가 15 개 까지죠.
그 이하는 의미가 없는 수입니다.
printf 구현의 차이인 것 같군요.
VC++는 의미있는 수 아래는 그냥 0으로 출력하는 듯...
'의미있는 수' 라는
'의미있는 수' 라는 말이 좀 혼동을 일으킬거 같은데요.
이 경우에서는 1의 자리까지 다 의미있잖아요.
gcc의 구현이 정확한 값을 출력합니다.
gcc는 1의자리까지 일치합니다.
그런데 윈도우의 gcc (mingw)의 printf는 VC와 같은 결과를 출력하네요;
윈도우것을 쓰는지는 잘모르겠습니다만,
double값 자체에는 문제가 없습니다.
결과: 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
printf 함수 문제는 아닌듯합니다.
특정 데이터 타입의 크기로 표현할 수 있는 수의 크기가 궁금해서 실습해본 코드입니다.
데이터 타입의 크기는 머신과 컴파일러에 의존적이지만, 일반적으로,
위에서 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/) 내용물들을 만들고 있음.
*((공부해서 남을 주려면 남보다 더많이 연구해야함.))
C의 double은
C의 double은 부동소수점 방식입니다. 지수부와 가수부에 따로따로 비트가 할당되있어요....
sizeof(double) == 8바이트(64비트) == 2의64승 == 18446744073709551616 (천문학적인 숫자)
적으신건 정수형에만 해당되는 이야기입니다. 부동소수점과 유효숫자에 대해서 찾아보세요.
더불어 정수형이라고 해도 일반적으로 n비트의 정수형은, 부호비트로 1비트가 빠지고, 가장 큰 수는 2^(n-1) - 1 입니다.
부호없는 1비트 정수형의 최대값이 얼마일지 생각해보세요.
2**64 라고 해도,
2**64 라고 해도, 실제로 유효자리수는 한자리 입니다. float/double이 실수부를 십진수로 들고 있는게 아니라 이진수로 들고 있죠.
따라서 gcc의 double은 정상입니다. 또한 윈도와 리눅스에서 float를 똑같이 IEEE754를 쓰고 있다면, 차이는 printf구현 뿐입니다.
언제나 삽질 - http://tisphie.net/typo/
프로그래밍 언어 개발 - http://langdev.net
언제나 삽질 - http://tisphie.net/typo/
프로그래밍 언어 개발 - http://langdev.net
댓글 달기