IEEE 754 부동 소수점 관련 간단한 정리.

Date:     Updated:

카테고리:

태그:

IEEE754 부동소수점

부동 소수점의 구성.

  1. 부호부 : 최상위 1비트(양수, 음수 판별)
  2. 지수부 : 부호부 다음 8비트
  3. 가수부 : 지수부 다음 23비트

-38.625를 이진법으로 변환한다.

-38.625를 이진법으로 변환한다.

  1. 처음 부호부는 -38.625가 음수이니 1을 넣어준다.
  2. 38.625에 대한 이진 수 변환처리를 해보면 100110.101이 된다.
  3. 소수점을 왼쪽으로 이동시켜 정수부가 한 자리가 되도록 만든다.

따라서 100110.101 → 1.00110101이 된다.

  1. 3번에서 왼쪽으로 몇 번 이동했는가? 5번 이동했다. 이동한 자릿수만큼을 2의 지수로 하여 곱해준다.

따라서 1.00110101 * 2^5가 되며, 이를 정규화 된 부동 소수점이라고 한다.

  1. 지금껏 계산했던 소수점 아래 부분(0011 0101)이 가수부(23비트)가 되도록 나머지 비트를 0으로 채운다. (0011 0101 0000 0000 0000 000 * 2^5) ← 이걸 가수부라고 한다.
  2. 32bit IEEE754에는 Bias라는 게 있다. 이건 127 값이며, 우리는 위에서 곱한 2의 지수(5)를 더해서 이를 이진수로 변환한다 (127 + 5 == 132 → 1000 0100) ← 이게 지수부(8비트)이다.
  3. 이걸 조합하면 1(부호부) 1000 0100(지수부) 0011 0101 0000 0000 0000 000(가수부)가 된다.

float을 int로 conversion할 때 일어나는 일.

std::cout << "static_cast<int>(52.6f) = " << static_cast<int>(52.6f) << std::endl;
std::cout << "static_cast<int>(-74.3f) = " << static_cast<int>(-74.3f) << std::endl;\

//static_cast<int>(52.6f) = 52
//static_cast<int>(-74.3f) = -74
  • 여기서 알아야 할 것은 내림이 아니라, 버리는 것이다.

일어날 수 있는 문제점

  • 정밀도 손실 → float값에 소수점 이하 부분이 포함되어 있을 경우, int로 변환할 시에 소수점 이하가 버려져서 원래 값의 일부 정보가 손실될 수 있다.
  • 범위 초과(오버 플로우) → float가 표현할 수 있는 값의 범위는 int의 범위와 다르다. 따라서 float값이 담고있는 범위가 int와 다를 때, 결과가 정의되지 않거나 예기지 못한 값이 나올 수 있다.
	float aa = 321321354132132.23;
	cout << aa << endl;
	cout << static_cast<int>(aa);
	
	//3.21321e+14
  //-2147483648
  • 위에서 서술했듯이, float을 int로 형변환 할 때는 기본적으로 소수점 이하를 버림(내림이 아님) 처리한다. 따라서 반올림을 기대하는 경우에는 별도의 처리가 필요하다.

이 부작용을 줄이기 위한 방법

  1. 범위 검사 → int형이 표현할 수 있는 범위인가? 먼저 검사해서 예외처리
  2. 반올림이 필요할 경우(rount, floor, ceil)과 같은 함수를 사용한다.
#include <cmath>
float f = 9.99f;
int i = static_cast<int>(std::round(f)); // 올바른 반올림 처리 후 변환

  1. 암시적 형변환이 아닌 명시적 형변환을 통해 암시적 형변환의 예기치 못한 부작용 방지.

Cpp 카테고리 내 다른 글 보러가기

댓글 남기기