TIL 018 고정소수점 연산

조성현·2021년 3월 1일
0

정글

목록 보기
20/21
post-custom-banner

📕 고정 소수점 연산

👉 실수를 표현하는 방법

실수를 표현하는 방법에는 두 가지가 있다.

  1. 고정 소수점
    정수를 표현하는 비트와 소수를 표현하는 비트를 정해 놓는다.
    예를 들어, 8비트에 4비트의 정수부 4비트의 소수부를 표현한다면
    11.011 을 0011 0110 으로 표현할 수 있다.
    int와 다름 없으므로 구현히 쉽고, 연산이 빠지만 표현할수 있는 범위가 작다.
    임베디드 시스템, 딥러닝(확률의 근사값이기 때문), FPGA에서 사용된다.

  2. 부동 소수점
    소수점이 '떠다니면서' 표현하는 방식이다. (한자로 浮動, 영어로 floating)
    실수를 x * 2^y 로 표현한 후 x,y 를 저장한다. ( 1<= x <2 , y = 정수)
    부동소수점은 넓은 범위 수를 표현하면서도, 상대적으로 정확하게 표현 가능하다.
    FPU 유닛에 연산되며, 그럼에도 불구하고 고정 소수점에 비해 상당히 느리다.

👉 IE77

IE77은 다음과 같이 실수를 나타낸다.

s = sign(부호) (양수:0, 음수:1)
M = significand(유효숫자)
E = exponent(지수)

단정도(single-precision)의 경우, E:8bit, M:23bit
배정도(double-precision)의 경우 E:11bit, M:52bit

3가지 인코딩 방법이 있는데
E가 000...0 인 경우, Denormalized value
E가 111...1 인 경우, Special value
그 외, Normalized value

표기방법 : 컴퓨터에서의 실수 표현

👉 고정 소수점 연산

만약 decimal point를 14 (정수 17bit, 소수 14bit) 한다면 정수에 2^14을 곱해줌으로써 고정 소수점으로 변경시킬 수 있다. 반대는 나눠준다.

int int_to_fp(int n)
{
    return n * 1<<14;
}

int fp_to_int_round(int x)
{
    return x / 1<<14;
}

사칙연산은 다음과 같다. 32비트를 넘기는 overflow가 발생할 수 있기 때문에 64비트연산을 표기를 사용하면 간단히 해결할 수 있다. 곱셈, 나눗셈에서 1<<14를 곱해주거나 나눠주거나 하는 이유는, 어차피 연산에 있는 날라갈 부분을 shift 시켜줌으로서 정확한 연산을 하기 위함이다.

int add(int x, int y)
{
    return x + y;
}

int sub(int x, int y)
{
    return x - y;
}

int mult(int x, int y)
{
    return ((int64_t)x) * y / 1<<14;
}

int div_fp(int x, int y)
{
    return ((int64_t)x) * 1<<14 / y;
}
profile
Jazzing👨‍💻
post-custom-banner

0개의 댓글