Hacker News new | ask | show | jobs
by sitkack 623 days ago
The other great thing about going fixed point is that it doesn't expose you to device specific floating point bugs, making your embedded code way more portable and easier to test.

32b float on your embedded device doesn't necessary match your 32b float running on your dev machine.

1 comments

32b float can match your desktop. Really just takes a few compiler flags(like avoiding -funsafe-math), setting rounding modes, and not using the 80bit Intel mode(largely disused after 64bit transition).
I understand what you are saying ...

You aren't guaranteed that your microcontrollers float is going to match your desktop. Microcontrollers are riddled with bugs, unless you need floats and fixedpoint is fast enough. My recommendation is still to use fixedpoint if application is high reliability.

Esp if your code needs to be portable across arm, risc-v, etc.

Many microcontrollers today, including ARM, RISC-V, and Xtensa have IEEE compliant FPUs or libms available. Same numeric format, same rounding, same result.

Fixed point isn't bad at all, just often slower when a compliant FPU is available.

> IEEE compliant FPUs or libms available. Same numeric format, same rounding, same result.

IEEE only mandates results within ½ ULP (= best possible) for basic operations such as addition, subtraction, multiplication, division, and reciprocal.

For many other ones such as trigonometric functions, exponential and logarithms, results can (and do) vary between conforming implementations.

https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.h...:

“The IEEE standard does not require transcendental functions to be exactly rounded because of the table maker's dilemma. To illustrate, suppose you are making a table of the exponential function to 4 places. Then exp(1.626) = 5.0835. Should this be rounded to 5.083 or 5.084? If exp(1.626) is computed more carefully, it becomes 5.08350. And then 5.083500. And then 5.0835000. Since exp is transcendental, this could go on arbitrarily long before distinguishing whether exp(1.626) is 5.083500...0ddd or 5.0834999...9ddd. Thus it is not practical to specify that the precision of transcendental functions be the same as if they were computed to infinite precision and then rounded. Another approach would be to specify transcendental functions algorithmically. But there does not appear to be a single algorithm that works well across all hardware architectures. Rational approximation, CORDIC,16 and large tables are three different techniques that are used for computing transcendentals on contemporary machines. Each is appropriate for a different class of hardware, and at present no single algorithm works acceptably over the wide range of current hardware.”

IEEE 754-2019 says for the transcendental functions (the ones in §9.2):

> A conforming operation shall return results correctly rounded for the applicable rounding direction for all operands in its domain.

so all of them are supposed to be correctly rounded. I think IEEE 754-2008 also requires correct rounding, but I don't have that spec in front of me right now.

In practice, they're not correctly rounded--the C specification explicitly disclaims the need for them to be (§F.3¶20), reserving the cr_ prefix for future mandatory correctly-rounded variants.

Thanks! Reading https://grouper.ieee.org/groups/msc/ANSI_IEEE-Std-754-2019/b... (“It is believed that any existing implementation of 754-2008 conforms to 754-2019”) it seems IEEE 754-2008 also required it.

Even with that and ignoring C’s “we don’t support that”), it still can be hard to write C code that provides identical results on all platforms. For example, I don’t think much code uses float_t or double_t or checks FLT_EVAL_METHOD (https://en.cppreference.com/w/c/types/limits/FLT_EVAL_METHOD)