2
votes

How to decide when to use fixed point arithmetic over float?

I have read that, fixed point is used when there is no Floating point unit in the processor. When there is no FPU, does that mean 'float' datatype is not supported ?

4
I wrote an answer on this topic on the EE site here. The TL;DR is: "If your MCU has a FPU and you actually need to do advanced math, then you should use floating point. Otherwise you should not."Lundin

4 Answers

2
votes
  • If you have no FPU fixed point will be faster and more deterministic
  • If you have no FPU fixed point will in many cases be smaller - certainly for simple arithmetic.
  • If you need your code to generate bit-identical results across different platforms or toolchains with or without an FPU, then fixed point is necessary.
  • If you need to do complex math requiring trig or log functions for example, floating point is the path of least resistance, but by no means the only option - but you need to develop or find a library (see links below) - and there are plenty of ways of doing that badly.
  • If you need wide dynamic range floating point is simpler. For example the square root of a number less than one is a smaller number - with fixed point you can run out of bits and end up with zero, with floating point, the point is simply moved to increase the resolution at the expense of range.
  • If you have an FPU and are using an RTOS and don't want the overhead of stacking FPU registers on a context switch (or if it is not supported), fixed-point avoids the need, and avoids errors if you forget to enable the option for every task that needs it.

Generally if your operation is trivial, use fixed point or at least an integer representation by selecting your units appropriately. For example storing voltage values in integer millivolts (or even in ADC quanta) rather then in volts can avoid unnecessary floating point.

If you are doing complex maths and have an FPU, floating point is the simpler, least error prone solution. Even without and FPU, if your solution meets timing and code size constraints, floating point may still be simpler, but may restrict your ability to use the same code in more constraint execution environments. So is reuse across a wide range of platforms is required fixed-point may be preferable.

Whatever you do, avoid "decimal fixed point" in most cases, use where possible use a binary fixed point representation (Q representation), where for example 10Q6 has 10 integer bits and 6 fractional bits. The reason for this is that rescaling following multiply/divide are then shift operations rather than potentially expensive multiply/divide operations and you loose no precision in the rescaling.

Some useful references:

0
votes

If there is no FPU available, compilers can often emulate floating point arithmetics. But this is inefficient, as it takes a lot of cycles.

If you are resource constraint (which you often are in environments without a FPU), you can then opt for fixed point arithmetic, which uses regular integer operations.

Just rambling: When I was using FP, I missed support from the compiler (C/C++) to be able to mark variables to be fixed point (with some specific number of fractional bits).

0
votes

If you have a standard compliant compiler, then float and double are always available and work correctly. If there isn't an FPU then the calculations are done in software (called soft-FPU or FPU emulation). This is slower and uses more memory.

When to use fixed point is mainly a matter of opinion, but when NOT to use it is when a variable has a large dynamic range, ie: when a number could be very large but you still need it to be accurate if it is very small.

Eg: Displaying the speed of a car. I need to know the difference between 68 and 70 mph, but I don't care about the difference between 0.68 mph and 0.70 mph. This has low dynamic range (that I care about) so I could use fixed-point if other reasons suggested that I might want to. Alternatively, measuring the radio-activity of a sample: I care about the difference between 100 and 90 counts per second and I still care about the difference between 1 and 0.9 counts per second. This high dynamic range means that fixed point would not be suitable.

0
votes

How to decide when to use fixed point arithmetic over float?

It depends on many factors which may or may not affect you, including...

Pros:

  • Fixed-point requires less circuitry so may be more practical on smaller, simpler devices.
  • Fixed-point uses less energy so may be more practical
    • on battery-powered devices,
    • in applications where intensive computation incurs a significant energy bill, or
    • where heat dissipation is a problem.
  • Fixed-point is really just integer arithmetic so operations are lossless.
  • Fixed-point allows you to precisely express real numbers in the number base of your choice, e.g. the values 1/10 or 1/3.
  • Floating-point arithmetic can exhibit inconsistent behavior related to things like
    • global rounding modes,
    • optimisation,
    • associativity,
    • implementation-defined behavior, and
    • variations in FPU hardware.

Cons:

  • While lossless, fixed-point arithmetic is prone to out-of-range errors, such as overflow. (Libraries and UB sanitizers can help avoid/detect errors.)
  • Lossless division is achieved with the help of the modulus operator (%), which is often harder to work with.
  • Fixed-point arithmetic is not as well supported in most languages: you have to perform error-prone calculations by hand using integers or find a library to help you.
  • Floating-point formats tend to be more consistent across architectures, unlike integers which vary in width and endianness.
  • Not only do floating-point types have a dynamic radix point, but the optimal position of that point is maintained automatically, saving headaches and precision loss.

Really, floating-point is an easy-to-use and widely-supported solution for representing real numbers. If floating-point works for you, think carefully before exploring alternatives.

Exception: an application where the pros make fixed-point a natural choice is currency. Lossless representation of denominations is especially important in finance. (example)

I have read that, fixed point is used when there is no Floating point unit in the processor.

That is true. Without an FPU, floating-point arithmetic is very slow!

When there is no FPU, does that mean 'float' datatype is not supported ?

No, that shouldn't necessarily follow, although implementations may vary. (IIRC, older versions of GCC had a flag to enable floating-point support.) It's entirely possible to perform floating-point operations using

  • the compiler, by generating equivalent ALU instructions, or
  • the system, by interrupting the process when an FPU instruction is encountered and deferring to a software routine.

Both of these are much slower, so using fixed-point arithmetic on such hardware may become a practical choice. It may be best to think of fixed-point as an optimisation technique, used once a performance deficit has been identified.