[CPP-02] 정수/부동소수값 <-> 고정소수값 변환

이대현·2021년 4월 25일
0

C / CPP

목록 보기
20/28

[CPP-Module/ex01 : Towards a more useful fixed point class 과제]

  • 인자를 고정소수값으로 변환해주는 생성자 함수를 만들어라. 이때 fractional bits는 8이다.

  • toFloattoInt 멤버함수를 만들어 고정소수값을 각각 다시 부동소수값, 정수값으로 변환할 수있도록 해라.

  • 헤더, 소스에 << 연산자 오버로드를 추가한다.

    • 고정 소수점 값의 부동 소수 표현을 매개 변수 출력 스트림에 삽입한다.
    • toFloat 활용

1. 부동소수와 고정소수

각각의 개념과 변환 과정에 대한 내용은 이 블로그에 잘 정리되어 있다. 부동소수값은 우리가 이미 흔히 사용하고 있다. float, double 같은 자료형이 부동소수값으로 저장되어 있다.

고정소수값은, 소수 부분을 표현할 비트의 수를 미리 정해두고 10진수를 2진수로 변환한 값을 그대로 비트에 넣은 값이다.

예를 들면 7.625라는 실수가 있다고 치자. 2진수로 변환하면 111.101이 될 것이다. 이걸 다음 그림처럼 저장한다.

img

  • 맨 앞 1자리는 부호 비트 (Sign Bit) 라고 해서 0이면 양수, 1이면 음수라는 뜻이다.
  • 우리 과제에서 소수점의 위치는 8번째 비트 다음이다.
  • 소수부의 경우 앞에서부터 채우며 남는 뒷자리는 다 0으로 채운다.

이러한 고정소수점 방식은 구현하기 편리하지만 사용하는 비트 수 대비 표현 가능한 수의 범위 또는 정밀도가 낮기 때문에 실수를 다룰 필요가 있는 범용 시스템에서는 거의 안 쓰이고, 높은 정밀도가 필요없는 소규모 시스템에서는 쓰인다고 한다. 임베디드 같은?


2. 고정소수값 변환 공식

다시 고정소수값의 개념을 정리하자면, 2진법 정수 혹은 부동소수값의 소수 부분을 넣을 비트 수를 정해두고 표현 하는 것이다. 우리 과제처럼 그 비트 수(fractional bits)를 8비트로 정했다면 32비트 체계에서는 앞의 24비트를 정수 부분으로, 뒤의 8비트를 소수부분으로 표현한다.

따라서 임의의 2진수 정수 N을 고정소수값으로 표현하기 위해서는, 앞으로 8비트만큼 << 비트 시프트 연산을 해줘야 한다. 그래야 마지막 8칸을 N.00000000 같은 식으로 소수로 표현할 수 있기 때문이다.

비트 체계에서는 한 칸이 하나의 자릿수를 의미하니, << 연산은 왼쪽으로 한 칸 시프트할 때 마다 2를 제곱해주면 된다. 반대의 과정은 2를 8번 나눠주는 식으로 가능할 것이다.

즉, fractional bits가 8일 때 공식을 정리하자면 다음과 같다.

1) 고정소수값(fixed_point_number)으로 변환

  • N << 8 혹은
  • N * 256

2) 고정소수값을 정수로 변환

  • fixed_point_number >> 8 혹은
  • fixed_point_number / 256

3) 고정소수값을 실수로 변환

  • (float)fixed_point_number / (1 << 8) 혹은
  • (float)(fixed_point_number / 256)
profile
삽질의 기록들 👨‍💻

0개의 댓글