해결된 질문
작성
·
210
·
수정됨
2
double을 float로 변환할 때 float의 가수부가 저장할 수 있는 23비트를 초과하면 23비트까지 저장하고 초과한 부분은 모두 절삭된다고 하는데 맞는건가요??
절삭이 되면 항상 값이 줄어야 하는데 아래 코드로 해보니 결과가 좀 다르게 나와서요..
#include <stdio.h>
int main() {
double d1 = 3.1415928;
float f1 = d1;
printf("%.7f\n", d1);
printf("%.7f\n", f1);
double d2 = 3.1415929;
float f2 = d2;
printf("%.7f\n", d2);
printf(".7f\n", f2);
};
double형 3.1415928를 float로 변환하면 3.1415927로 값이 줄어서 나오는데
double형 3.1415928를 float로 변환하면 3.1415930으로 값이 증가해서 나옵니다..
왜 이렇게 나오는지 알 수 있을까요??
3.1415928≈11.00100100001111110110101010000010이며
이 중 가수부로 저장되는 비트는 00100100001111110110101이고
나머지 010000010는 버려진다는 것과
3.1415929≈11.00100100001111110110101010000011이며
이 중 가수부로 저장되는 비트는 00100100001111110110101이고
나머지 010000011는 버려진다는 것인데
버려지는 비트를 제외하고 저장되는 값은 11.00100100001111110110101로 똑같은데 왜 변환된 값은 3.1415927과 3.1415930인지 잘 모르겠습니다.
답변 1
3
안녕하세요, 답변 도우미 Soobak 입니다.
초과하는 비트들이 버려지는 과정, 즉, 절삭 과정 중 반올림(rounding)이 발생하기 때문입니다.
부동소수점 연산에 대한 IEE 754 표준에서는 bankers rounding
이라는 반올림(rounding) 방법을 사용하여 가장 근접한 표현 가능 값을 표현합니다.
해당 방법은 가장 가까운 값을 선택하는 반올림 방식입니다. (두 가지 가능한 값이 동일하게 근접할 경우에는 가장 가까운 짝수를 선택)
말씀해주신 각각의 경우에 대해서 버려지는 가수부에 대한 반올림과, 표현하려는 숫자를 고려할 때,3.1415928
은 3.1415927
이 가장 가까운 float
부동 소수점 수 이며,3.1415929
는 3.1415930
이 가장 가까운 float
부동 소수점 수 입니다.
즉, 단순히 버려내기만 하는 것이 아니라 반올림(한국어 표현으로 '올림' 단어가 들어가 있지만, 항상 올림이 이루어지는 것이 아니며, 가장 가까운 숫자를 선택하게 됩니다. 영어의 rounding, 그 중에서도 IEE 754 표준에서 사용하는 bankers rounding 방법에 대해서 간단히 검색해보시면 좋을 것 같습니다.) 과정이 포함되어 있기 때문에 다른 것입니다.
참고
How does C++ round int to float/double? - StackOverflow(링크)
https://en.wikipedia.org/wiki/IEEE_754(링크) ->중간의 'Rounding rules' 항목 참고
https://en.wikipedia.org/wiki/Rounding(링크)