When working with embedded systems, it's not uncommon to encounter fixed-point mathematical operations. Many processors lack floating-point hardware support, resulting in inefficient software emulation of floating-point operations. Some situations require avoiding precision variability, and other situations require fixing the significand or exponent sizes to achieve specific precision targets. Additionally, fixed-point operations are portable and consistent across toolchains and architectures.

I recently stumbled across a C++11 `fixed_point`

header-only library. The library introduces a `fixed_point`

type, which is templated on two values:

```
template <class Rep, int Exponent>
class fixed_point;
```

The `Rep`

parameter indicates the capacity and signedness of the underlying representative data type. The default representation is `int`

, but you can supply any fundamental integral type or integral-like type. The library author's recommendation:

The most suitable types are:

`std::int8_t`

,`std::uint8_t`

,`std::int16_t`

,`std::uint16_t`

,`std::int32_t`

and`std::uint32_t`

. In limited situations,`std::int64_t`

and`std::uint64_t`

can be used. The reasons for these limitations relate to the difficulty in finding a type that is suitable for performing lossless integer division.

The `Exponent`

parameter is equivalent to the exponent field in a standard floating-point type and sets the precision of the `fixed_point`

number. Resolution of a `fixed_point`

number is `2^(Exponent)`

, so expect `Exponent`

to be negative.

The library also provides two helper functions: `make_fixed`

and `make_ufixed`

. These are declared as:

```
template <int IntegerDigits, int FractionalDigits = 0,
class Type = signed>
using make_fixed;
template <int IntegerDigits, int FractionalDigits = 0,
class Type = unsigned>
using make_ufixed;
```

Rather than worrying about underlying data types or exponent values, these helper functions allow you to specify the number of integral and fractional bits you wish to support:

```
//8-bit, unsigned, with 4 integer digits and 4 fractional digits
auto t = make_ufixed<4, 4> value { 15.9375 };
//32-bit, signed, with two integer digits and 29 fractional digits:
auto v = make_fixed<2, 29> value { 3.141592653 };
```

Normal mathematical operators (`+`

, `-`

, `/`

, `*`

) are supported with the `fixed_point`

class and work with one or two fixed-point arguments. However, the operators perform as little computation as possible, resulting in the possibility of overflows and information loss. To combat this, the library supports mathematical functions that handle data widening for the user: `negate`

, `add`

, `subtract`

, `multiply`

, `divide`

. These functional operations should be preferred to the mathematical operators.

```
auto f = fixed_point<uint8_t, -4>{15.9375};
auto p = multiply(f, f);
// p === fixed_point<uint16_t, -8>{254.00390625}
```

You can find the `fixed_point`

library on GitHub, or you can take a shortcut and clone it using:

`$ git clone https://github.com/johnmcfarlane/fixed_point.git`

The API is exposed through headers in the include directory. Add this to your system header list and include:

`#include <sg14/fixed_point>`