caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Andreas Rossberg <rossberg@mpi-sws.org>
To: Oleg <oleg@okmij.org>
Cc: asai@is.ocha.ac.jp, caml-list@inria.fr
Subject: Re: [Caml-list] string_of_float (0.1 +. 0.2)
Date: Thu, 16 Jun 2022 11:01:32 +0200	[thread overview]
Message-ID: <57A2C5E8-34C7-4B90-9FEF-607B8236E379@mpi-sws.org> (raw)
In-Reply-To: <20220616062405.GA1555@Melchior.localnet>

[-- Attachment #1: Type: text/plain, Size: 1438 bytes --]

Since I believe it hasn’t been stated explicitly in this thread yet, a reminder that it is generally _impossible_ to represent arbitrary float values accurately (and finitely) in decimal notation. Except for few cases, you will have to cut off and round at some point.

But that doesn’t necessarily mean that round-tripping between text and binary loses precision, as long as the rounding is precise enough for both binary-to-text and text-to-binary conversion. Though as Oleg points out, that is not an easy problem.

> On 16. 6. 2022, at 08:24, Oleg <oleg@okmij.org> wrote:
> 
> In practice in our recent project, we settled on
> 
> let float : float -> float cde = fun x ->
>  let str = if Float.is_integer x then string_of_float x else
>            Printf.sprintf "%.17g" x

"%.17g" is what we use in the WebAssembly reference interpreter as well. Plus, we do some extra work to also preserve -0.0 and NaNs. Simplified a bit, it's something like this:

  let float_to_string x =
    let x' = abs_float x in
    (if Int64.bits_of_float x < 0L then "-" else "") ^
    if x' <> x' then
      let payload = Int64.(logand (bits_of_float x') 0x000f_ffff_ffff_ffffL) in
      "nan:0x" ^ Printf.sprintf "%Lx" payload
    else
      let s = Printf.sprintf "%.17g" x' in
      if s.[String.length s - 1] = '.' then s ^ "0" else s

Our of_string function recognises the special NaN syntax accordingly.

/Andreas


[-- Attachment #2: Type: text/html, Size: 2684 bytes --]

  reply	other threads:[~2022-06-16  9:01 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-06-15  1:59 Kenichi Asai
2022-06-15  6:22 ` Andreas Rossberg
2022-06-15  7:00   ` François Pottier
2022-06-15 14:07 ` Gabriel Scherer
2022-06-15 14:25   ` Daniel Bünzli
2022-06-16  1:45     ` Kenichi Asai
2022-06-16  6:24       ` Oleg
2022-06-16  9:01         ` Andreas Rossberg [this message]
2022-06-16  9:14           ` [Caml-list] unsubscribe Jean-Denis EIDEN JEAN-DENIS

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=57A2C5E8-34C7-4B90-9FEF-607B8236E379@mpi-sws.org \
    --to=rossberg@mpi-sws.org \
    --cc=asai@is.ocha.ac.jp \
    --cc=caml-list@inria.fr \
    --cc=oleg@okmij.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).