[CPP-Module/ex01 : Towards a more useful fixed point class 과제]
인자를 고정소수값으로 변환해주는 생성자 함수를 만들어라. 이때 fractional bits는 8
이다.
toFloat
과 toInt
멤버함수를 만들어 고정소수값을 각각 다시 부동소수값, 정수값으로 변환할 수있도록 해라.
헤더, 소스에 <<
연산자 오버로드를 추가한다.
toFloat
활용각각의 개념과 변환 과정에 대한 내용은 이 블로그에 잘 정리되어 있다. 부동소수값은 우리가 이미 흔히 사용하고 있다. float
, double
같은 자료형이 부동소수값으로 저장되어 있다.
고정소수값은, 소수 부분을 표현할 비트의 수를 미리 정해두고 10진수를 2진수로 변환한 값을 그대로 비트에 넣은 값이다.
예를 들면 7.625라는 실수가 있다고 치자. 2진수로 변환하면 111.101이 될 것이다. 이걸 다음 그림처럼 저장한다.
이러한 고정소수점 방식은 구현하기 편리하지만 사용하는 비트 수 대비 표현 가능한 수의 범위 또는 정밀도가 낮기 때문에 실수를 다룰 필요가 있는 범용 시스템에서는 거의 안 쓰이고, 높은 정밀도가 필요없는 소규모 시스템에서는 쓰인다고 한다. 임베디드 같은?
다시 고정소수값의 개념을 정리하자면, 2진법 정수 혹은 부동소수값의 소수 부분을 넣을 비트 수를 정해두고 표현 하는 것이다. 우리 과제처럼 그 비트 수(fractional bits)를 8비트로 정했다면 32비트 체계에서는 앞의 24비트를 정수 부분으로, 뒤의 8비트를 소수부분으로 표현한다.
따라서 임의의 2진수 정수 N을 고정소수값으로 표현하기 위해서는, 앞으로 8비트만큼 <<
비트 시프트 연산을 해줘야 한다. 그래야 마지막 8칸을 N.00000000
같은 식으로 소수로 표현할 수 있기 때문이다.
비트 체계에서는 한 칸이 하나의 자릿수를 의미하니, <<
연산은 왼쪽으로 한 칸 시프트할 때 마다 2를 제곱해주면 된다. 반대의 과정은 2를 8번 나눠주는 식으로 가능할 것이다.
즉, fractional bits가 8일 때 공식을 정리하자면 다음과 같다.
N << 8
혹은N * 256
fixed_point_number >> 8
혹은 fixed_point_number / 256
(float)fixed_point_number / (1 << 8)
혹은 (float)(fixed_point_number / 256)