'string_of_float' only prints 12 digits, which loses some digits, see discussion at ocaml/ocaml#11975.
Using %.17g instead should suffice for preserving all digits, however the numbers printed can have extra "ugly" unnecessary digits for commonly used values:
# Printf.sprintf "%.17g" 3.14;;
- : string = "3.1400000000000001"
To reproduce:
#require "owl";;
open Owl
let df = Dataframe.make ~data:[|Dataframe.pack_float_series [|1.;1. +. Float.epsilon|]|] [|"f"|] in Dataframe.to_csv df "/tmp/foo";; Dataframe.of_csv "/tmp/foo.csv";;
https://ocaml.org/p/base/latest/doc/Base/Float/index.html#val-to_string has a pragmatic approach: try %.15g, and check that it round-trips, if not then use %.17g. See longer explanation at https://github.com/janestreet/base/blob/v0.15.0/src/float.ml#L68-L172
P.S.: Npy write/read doesn't have this problem: it preserves the float in its entirety.
'string_of_float' only prints 12 digits, which loses some digits, see discussion at ocaml/ocaml#11975.
Using
%.17ginstead should suffice for preserving all digits, however the numbers printed can have extra "ugly" unnecessary digits for commonly used values:To reproduce:
https://ocaml.org/p/base/latest/doc/Base/Float/index.html#val-to_string has a pragmatic approach: try
%.15g, and check that it round-trips, if not then use%.17g. See longer explanation at https://github.com/janestreet/base/blob/v0.15.0/src/float.ml#L68-L172P.S.: Npy write/read doesn't have this problem: it preserves the float in its entirety.