printing a float with runtime-selectable precision

谁说我不能喝 提交于 2019-12-24 05:18:42

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!