Principia icon indicating copy to clipboard operation
Principia copied to clipboard

Deterministic floating-point arithmetic

Open eggrobin opened this issue 7 years ago • 1 comments

  • find the right set of flags to prevent floating-point contraction while still allowing optimizations that make assumptions about the rounding mode and ignore floating-point exceptions;
  • use the same (correctly-rounded) libm on all platforms.

eggrobin avatar Mar 17 '18 11:03 eggrobin

Someone asked on Discord, so I thought I would clarify what this issue does. The important part is the second bullet, "use the same (correctly-rounded) libm on all platforms".

As things stand, our saves are not portable from one platform to another or from one version of a platform to the next. It all comes from the elementary functions libraries (the "libm" of the issue description) which behave differently between platforms and versions. C++ doesn't mandate what functions like std::sin does, and various implementation return different results (macOS and Windows are rather good, Linux is pretty lame).

This makes our tests unnecessarily complicated and brittle (see for instance the tolerances here) but more importantly it actually means that saves will change behaviour when copied to another system, or when the underlying operating system is upgraded. This is not only a theoretical issue: a recent Windows upgrade caused the Reach flight plan to break (#4188).

The solution is to use a library that is "correctly rounded", i.e., that returns, for each value of the argument x in double, the machine number closest to the exact mathematical value of sin(x). This is, however, a hard problem, see this paper for details.

There exists one correctly-rounded open-source library, the CORE-MATH project. Unfortunately, its performance is rather disappointing (5-10× slower than the native libraries) so our strategy is to have our own implementation (starting with sin and cos, which are the functions we use the most) that is reasonably fast, but detects if it is at risk of not returning a correctly-rounded result, and falls back to CORE-MATH in that case.

We've been working on this on and off since 2018, and it's not clear if it will come to fruition. One of the main difficulties is that it's not possible to check correctness for all the values of the double argument, so we need careful mathematical proofs that our implementation is indeed doing what it purports to do.

pleroy avatar Jul 20 '25 10:07 pleroy