Open roberth opened 1 year ago
All of nix's floating point operations are already defined precisely (they are ieee754 float64's), except for printing.
My idea was to fully add (a variant of) ryu to print nicely while preserving precision.
We are working on a versioning RFC to make these backwards-incompatible changes possible in the future (cc @fricklerhandwerk).
I heard that some embedded platforms don't implement floats precisely according to ieee754, but I don't expect we need to be bothered by that, with Nix evals being quite expensive in practice.
Side note: I think there's generally too much FUD around floats. All operations doable on 32-bit integers are done without any loss of precision on 64-bit floats (with quite a few bits to spare). Yes, even the textbook counter-examples with floating-point control variable in a for loop...
Linking https://github.com/NixOS/nix/issues/5733#issuecomment-1529002378 as it's relevant.
Describe the bug
Native floating point
Native CPU floating point operations are not suitable for a portable deterministic language because they can produce slightly different results on different platforms or with different compiler settings due to variations in the precision and range of the floating point numbers used, as well as rounding errors. Portable deterministic languages aim to produce identical results on different platforms and with different compiler settings, so they typically use fixed-point or arbitrary-precision arithmetic libraries instead.
C++ footgun
Furthermore their printing has accidentally changed recently. Floats are too easy to use in ways that are not portable and deterministic.
8259
Steps To Reproduce
Expected behavior
Some ideas.
Arbitrary precision library
The rational numbers support all the operations we already support in the language:
I suspect that we can use a fairly small library for our purposes.
We already have OpenSSL bignum at our disposal for no extra dependency cost, but that's only an integer library. Boost and GNU libgmp provide rational number support but should be evaluated for our specific toString needs.
newtype
Use a C++ type that doesn't expose non-deterministic behavior, like
NixFloat = double
does.This is also useful for limiting the boost overhead to a single file if needed.
nix-env --version
outputAdditional context
8259
Priorities
Add :+1: to issues you find important.