From mboxrd@z Thu Jan 1 00:00:00 1970 Received: (from majordomo@localhost) by pauillac.inria.fr (8.7.6/8.7.3) id KAA28535; Tue, 10 Dec 2002 10:49:32 +0100 (MET) X-Authentication-Warning: pauillac.inria.fr: majordomo set sender to owner-caml-list@pauillac.inria.fr using -f Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by pauillac.inria.fr (8.7.6/8.7.3) with ESMTP id KAA28228 for ; Tue, 10 Dec 2002 10:49:31 +0100 (MET) Received: from pauillac.inria.fr (pauillac.inria.fr [128.93.11.35]) by concorde.inria.fr (8.11.1/8.11.1) with ESMTP id gBA9nOX08573; Tue, 10 Dec 2002 10:49:24 +0100 (MET) Received: (from xleroy@localhost) by pauillac.inria.fr (8.7.6/8.7.3) id KAA28125; Tue, 10 Dec 2002 10:49:23 +0100 (MET) Date: Tue, 10 Dec 2002 10:49:23 +0100 From: Xavier Leroy To: jeanmarc.eber@lexifi.com Cc: caml-list@inria.fr Subject: Re: [Caml-list] float pretty-printing precision, once more. Message-ID: <20021210104923.A26880@pauillac.inria.fr> References: <1039475060.3df52174c32a4@imp.pro.proxad.net> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Mailer: Mutt 1.0i In-Reply-To: <1039475060.3df52174c32a4@imp.pro.proxad.net>; from jeanmarc.eber@lexifi.com on Tue, Dec 10, 2002 at 12:04:20AM +0100 Sender: owner-caml-list@pauillac.inria.fr Precedence: bulk > # let f = 1. /. 86400.;; > val f : float = 1.15740740741e-05 > # let s = string_of_float f;; > val s : string = "1.15740740741e-05" > # let f1 = float_of_string s;; > val f1 : float = 1.15740740741e-05 > # f1 = f;; > - : bool = false > # f1 -. f;; > - : float = 2.59259844496e-17 > > This situation may be understandable, but is unfortunate. Well, you get a relative error of 2e-12. Are you sure your computations require more precision than this? In physics, the answer would be almost universally "no". In finance, you know better than I... > Suppose you calculate somewhere (with an caml program, say) a float > constant (such a calculation may last for hours!), and you want after > obtaining the result to *generate* a caml source using this calculated > value. You will probably generate something like > > let my_const = > > But my example shows that you are loosing precision and accuracy if you > just use string_of_float. There are two approaches to your problem: 1- The physicist's approach: Your float constant is known to have no more than N significant digits (e.g. because it's based on measurements that have a 10^-N error margin). Then, use the printf %g format corresponding to N to generate your source. 2- The programmer's approach: Having no idea on the actual precision of their data, programmers want bit-for-bit identity on float representation. You can do that in OCaml using Int64.bits_of_float and Int64.float_of_bits, which give direct access to the IEEE bit-level representation of floats. For instance, generate your Caml code with printf "let my_const = Int64.float_of_bits(Int64.of_string \"%Ld\")\n" (Int64.bits_of_float my_const) That will generate something like let my_const = Int64.float_of_bits(Int64.of_string "4532949752942055721") which is truly unreadable, but it guaranteed to give you the exact same float when executed. (To help reading the source, consider putting the decimal representation of the float in a generated comment.) Hope this helps, - Xavier Leroy ------------------- To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ Beginner's list: http://groups.yahoo.com/group/ocaml_beginners