C에서 double에 대한 질문입니다.
글쓴이: 푸르미 / 작성시간: 금, 2006/04/07 - 6:01오후
C 에서 double 5.4를 binary로 출력해보니
Quote:
0 10000000001 0101100110011001100110011001100110011001100110011010
가 나왔습니다.
즉 가수부는
Quote:
0101100110011001100110011001100110011001100110011010
가 되죠
main()
{
double a = 5.4;
long long int * b = (long long int*)(double*)&a;
printf("%f %x\n", a, b);
long long int c = *b;
int i;
for(i=0; i<64; i++)
{
if(i == 1 || i == 12) printf(" ");
printf("%d", (c>>(63-i))&0x1);
}
printf("\n");
}
그런데 자바스크립트로 이런 데이터를 만들어보니
(http://purmi.org/work/ide/kk.html)
가수부가
Quote:
0101100110011001100110011001100110011001100110011001
가 나옵니다.
위의 것과 밑의 것을 비교하면 끝에 두 수만 다릅니다.
이것이 항상 그런 것은 아니고 몇 가지 수에서만 그렇습니다.
그 몇 가지가 몇 가지일지 몇 십가지일지는 저도 모르겠습니다.
왜 이런 결과가 나온 걸까요?
뭔가 잘못 처리한 걸까요? 아니면 C언어에서 반올림처리하는게 있는걸까요?
Forums:
대부분의 10진 실수는
대부분의 10진 실수는 2진수로 완벽하게 표현할 수 없습니다. 아마도 그 때문에 일어나는 일인 듯 하군요.
컴파일러 (혹은 자바스크립트 번역기)가 소스 코드의 10진 상수 5.4를 읽어들여 내부적으로 2진수로 변환하는 과정에서, C 컴파일러와 자바스크립트가 서로 다른 방식으로 동작하는 듯 합니다.
코드를 보시면 알겠지만 해당 수를 직접 계산해서 처리한 것입니다.
5.4의 경우 0.4를 2진수로 취하면 0. 이후 0110이 반복되는 수가 됩니다. 2진 순환소수일까나요.. 그런데 C 에서는 0110이 반복되다가 0110의 형태가 아닌 10으로 끝나더군요. 정확하지 않다고는 하나 어떤 식으로 처리하여 그런 결과가 나온 것인지 궁금한 것입니다.
http://purmi.org/work/ide/kk.html
++++++++++
學而時習之
.
님의 코드는 자바스크립트에서 내부적으로 5.4를 저장하는 방식을 보여주는게 아니라, 그냥 5.4를 이진수로 바꾸어서 52자리까지만 보여주는 코드일 뿐입니다.
사실, 자바스크립트는 메모리에 대한 직접 접근을 허용하지 않으므로, 자바스크립트 내부에서 5.4를 어떻게 저장하고 처리하는지 알 수 있는 방법은 전혀 없습니다.
IEEE 754를 제대로 구현했다면, C와 같은 결과가 나와야 맞습니다.
http://babbage.cs.qc.edu/courses/cs341/IEEE-754.html
위에서 제시하신 두가지 경우의 차이는, 단지 어느 자리에서 반올림을 하는가의 차이일 뿐입니다.
그냥 이쪽이 더
그냥 이쪽이 더 이해하시기 편하시겠군요.
http://www.h-schmidt.net/FloatApplet/IEEE754.html
맨 끝자리 비트를 01로 하는 것과 10으로 하는 것 중 어느 쪽이 더 5.4에 가까우신지 직접 보시면 되겠군요.
자바스크립트(정확히는, ECMAScript)와 C/C++는 둘 다 IEE
자바스크립트(정확히는, ECMAScript)와 C/C++는 둘 다 IEEE-754 부동 소숫점 표현을 사용합니다만 거기에 대한 스펙은 상당히 다릅니다. IEEE-754는 표현 형식 뿐만 아니라 거기에 따라 가는 연산(덧셈, 곱셈, 제곱근 등)에 대한 규칙이 정리되어 있는데, 둘은 rounding method에서 다음과 같이 다릅니다.
- (익명께서 말씀하신 것과는 다르게) ECMAScript는 무조건 round to nearest(가까운 쪽으로 반올림)입니다.
- C/C++는 implementation defined입니다. (float.h에서 FLT_ROUNDS를 보면 기본값이 어떤 방식인 지 알 수 있습니다.) 단 제 노트북에서는 마찬가지로 round to nearest군요.
따라서 두 구현체의 rounding method가 다르다면 다른 결과가 충분히 나올 수 있습니다. 물론 그렇다고 해서 푸르미 님의 스크립트가 실제로 "어떻게 저장되는 지"를 보여 주는 건 아닙니다만...;;- 토끼군
IEEE 754 에 대한 자료를 가지고 있으신지?
답해주셔서 감사합니다.
그런데, 혹시 IEEE 754에 대한 자료를 가지고 있으신가요?
있다면, 좀 주셨으면 합니다.
대충은 무슨 소리인지 알겠는데, 어떻게 정의되어 있는지 한 번 보고 싶습니다.
++++++++++
學而時習之
google에서 "ieee 754"로
google에서 "ieee 754"로 검색해 보세요.
--
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://www.cinsk.org/cfaqs/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://cinsk.github.io/cfaqs/
댓글 달기