정확한 이유를 이해하기 위해서는 IEEE 의 double 형 데이터
표현방식을 참조해 보시면, 다음을 이해하는데 도움이 됩니다.
다음의 코드를 한번 실행해 봅시다.
( 아, 참고로, 리눅스 kernel 2.4.x 에서는 이렇지 않고,
sparc-sun-solaris 에서 다음과 같은 현상이 나는데,
아마 Architecture 의 Endian 형이 인텔과 솔라리스가
다른 이유가 아닌가 합니다. 솔라리스가 아마 Big-Endian
이죠? 아님 말고..
)
#include <stdio.h>
int main()
{
double a = 3;
printf ("%d\n", a);
printf ("%x\n", a);
return 0;
}
이것을 실행하면,
1074266112
40080000
-----
1074266112 는 십진수이죠.. 이것을 16진수로 나타내면 40080000 이고요..
이것을 이진수로 고쳐써 봅시다.
00100000 00001000 00000000 00000000 입져.
( 40 ) ( 08 ) ( 00 ) ( 00 )
3 이 이진수로 얼마인지는 중요하지 않습니다만,
중요한것은 double a = 3; 이라는 statement 에서
오른쪽의 3 이 컴파일 과정에서 먼저 정수 3으로 인식되지만
왼쪽 double 변수에 대입될때, type cast 가 발생합니다.
정수 3을 double 형으로 변환하게 되면 앞의 4바이트가 위의
이진수꼴이 되죠. 뒤의 4바이트는 아마 다른곳에 덮어써졌을겁니다.
그형태를 printf() 에서 정수형으로 찍으니깐, 그냥 큰수로 밀어내는것이죠.
그럼 3 은 0011 인데, 저것이 어떻게 0011 이란 형태가 보이지 않죠?
( 오래전에 학교에서 배운거라 잘 기억은 안나지만 )
floating point number 를 표현할때는, fraction 과 exponent로
나누어서 저장하는데, fraction 부분이 3이되고, exponent 부분이
1승 이되지요..
근데, fraction 을 표현할때, 한 비트를 아끼기 위해 1.f 형으로 표현됩니다.
즉, 3이 11(2진수) 이긴 한데, 1.f 형으로 쓰면 1.1 이되고,
거기서 f 형만 저장되니깐 1만 저장된겁니다.
아마 exponent가 12비트를 쓰고 나머지는 fraction 에 할당되지 않나
사료됩니다.
( 위의 형태를 보면 13번째 비트가 1로 시작합니다. 그래야 1.1이 되죠.)
자세한건 다음을 읽어보시고.. 그럼 이만.
Re: double 형이 %d로 출력할경우 값이 크게 나타나는 이유는>
*(int*)&k 값이 찍혀서 그렇습니다.
va_arg의 원리를 이해하시면 될 것 같구요.
원하는 의도대로라면, (int)k 를 인자로 해야겠죠.
Orion Project : http://orionids.org
정확한 이유를 이해하기 위해서는 IEEE 의 double 형 데이터표
정확한 이유를 이해하기 위해서는 IEEE 의 double 형 데이터
표현방식을 참조해 보시면, 다음을 이해하는데 도움이 됩니다.
다음의 코드를 한번 실행해 봅시다.
( 아, 참고로, 리눅스 kernel 2.4.x 에서는 이렇지 않고,
sparc-sun-solaris 에서 다음과 같은 현상이 나는데,
아마 Architecture 의 Endian 형이 인텔과 솔라리스가
다른 이유가 아닌가 합니다. 솔라리스가 아마 Big-Endian
이죠? 아님 말고..
)
이것을 실행하면,
1074266112
40080000
-----
1074266112 는 십진수이죠.. 이것을 16진수로 나타내면 40080000 이고요..
이것을 이진수로 고쳐써 봅시다.
00100000 00001000 00000000 00000000 입져.
( 40 ) ( 08 ) ( 00 ) ( 00 )
3 이 이진수로 얼마인지는 중요하지 않습니다만,
중요한것은 double a = 3; 이라는 statement 에서
오른쪽의 3 이 컴파일 과정에서 먼저 정수 3으로 인식되지만
왼쪽 double 변수에 대입될때, type cast 가 발생합니다.
정수 3을 double 형으로 변환하게 되면 앞의 4바이트가 위의
이진수꼴이 되죠. 뒤의 4바이트는 아마 다른곳에 덮어써졌을겁니다.
그형태를 printf() 에서 정수형으로 찍으니깐, 그냥 큰수로 밀어내는것이죠.
그럼 3 은 0011 인데, 저것이 어떻게 0011 이란 형태가 보이지 않죠?
( 오래전에 학교에서 배운거라 잘 기억은 안나지만 )
floating point number 를 표현할때는, fraction 과 exponent로
나누어서 저장하는데, fraction 부분이 3이되고, exponent 부분이
1승 이되지요..
근데, fraction 을 표현할때, 한 비트를 아끼기 위해 1.f 형으로 표현됩니다.
즉, 3이 11(2진수) 이긴 한데, 1.f 형으로 쓰면 1.1 이되고,
거기서 f 형만 저장되니깐 1만 저장된겁니다.
아마 exponent가 12비트를 쓰고 나머지는 fraction 에 할당되지 않나
사료됩니다.
( 위의 형태를 보면 13번째 비트가 1로 시작합니다. 그래야 1.1이 되죠.)
자세한건 다음을 읽어보시고.. 그럼 이만.
http://www.math.byu.edu/~schow/work/IEEEFloatingPoint.htm
삽질의 대마왕...
댓글 달기