`QCheck.Print.float` output legality and consistency
We should reconsider our use of string_of_float in QCheck.Print.float in favor of Printf.sprintf "%F".
The former
- doesn't print legal OCaml syntax (e.g.,
infand-infbelow) - isn't consistent across architectures (on macOS, MinGW, and MSVC
-. nanprints asnan, but as-nanon Linux, Cygwin, and with musl)
Here's Linux's behaviour of QCheck.Print.float:
# #require "qcheck-core";;
# let examples = Float.[0.0; -0.0; pi; infinity; neg_infinity; nan; -. nan];;
# List.iter (fun f -> QCheck.Print.float f |> print_endline) examples;;
0.
-0.
3.14159265359
inf
-inf
nan
-nan
whereas Printf.sprintf "%F" is guaranteed to print legal OCaml by the manual
(- F : convert a floating-point argument to OCaml syntax ( dddd. or dddd.ddd or d.ddd e+-dd ).):
# List.iter (fun f -> Printf.printf "%F\n" f) examples;;
0.
-0.
3.14159265359
infinity
neg_infinity
nan
nan
If we would like to distinguish nans with the sign-bit set (this could be considered a float special case after all), perhaps it is possible to write a special case for it in our printer (e.g., printing it as -.nan uniformly)? 🤔
(Spotted in https://github.com/ocaml-multicore/multicoretests/pull/565 and https://github.com/ocaml-multicore/multicoretests/pull/566)
This just came up again in https://github.com/c-cube/qcheck/pull/364 where I ended up inserting a special case to print negative nan as -nan across all platforms, but otherwise still using string_of_float.
I'm planning to start "the-great-combinator-renaming" next, which will involve lots of deprecations.
It would make sense to lump together such larger API changes with a switch to Printf.printf "%F"... 🤔