Расчеты с фиксированной запятой

Как уже упоминалось ранее, заметно ускорить расчеты позволяет целочисленная арифметика. Однако если расчеты без вещественных чисел невозможны (например, при обработке сигналов), то в системах без модуля FPU имеет смысл использовать тип с фиксированной запятой. Стандарт Си не включает арифметику с фиксированной запятой (а значит, ее нет и в стандартной библиотеке).

Реализация данного типа данных — нетривиальная задача, особенности которой можно найти в документе от компании ARM Application Note 33: Fixed Point Arithmetic on the ARM. Изобретать велосипед и писать библиотеку самостоятельно не стоит, так как уже существует платформонезависимая библиотека с открытым исходным кодом, libfixmath, позволяющая работать с числами формата Q16.16.

Библиотека предоставляет функции конвертации из стандартных типов Си в Q16.16 и обратно.

#include "fix16.h"
// ...
double a= fix16_to_dbl(a_fix);      // convert Q16.16 to a double
float b= fix16_to_float(b_fix);     // convert Q16.16 to a float
uint32_t c= fix16_to_int(c_fix);    // convert Q16.16 to an integer
fix16_t d= fix16_from_dbl(2.71);    // convert double to a Q16.16
fix16_t e= fix16_from_float(3.14f); // convert float to a Q16.16
fix16_t f= fix16_from_int(1024);    // convert integer to a Q16.16

Кроме стандартных (сложение, вычитание, умножение, деление) в библиотеке имеются и другие математические операции (логарифмические, тригонометрические, степенные и т.д.) Прототипы некоторых из них приведены ниже.

fix16_t fix16_acos(fix16_t inValue);
fix16_t fix16_div(fix16_t inValue);
fix16_t fix16_exp(fix16_t inValue);
fix16_t fix16_sin(fix16_t inValue);
fix16_t fix16_sqrt(fix16_t inValue);

Согласно цифрам, приведенным на сайте, ускорить работу программы на Cortex-M0 можно до 26,3%.


Изменено: