I'm confused at why you'd expect fixed point to avoid these problems. Consider auto pi = fixed_point<int16_t, -7>(3.141592654);
auto e = fixed_point<int16_t, -7>(2.718281828);
auto log2_10 = fixed_point<int16_t, -7>(3.321928095);
std::cout << (pi * e) * log2_10 << std::endl;
std::cout << pi * (e * log2_10) << std::endl;
These give 28.2422 and 28.2656 with the provided code, respectively.For float16s, these give 28.375 and 28.359 respectively. The correct answer is 28.368, so floats are much closer as well as being closer to each other. --- In fact, your example doesn't justify this calculation. If one is sending the accumulated values to C, one isn't worried about calculation error. You just need to require all parties that do calculate it to do so in agreement. There are several more targeted problems of floating point * C++ makes few guarantees about what floating point calculations do, and they can vary even between optimization levels. Languages like Python and Javascript fix this by setting well-defined behaviour. * Often one only needs a certain level of detail, so adaptive computations are just a waste. If you know the bounds of your map and the maximum zoom, a fixed precision gives more uniform calculations and often better precision. * Fixed precision has obvious and rounding-free addition. |