Includes not only infinite-precision [correction: arbitrary-precision] floats (not sure about the correct rounding part) but also integers (so subsumes GMP), rationals, complex numbers, and polynomials.
Includes not only infinite-precision [correction: arbitrary-precision] floats (not sure about the correct rounding part) but also integers (so subsumes GMP), rationals, complex numbers, and polynomials.
The original library claim for correct rounding is very important for many tasks, and is the entire reason for that library. I doubt your library does it, it it would claim it, since it's extremely hard to do and would be a great selling point.
Here's [1] a slightly older paper with lots of details on the problems in getting such a library to work. There's massive literature on this
[1] https://hal-ens-lyon.archives-ouvertes.fr/ensl-01529804/file...
True. I've edited my comment to reflect the error.
> I doubt your library does it
Just for the record, CLN is not mine. I'm just a (casual) user. And you're right, it probably does not do correct rounding. I was unaware of the significance of this.
The above notwithstanding, I think CLN is pretty cool and deserves more attention than it gets.
Agreed - I think all such libraries are interesting. Knowing the pitfalls of them is also useful and not obvious.
When reproducibility doesn't matter, it's basically always better to use a not-necessarily-correctly-rounded implementation at somewhat higher precision, as this gets you smaller overall errors for less effort. But there are a lot of domains where reproducibility matters, and that's where correct rounding comes in.
"If you input 0.1 into atan, the result should round up when outputting 5 digits, down with 8 digits and up with 12 digits"?
Also, "round up" is not any easier than "round correctly" if you require it to be consistent. Say you compute a result like 9.004 and want to round to two digits - if the exact result would have been 8.991, then rounding your computation as 9.01 is different from the standard-specified result of 9.00.
So your standard would literally have to specify the desired output for every combination of operation, input, and output precision - obviously impossible.
This, FWIW, is what GCC uses MPFR for.
If it doesn't matter, then high precision rarely matters either. Once you have results with unknown noise in them, and you do a few operations on those, the noise compounds, at approximately sqrt(N) bits for N steps of computation (rough estimate, it certainly depends on algorithm selection, compiler nuances, stability of problem, etc.). So high precision degrades quickly when doing any work without using a reproducible and understood rounding mode.
>correct rounding is that it is the easiest mechanism to unlock reproducibility
Any rounding method works works for reproducibility - truncate, round to zero, Bankers rounding, etc., all (roughly) equivalently hard/easy to implement. However, pretty much none of these are possible without the ability to do correcting rounding first as a result of the Table Makers' Dilemma.
For example, Banker's rounding is generally better for doing computation than the usual correctly rounded. Knuth has some papers on this somewhere which are fascinating.
Also note most of the non-reproducible issues in numerical computation are compiler added - compile code with GCC version X, get one result, compile with later version, and results may change. Or across compilers. Negative 0, denormals, rounding modes, all need carefully dealt with. It can be done, but is not trivial. Keeping floating point solid is very, very tricky over compilers and time.
This isn't really true for any of the numerous numerical algorithms that satisfy backwards error bounds; there you would always prefer to have a well-rounded arithmetic at higher precision, if reproducibility is not required.
> Any rounding method works works for reproducibility
Only if you round _correctly_ in that direction.
> Banker's rounding is generally better for doing computation than the usual correctly rounded.
Banker's rounding _is_ the default IEEE 754 rounding mode.
And in case its relevant, in this setting, students are only allowed to use single (32-bit) precision floats and operations.
That's actually a good method that lots of numerical analysts use. I think C99 has several rounding modes - I often have code that runs the same computation under each mode and look at what your doing.
>not all crappy code generates a wide window
True, often you need to find the values that make it puke. I think there was a paper recently on doing this automatically.... If I can refind it I'll post - it was cool stuff.
>students are only allowed to use single (32-bit) precision floats and operations
For stuff this small you can often brute force all values or at least all edge case values. I sometimes do the trick of converting 32 bit integers (watch out for weird C aliasing rules) to hit lots of numbers near precision edges and run them through, denormals, other edge cases, and pseudo-fuzz the results. This will sometimes turn up more.
If you teach, and have not worked through some numerical analysis books that provide good background for this stuff, read Goldberg's paper "What Every Computer Scientist Should Know About Floating-Point Arithmetic" [1]. The next good thing to dig through is Higham's book "Accuracy and Stability of Numerical Algorithms" [2]
Those will give you lots of places to look for issues, and the ability to analyze algorithms more concretely for floating point issues.
[1] https://docs.oracle.com/cd/E19957-01/800-7895/800-7895.pdf [2] http://ftp.demec.ufpr.br/CFD/bibliografia/Higham_2002_Accura...
In my class, FP computation is something I try to teach the students to be mindful of, but it is hardly the focus of the class (about certain kinds of data visualization). FP computation arises in lots of different places in many different functions, often in the context of a larger data processing pipeline that actually starts and ends with 16-bit integers (e.g. medical imaging data). So I'm not sure how I'd thoroughly exercise the FP-related code in the way that you describe. Hence my current use of something I can easily control at the outset of the whole pipeline (the direction of rounding).
Do you have any ideas on injecting randomized rounding mode changes prior to FP ops in the assembly, or something functionally equivalent for characterizing C code (ideally without code changes)? I just found [1] which seems extremely related, but I'll have to look into whether the code still works.
[2] https://tel.archives-ouvertes.fr/tel-03110553/document
https://www.mpfr.org/mpfr-4.0.1/timings.html
Also, MPFR depends on GMP which has integers and rationals. Then there is MPC which in turn depends on MPFR and provides complex numbers.