c언어 floating point 관련 질문 입니다.
글쓴이: ydx / 작성시간: 토, 2008/03/15 - 2:21오전
#include
main()
{
if(0.14*50 == 7)
printf("0.14*50 = 7 %lf\n",0.14*50);
else
printf("0.14*50 <> 7 %lf\n",0.14*50);
if(14.0*0.5 == 7)
printf("14*0.5 = 7 %lf\n", 14*0.5);
else
printf("14*0.5 <> 7 %lf\n", 14*0.5);
}
위와 같이 짰습니다.
결과는 아래와 같습니다.
0.14*50 <> 7 7.000000
14*0.5 = 7 7.000000
왜 이렇게 되는지 도저히 이해가 되지 않습니다.
컴파일러는 gcc 3.4.6 입니다.
부디 간단하게나마라도 설명 부탁 드립니다.
Forums:
그건 당연히 그렇게
그건 당연히 그렇게 됩니다. 수학적인 실수는 연속적이지만, 컴퓨터의 floating point 는 불연속적이니까요. 그래서 대개는 오차 범위를 두어 비교합니다. 일반적으로 eps ( epsilon ) 값이라고 부릅니다.
예를 들어 임의 실수 val 이 0 인지 판단하는 코드는 다음과 같습니다. 리터값이 0인 경우 val 을 0으로 판단합니다.
Orion Project : http://orionids.org
당연한 것이라도 이해가..ㅠㅠ
답변 감사드립니다.
코드를 보면 if 구문이 2개로 되어 있습니다.
하지만 첫 번째 if는 7과 다르다고 찍히지만 %lf로 찍히는 값은 7.0 입니다.
두 번째 if는 7과 같다고 찍히며, 역시 %lf로 찍히는 값이 7.0 입니다.
제 느낌으로는 첫 번째 if와 두 번째 if가 같은 결과를 찍어내야 하는데 서로 다른 결과를 찍어 내는 것일까요?
입실론(epsilon)은 우리가 임의로 정해주는 값인가요?
허용 오차범위를 우리가 정해 주는 그런 개념이겠지요?
0.14라고 쓰면 십진수
0.14라고 쓰면 십진수 0.14가 아닙니다. IEEE754의 구조가 어떻게 되어 있는지 보세요.
코드를 더 짜봐도 이해가 안됩니다.
위와 같이 짜면 아래와 같이 나옵니다.
아무리 생각 해 봐도 output의 각 라인이 같은 내용을 출력해야 하는데 첫 두 라인과 나머지 두 라인이 서로 다릅니다.
왜 그런지 아시는 분 답변 부탁드립니다.ㅠㅠ
그럼 0.5는 십진수 인가요?
cwryu 님 답변 감사드립니다.
금방 IEEE754에 대해서 잠깐 찾아봤는데, 아무래도 0.14는 2진수 형태로 변형하게 되면 2진수 무한소수가 되어 23비트 이하는 잘려버리기 때문 인 것 같습니다.(맞는지요?)
하지만 0.5의 경우에는 무한소수로 되지 않고 딱 떨어지기 때문에 잘리지 않구요.
그렇다면, c언어 내에서 if문 내에서 변수가 아닌 floating point의 상수로 이루어진 수식을 평가할 때, float형, double형 중에서 어떤 형태로 정확도를 줘서 평가하는 것일까요?
아무래도 double형의 정확도로 평가 할 것 같은데..^^; 이부분에 대해 확실히 나와 있는 문서는 어디서 찾을 수 있나요?
마지막으로 printf에서 0.14*50의 값이 7.000000 이 나온 것은 소수점 6자리 정확도에서는 반올림 되어 7.000000 이지만 정확도가 더 늘어나면 다른 값이 출력 되겠지요?
정확하십니다. float=flo
정확하십니다.
float=float일 때는 float로, long double=double이나 long double=long double일 때는 long double로 비교하겠죠.
(전략) 항복 권고를 받은 키탈저 태수 아지엣 사카라는 "항복? 먹는 거냐?"라는 짤막한 답장을 써보냈다. 베로시 토프탈은 행간에서 낄낄거림이 묻어나는 문체로 항복은 먹는 것이 아니라 자신의 미력함을 인정하고 상대에게 굴복하는 것이라는 상냥한 답을 보냈다. 그러자 아지엣 사카라는 "못 먹는 것이면 관심 없다."는 답장을 보냈다.
몽화 대사전 - http://cppig1995.n-pure.net/mh
Real programmers /* don't */ comment their code.
If it was hard to write, it should be /* hard to */ read.
그냥 상수를 쓰면
그냥 상수를 쓰면 double로, 상수 뒤에 f를 붙이면 float로 인식됩니다.
sizeof 나 컴파일러 워닝으로 대충 짐작도 할 수 있습니다 :)
정수형 상수 뒤에도 l, u, ul 등을 붙여서 long, unsigned, unsigned long 등으로 타입을 정해줄 수 있습니다.
댓글 달기