kyaryunha   6년 전

아래 두개의 코드를 첨부했습니다.

위에는 double을 사용한 코드이고, 아래는 float를 사용한 코드입니다.

그 외의 차이점은 없는 코드입니다.


double을 사용하면 0%에서 바로 틀렸습니다가 뜨고,

float를 사용하면 6~70%에서 틀렸습니다가 뜹니다..


대체 왜일까요..................................(.....)


겸ㅁ float를 사용한 코드에서 반례케이스를 알려주심ㅁ 감사하겠습니다.......

starjrm00   6년 전

float와 double은 IEEE 754 표준에 명시되어 있습니다.

설명글 : http://www.tipssoft.com/bullet... (학교 수행때문에 찾아본적이 있는데 저곳이 가장 이해하기 편하더군요.)

저같은 귀차니스트들을 위해 간단히 설명하자면 float는 32bit 실수형, double은 64bit 실수형입니다. (long double은 c++기준 80bit 실수형인걸로 기억합니다.)

float는 32비트 부동소수점 표기로 자료형을 저장하는데 이때 a^b형태로 자료를 저장합니다. (a는 8비트 정수, b는 23비트 정수인걸로 알고있습니다.) 저장을 할 때 이진수 형태로 저장을 하기에 분모가 2의 거듭제곱꼴이 아닌경우 반올림이 일어납니다. 설명글에서 든 예시를 언ㄱ브하자면 0.35 = 0.0101100110011....이 되는 식입니다.

double의 경우 64비트 부동소수점이기에 float보다는 정확하지만 실수라는 한계점이 있기에 값 저장시 역시 데이터 변조가 일어나게 됩니다.

아마 저 코드가 틀린 이유는 값 비교시 실수와 실수를 비교하면서 에러가 난듯 하네요. 대다수의 실수연산 문제에서는 10^(-6)범위 이하는 다루지 않는 경우가 많고 (ex : https://www.acmicpc.net/proble... (Ax+Bsin(x)=C) ) 이런 경우가 없을때는 대부분 특정 상수를 곱해서 정수와 정수의 비교형태로 만든 다음에 계산을 해줍니다.

개인적인 의견으로는 float가 double보다 부정확하기에 초반 TC를 통과해간것 같습니다만... long double을 함 써보시는걸 추천드립니다. (이걸로도 안되면 실수에 상수 곱해서 정수와 실수비교 또는 정수와 정수비교꼴로 만들거나, 분수를 구현해서 비교하는 방법이 있습니다.)

kyaryunha   6년 전

헉ㄱ.. 단순히 출력하는 자릿수의 차이만 있는줄 알았는데 지수부 가수부...(신기)
그리고 IEEE라던가 long double 이란건 왠지 처음 듣네요.. (신기.. 저런게 학교 수행이라니.. 왠지 대단..)
그치만 long double 역시 2~30% 정도에서 틀렸습니다..
흠ㅁ.. 분수로 새로 데이터구조 만들어서 푸는 것 밖에 답이 없는 거려나요..ㄷㄷ.. (포기.....!)

chogahui05   6년 전

그런데 애초에 이 문제가 정밀도를 명시해 주지 않아서.


마음만 먹고

2

0.333333..3333333333333333333333333343 (소숫점 21억자리)

0.66666..66666666666666668676723424241 (소숫점 50억자리)

이렇게 넣으면 다 틀릴 겁니다. 원래 의도가 무엇인지도 잘 모르겠습니다만..

파싱을 요구하는 문제가 아닐까 싶네요. 출제진 분들의 의도와 다르게..

kyaryunha   6년 전

헉ㄱ 파싱ㅇ.. (왠지 처음 듣는 단어..   왠지 앞으로 정보 더 열ㄹ심히 해야겠..

21억자리라니....(( 그럴수도 있겠군요..ㄷㄷ))

좋은 정보 감사합니다 :)

댓글을 작성하려면 로그인해야 합니다.