Fixed Point Algorithm For STM32
Fixed Point Algorithm For STM32 Abstract For You Information Code Good Luck
Abstract
An implementation of Fixed Point algorithm for STM32 or any other MCUs which have no FPU support.
For You Information Motive When using STM32F10x MCU, the lack of FPU makes the float computation too slow for a time sensitive processing–for example, an interrupt handle which should get job done in milliseconds. Assembly language is a good way but not best, because it involves the learning of another language and less generic. Not sure if others had built the wheels, but I like to reinvent it–for nothing else, just because I can. Compiler The implementation was written in C++ with templates. By now, most embedded GCC compilers should work well. MCU Architecture The implementation is designed to work on a 32-bit MCU. It works on 16-bit MCU too. Limitation of Precision and Range To represent a float number, the implementation uses partial bits of 32-bit/64-bit integer to represent the integer part and fraction part. It also means the precision and the range the fixed point can represent are limited. For 32-bit representation, the integer part uses 21 bits and the fraction uses 11 bits. For 64-bit, the bits are 42 and 22, just doubled. Further more, the situation of overflow is not considered. It’s your responsibility to handle it.Keep this in mind when using the code. Understanding The Fixed Point I assume you already knew the Fixed Point algorithm. If don’t, please teach yourself. It’s very simple. Liability The code is free for using for anyone. In no event shall I be liable for any situation arising in any way out of the use of the code. Take your own risk to use the code.
Code
Enough talk, let’s show the code.
Good Luck
Abstract
An implementation of Fixed Point algorithm for STM32 or any other MCUs which have no FPU support.
For You Information
Code
Enough talk, let’s show the code.
/*
* fxfloat.hpp
*
* Created on: Mar 4, 2019
* Author: igame
*/
#ifndef FXFLOAT_HPP_
#define FXFLOAT_HPP_
namespace igame {
template<typename T = int64_t>
class FxFloat {
public:
const uint32_t fixed_point_32bits = 11;
const uint32_t fixed_point_64bits = 22;
const uint32_t fixed_point_bits = sizeof(T) == 8 ? fixed_point_64bits : fixed_point_32bits;
const int64_t fixed_point_scale = (int64_t)1 << fixed_point_bits;
const uint64_t fixed_point_fraction_mask = ((uint64_t)0xFFFFFFFFFFFFFFFF >> (32 - fixed_point_bits));
const int64_t fixed_point_max = (int64_t)0x3F3F3F3F3F3F3F3F;
const int64_t fixed_point_min = -fixed_point_max;
public:
typedef T value_type;
typedef const T const_value_type;
public:
value_type value{ 0 };
public:
FxFloat() { }
FxFloat(const float x) {
int64_t integer = ((int64_t)x) << fixed_point_bits;
int64_t fract = (int64_t)((x - (int64_t)x) * fixed_point_scale);
this->value = integer + fract;
}
/// convert back to float
INLINE operator float() {
return to_float();
}
/// Assignment
INLINE FxFloat& operator = (const int64_t& right) {
this->value = right;
return *this;
}
INLINE FxFloat& operator = (const float& right) {
this->value = from_float(right);
return *this;
}
INLINE FxFloat& operator = (const FxFloat& right) {
return this->operator = (right.value);
}
/// Add
INLINE FxFloat& operator += (int64_t right) {
this->value += right;
return *this;
}
INLINE FxFloat& operator += (const float& right) {
return this->operator += (from_float(right));
}
INLINE FxFloat& operator += (const FxFloat& right) {
return this->operator += (right.value);
}
/// Sub
INLINE FxFloat& operator -= (const int64_t& right) {
this->value -= right;
return *this;
}
INLINE FxFloat& operator -= (const float& right) {
return this->operator -= (from_float(right));
}
INLINE FxFloat& operator -= (const FxFloat& right) {
return this->operator -= (right.value);
}
/// Mul
INLINE FxFloat& operator *= (const int64_t& right) {
this->value *= right;
this->value >>= fixed_point_bits;
return *this;
}
INLINE FxFloat& operator *= (const float& right) {
return this->operator *= (from_float(right));
}
INLINE FxFloat& operator *= (const FxFloat& right) {
return this->operator *= (right.value);
}
/// Div
INLINE FxFloat& operator /= (const int64_t& right) {
if (right == 0) {
this->value = fixed_point_max;
}
else {
this->value <<= fixed_point_bits;
this->value /= right;
}
return *this;
}
INLINE FxFloat& operator /= (const float& right) {
return this->operator /= (from_float(right));
}
INLINE FxFloat& operator /= (const FxFloat& right) {
return this->operator /= (right->value);
}
private:
INLINE int64_t from_float(const float& x) {
int64_t integer = ((int64_t)x) << fixed_point_bits;
int64_t fract = (int64_t)((x - (int64_t)x) * fixed_point_scale);
return integer + fract;
}
INLINE float to_float() {
(float)this->value / fixed_point_scale;
}
};
/// Global Operator Overloading
template<typename T>
INLINE FxFloat<T> operator + (FxFloat<T>& left, FxFloat<T>& right) {
FxFloat<T> res{ left };
res += right;
return res;
}
template<typename T>
INLINE FxFloat<T> operator + (const FxFloat<T>& left, const float& right) {
FxFloat<T> res{ left };
res += right;
return res;
}
template<typename T>
INLINE FxFloat<T> operator + (const float& left, const FxFloat<T>& right) {
FxFloat<T> res{ left };
res.value += right;
return res;
}
template<typename T>
INLINE FxFloat<T> operator - (FxFloat<T>& left, FxFloat<T>& right) {
FxFloat<T> res{ left };
res -= right;
return res;
}
template<typename T>
INLINE FxFloat<T> operator - (const FxFloat<T>& left, const float& right) {
FxFloat<T> res{ left };
res -= right;
return res;
}
template<typename T>
INLINE FxFloat<T> operator - (const float& left, const FxFloat<T>& right) {
FxFloat<T> res{ left };
res.value -= right;
return res;
}
template<typename T>
INLINE FxFloat<T> operator * (FxFloat<T>& left, FxFloat<T>& right) {
FxFloat<T> res{ left };
res *= right;
return res;
}
template<typename T>
INLINE FxFloat<T> operator * (const FxFloat<T>& left, const float& right) {
FxFloat<T> res{ left };
res *= right;
return res;
}
template<typename T>
INLINE FxFloat<T> operator * (const float& left, const FxFloat<T>& right) {
FxFloat<T> res{ left };
res.value *= right;
return res;
}
template<typename T>
INLINE FxFloat<T> operator / (FxFloat<T>& left, FxFloat<T>& right) {
FxFloat<T> res{ left };
res /= right;
return res;
}
template<typename T>
INLINE FxFloat<T> operator / (const FxFloat<T>& left, const float& right) {
FxFloat<T> res{ left };
res /= right;
return res;
}
template<typename T>
INLINE FxFloat<T> operator / (const float& left, const FxFloat<T>& right) {
FxFloat<T> res{ left };
res /= right;
return res;
}
} // ns igame
#endif /* FXFLOAT_HPP_ */
Good Luck