caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: David Chase <chase@world.std.com>
To: caml-list@inria.fr
Subject: Re: [Caml-list] float pretty-printing precision, once more.
Date: Tue, 10 Dec 2002 23:03:55 -0500	[thread overview]
Message-ID: <5.2.0.9.0.20021210221857.02f85258@pop.theWorld.com> (raw)
In-Reply-To: <20021210164721.C7440@pauillac.inria.fr>

At 04:47 PM 12/10/2002 +0100, Xavier Leroy wrote:
>If that was really the best approximation, there would be nothing to
>argue.  But both 0.10000000000000001 and 0.1 read back as identical
>floats, so the latter should be printed instead, but sprintf (on
>Linux at least) is too stupid to realize this.

Gdtoa will supply you with the non-stupid answer, if you care
to ask it.  Again -- this I know well, I have used gdtoa to get
specification-conforming double->String conversion in a Java
VM/library.  Here is a test program that demonstrates how to
use gdtoa in "minimum unambiguous result length" mode.  This
assumes int is 32 bits long:

#include "gdtoa.h"
/* Always define to zero or one.  It is zero on Pentium. */
#define LITTLE_ENDIAN 1
FPI d_convert = { 53, 1-1023-53+1, 2046-1023-53+1, FPI_Round_near, 0};
union pun {
  double d;
  int i[2];
};
char * test_gdtoa(double d, int mode, int ndigits, int * plength, int * pdecpt) {
  union pun convert;
  convert.d = d;
  {
  int i0 = convert.i[0^LITTLE_ENDIAN];
  int i1 = convert.i[1^LITTLE_ENDIAN];
  
  int isNeg = i0 < 0;
  int m0 = i0 & 0xfffff;
  int e0 = ((unsigned)i0 >> 20) & 0x7ff; 
  int int_args[8];
  char * ptr_args[1];
  char * result;
  int length;
  
  /* NaN or Inf */
  if (e0 == 0x7ff) {
    if ((m0 | i1) != 0) {
      *plength = -1;
      return "NaN";
    } else {
      *plength = -1;
      return isNeg ? "-Infinity" : "Infinity";
    }
  }
  
  /* +/- 0 */
  if ((m0 | i1 | e0) == 0) {
    *plength = -1;
    return isNeg ? "-0.0" : "0.0";
  }
  
  /* If the exponent is larger than zero,
     then the leading "1" in the mantisssa
     is implicit.  Otherwise, the number is
     denormalized, and the exponent is
     really 1. */
  
  if (e0 != 0) m0 |= 0x100000;
  else e0 = 1;
  
  /* Adjust exponent to remove bias and to
     make the mantissa all "integer", e.g.
     12345e-4 instead of 1.2345e+0 */
  e0 -= 0x3ff + 52;
  int_args[0] = i1;
  int_args[1] = m0;
  int_args[2] = STRTOG_Normal;
  result = gdtoa(&d_convert, /* fpi */
                 e0,         /* be   */
                 int_args + 0, /* bits */
                 int_args + 2, /* kindP */
                 mode,         /* mode */
                 ndigits,      /* ndigits */
                 int_args + 3, /* decpt */
                 ptr_args + 0); /* rve */
  *pdecpt = int_args[3];
  length = ptr_args[0] - result;
  if (length == 0) {
      *plength = -1;
    return isNeg ? "-0.0" : "0.0";
  }
  *plength = length;
  return result;
  }
}

static test_one(double d) {
  int decpt;
  int length;
  char * result = test_gdtoa(d, 0, 0, &length, &decpt);

  if (length == -1) {
    printf("test of %f returns special value %s\n", d, result);
  } else {
    printf("test of %f returns regular value %s, decpt %d, length %d\n", d, result, decpt, length);
  }
}

int main(int argc, char ** argv) {
  test_one(1.0);
  test_one(1.0/0.0);
  test_one(-1.0/0.0);
  test_one(-1.0/0.0 + 1.0/0.0);
  test_one(0.0);
  test_one(-0.0);
  test_one(-1.0);
  test_one(0.25);
  test_one(4.0);
  test_one(8192.125);
  test_one(0.1);
  test_one(0.01);
  test_one(0.9);
  test_one(0.09);
  test_one(0.2);
  test_one(0.02);
  test_one(0.3);
  test_one(0.03);
}


David Chase


-------------------
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


  reply	other threads:[~2002-12-11  4:04 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-12-09 23:04 jeanmarc.eber
2002-12-09 23:46 ` Yaron M. Minsky
2002-12-10  0:07 ` Brian Hurt
2002-12-10  2:13 ` David Chase
2002-12-10  9:49 ` Xavier Leroy
2002-12-10 13:09 ` Damien Doligez
2002-12-10 15:37   ` Jacques Carette
2002-12-10 15:47   ` Xavier Leroy
2002-12-11  4:03     ` David Chase [this message]
2002-12-12  1:41       ` David Chase

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=5.2.0.9.0.20021210221857.02f85258@pop.theWorld.com \
    --to=chase@world.std.com \
    --cc=caml-list@inria.fr \
    /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).