그라운드 임베디드 EN 유튜브 구독

노트 / 자료구조와 알고리즘

고정소수점 연산: 정수로 소수 다루기

FPU가 없는 MCU에서 소수를 빠르게 계산하는 Q 포맷. 스케일, 곱셈 후 시프트, 포화 처리를 정리했습니다.

GROUND EMBEDDED · 정리 노트자료구조 08고정소수점 연산 1int16_t q15_mul(int16_t a, int16_t b) { 2 int32_t r = (int32_t)a * b; 3 return (int16_t)(r >> 15); 4}

Cortex-M0나 8비트 MCU에는 부동소수점 연산기(FPU)가 없어서 float 곱셈 하나가 수십 클럭 걸립니다. 고정소수점은 정수에 "소수점이 여기 있다"는 약속을 더해 정수 연산 속도로 소수를 다룹니다.

Q 포맷

부호1비트소수 부분15비트
Q15. 16비트 가운데 맨 위는 부호, 나머지 15비트가 소수 부분입니다. 값 = 정수 ÷ 32768.

Q15는 16비트 정수에서 아래 15비트를 소수부로 씁니다. 실제 값 = 정수값 / 2¹⁵ 이라서 -1.0 이상 1.0 미만을 표현합니다.

실제 값 Q15 정수
0.5 16384
-0.25 -8192
0.999 32735

곱셈

Q15 × Q1532비트 결과Q3015비트 오른쪽 시프트Q15
Q15끼리 곱하면 Q30이 됩니다. 15비트를 오른쪽으로 밀어 다시 Q15로 맞춥니다.

Q15 두 개를 곱하면 Q30이 되므로 15비트 오른쪽으로 밀어 되돌립니다. 중간 결과는 32비트에 담습니다.

int16_t q15_mul(int16_t a, int16_t b) {
    int32_t r = (int32_t)a * b;
    return (int16_t)(r >> 15);
}

주의할 점

  • 오버플로: 더한 결과가 범위를 넘으면 부호가 뒤집힙니다. 최대값에서 멈추게 하는 포화 연산을 씁니다.
  • 정밀도: 작은 값을 여러 번 곱하면 아래 비트가 사라집니다. 적분기처럼 계속 더하는 변수는 비트를 넉넉히 줍니다.
  • 스케일 문서화: 변수마다 어떤 Q 포맷인지 이름이나 주석에 남겨야 나중에 섞어 쓰는 실수를 막습니다.

Cortex-M4처럼 FPU가 있으면 float이 오히려 편하고 빠를 수 있으니, 대상 MCU를 보고 고릅니다.

영상으로 이어 보기공부법과 진로 시리즈 15편2025 임베디드 프로그래밍 공부 순서 | 공부 방법 | 로드맵PROJECT COURSE배운 자료구조를 실제 펌웨어에 넣어 보고 싶다면밸런싱 로봇 하나를 요구사항, 회로와 PCB, 펌웨어, 앱까지 실무 순서대로 만드는 강의입니다. 10파트 165강.강의 살펴보기 →FREE PDF무료 전자책 3권 받기이 주제를 한 권으로 이어서 읽고 싶다면. BLDC 모터 제어, 직렬통신, 센서를 책 분량으로 묶었습니다. 이메일만 남기면 바로 받습니다.무료로 받기 →