float형을 사용할떄
글쓴이: heobeom / 작성시간: 화, 2015/01/20 - 2:33오후
정수형 변수의 값을 받아서
float형으로 0.1% ~ 5%까지 나타내려고 하는데
1의 0.5%를 나타내려고 1 * 0.5 / 100을 하니까
값이 0.00499998이런식으로 변경되는데.. 이값을 0.5로 변경할 수는 없을까요??
printf를 써서 출력하는 경우가 아니라서 %0.4f이런식으로 처리할 수가 없어서..
float형에 저장된 값을 문자열로 변경하여 그대로 출력하게 하는거라 0.0049라고 출력되네요 ㅠㅠ
소수점 4자리에서 반올림하면 될 것 같아서
floor( (x)*10000 +0.5) / 10000)도 추가해봤는데 별다른 차이가 없네요 ㅠㅠ;
eclipse CDT를 이용해 코딩중이고 minGW컴파일러를 쓰고 있습니다.
Forums:
위 문제는 부동소숫점 때문인데 소숫점 한자리만
위 문제는 부동소숫점 때문인데
소숫점 한자리만 사용할 거라면 정수형으로 처리하는건 어떤가요?
예를들어 1의 0.5%를 나타낸다 하면
1000(default) * 1 / 2(0.5) / 100 = 5 가 되는데
default 가 1000 이므로 처리해줄 땐 0.005로 나타내면 되겠죠.
그래서 값을 integer형으로 받아서 데이터랑
그래서 값을 integer형으로 받아서
데이터랑 곱하기 처리를 해주고
1000으로 나눌때 형변환으로 float형에 넣어주었는데
결국은 값은 똑같이 표현이 되더군요 ㅠㅠ;
int data //1~10000
int per //0.1~5 %
float output
per *= 10 //정수형으로
data *= per //연산 실행
output = (float)data / 1000.f
이렇게 해도 data가 1이고 per가 0.5이면
output값이 0.004999998 이런식으로 나오네요 ㅠㅠ;
나누는것도 물론 직접처리해주어야 합니다.5를
나누는것도 물론 직접처리해주어야 합니다.
5를 문자열로받으면 그 앞에 0.00를 넣어주는식으로요
중복
.
printf만 안하면 되는거라면 sprintf 는
printf만 안하면 되는거라면 sprintf 는 어떠신가요?
float t = 0.005f
char a[101];
sprintf(a,"%.4f",t);
이런식으로 처리하면 될것같습니다만
결국은 소수점 위아래를 각각 정수형으로
결국은 소수점 위아래를 각각 정수형으로 표현하여
말씀하신대로 sprintf를 통해 출력하였습니다.
float input, data;
int over_value, under_value;
char str[100u];
int len;
data = (다른코드에 저장되어 있는 값 입력)
input = (입력받음)
over_value = data * 10u;
under_value = over_value % 1000u;
over_value /= 1000u;
sprintf(str, "%d.%03d", over_value, under_value);
len = strlen(str);
while(len--)
{
if(str[len] == '.')
{
str[len] = 0;
}
if(str[len] != '0')
{
break;
}
else
{
str[len] = 0;
}
이후 str을 출력하는 변수에 넣는것으로 마무리 지었습니다.
정상입니다.
float, double은 2진수로 표현되기 때문에 2의 거듭제곱으로 딱 나누어 떨어지는 숫자만 정확히 표현할 수 있습니다.
나머지 숫자는 정확한 표현이 안됩니다. 10으로 나눠 떨어지는 정확한 소수가 필요하다면 10의 거듭제곱을 적당히 곱해서 다 정수로 만드는 수가 있습니다.
확실히 double형이면 원하는 수에 가깝게
확실히 double형이면 원하는 수에 가깝게 표현되겠네요
근데 저 혼자 짜는 코드가 아니라 회사에서 짜는 거다 보니
자료형을 제 맘대로 바꾸기가 쉽지 않았네요 ㅠㅠ;
> float형에 저장된 값을 문자열로 변경하여
> float형에 저장된 값을 문자열로 변경하여 그대로 출력하게 하는거라 0.0049라고 출력되네요 ㅠㅠ
0.004999... 를 0.0049로 출력한다면 그건 문자열로 변경하는 과정에 문제가 있는겁니다.
0.004999... 를 5번째자리에서 반올림하면 0.0050 이 되어야 정상이죠.
문자열로 변환하는 과정에서 반올림이라는 걸 고려하지 않으신거 아닌가요?
banollim(x,dig)
banollim(x,dig) (floor((x)*pow(10,dig)+0.5)/pow(10,dig))
이러한 매크로를 찾아보고 이용해 써봤는데 코드상에서 영향을 안미치더군요 ㅠㅠ;
수치그자체를 반올림하는게 아니라 문자열로 바꾸는
수치그자체를 반올림하는게 아니라 문자열로 바꾸는 과정에서 고려해야죠.
아무리 발악을 해도 부동소수점은 부동소수점의 한계를 그대로 끌고가는 겁니다.
아니면 많은 분들이 지적한대로 고정소수점으로 구현을 하시거나요.
gilgil.net
http://www.gilgil.net/8417
상기 링크 아래 부분을 보시면 특정 숫자가 내부적으로 어떻게 저장되는지 확인할 수 있습니다.
0.5, 0.25, 0.125와 같은 숫자는 정확히 표현되는 반면에 0.1과 같은 숫자는 float로 정확히 표현할 수 없습니다.
double을 쓴다 하더라도 자리수만 더 커지게 되는 work around일 뿐입니다.
www.gilgil.net
댓글 달기