问题
This is similar to this question but not exactly the same.
i naively tried this:
let s prec = "%." ^ (string_of_int prec) ^ "f" in
Printf.printf (s 2) 1.23
but this is rejected, as well as replacing ^ by ^^. is there any way to do this?
回答1:
Since format string are type-safe they should be known at compile time. You can't take an arbitrary string and use it as a format string. This restriction still allows you to build formats from pieces, you just shouldn't forget to call format_of_string function, and make sure that all your formats are static, and resulting formats has the same type.
But, your particular case is already addressed by the formats, so you don't need to do anything fancy here. There is * specifier, that does exactly what you want:
# printf "%.*f" 10 1.0;;
1.0000000000- : unit = ()
# printf "%.*f" 1 1.0;;
1.0- : unit = ()
There is also Scanf.format_from_string that allows you to build arbitrary formats from dynamic strings. The following program demonstrates the flexibility of formats in OCaml:
let () =
print_endline "Floating point format: ";
let f = match read_line () with
| "engineering" -> "%e"
| "regular" -> "%f"
| "pretty" -> "%g"
| user -> user in
let fmt =
try Scanf.format_from_string f "%f"
with exn -> invalid_arg "Unrecognized format" in
Printf.printf (fmt^^"\n") (4. *. atan 1.)
Example:
ivg$ ocaml formats.ml
Floating point format:
pi = %.16f
pi = 3.1415926535897931
来源:https://stackoverflow.com/questions/28604446/printing-a-float-with-runtime-selectable-precision