delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2003/04/05/17:46:45

Sender: rich AT phekda DOT freeserve DOT co DOT uk
Message-ID: <3E8F48A3.2B0723E6@phekda.freeserve.co.uk>
Date: Sat, 05 Apr 2003 22:20:35 +0100
From: Richard Dawe <rich AT phekda DOT freeserve DOT co DOT uk>
X-Mailer: Mozilla 4.77 [en] (X11; U; Linux 2.2.23 i586)
X-Accept-Language: de,fr
MIME-Version: 1.0
To: djgpp-workers AT delorie DOT com
Subject: Re: Support for nan(0x[0-9a-f]*) in strto*, *printf
References: <200304031505 DOT RAA19060 AT lws256 DOT lu DOT erisoft DOT se>
Reply-To: djgpp-workers AT delorie DOT com

Hello.

Note to Juan Manuel Guerrero: We're only talking about how to support
nan(0x[0-9a-f]*) in *printf. It's unlikely that a patch will committed any
time soon.

Martin Stromberg wrote:
> 
> Richard said:
> > * (double) NAN or (long double) NAN results in the exponent being extended
> > up to the maximum for double or long double.
> 
> iff hardware FPU. Perhaps your mail only talks about hardware
> FPU. That's reasonable. I'll only think/talk of hardware FPU from now
> unless somebody explicitly talks about FPU emulation.

Yes, I am using a hardware FPU. FWIW I have an Athlon 850MHz ("Thunderbird", I
believe).

> > * (double) a long double NaN == a double NaN. See the test program t-nan.c
> > below.
> >
> > * (float) a long double NaN == a float NaN. See the test program t-nan.c
> > below.
> 
> You probably mean "the long double NaN used in t-nan.c" instead of "a
> long double NaN", right? (There are many different NaNs.)

Yes. Unless I say nan(0x...) I mean a NaN with the mantissa set to all ones
(like NAN).

> Also you probably mean "the bit pattern of ..." prepended to left and
> right sides of ==, because I thought "fcmp st, st1" (I made up that
> instruction as I don't know the syntax for them; hopefully you get my
> meaning) where st and st1 both contain a NaN with the same bit pattern
> sets the flag(s) to not equal ( x != x, if x == a NaN). I could be
> wrong here.

Yes, that's what I meant. I thought that some stray bits, other than the ones
we can set, are the reason for the inequality.

> I'm also a little confused where t-nan2.c enters the discussion.

That was just to show that converting NAN up to a double or long double and
then back down to a float gave you back NAN. Unfortunately it doesn't give you
exactly a NAN - the comparison above fails.

I don't really know enough about the behaviour of hardware FP to comment on
its handling of converting long double <-> double <-> float.

[snip]
> Thanks for the coding and testing.

You're welcome. Mostly I'm just trying to understand what's going on.

> I propose all strto*() do use an unsigned long long to store the
> mantissa (X) given in "nan(X)". If X > the maximum for float or
> double, set the mantissa to all-ones (we clamp the value to the
> maximum possible).
>
> This will make ``strtof(sprintf(s, "%d", NAN), NULL)'' return a
> NaN.

But I still don't think that this identity will hold: strtof(sprintf(F)) == F.
Maybe this identity (and the long double version) will hold strtod(sprintf(D))
== D.

Maybe I'm being too much of perfectionist in wanting the identity to hold?

Consider the test program t-nan4.c:

---Start t-nan4.c---
#include <stdio.h>
#include <stdlib.h>
#include <libc/ieee.h>

int
main (void)
{
  float_t  ft;
  double_t dt;
  float    f;
  double   d;

  ft.mantissa = 1U;
  ft.exponent = 0x7fU;
  ft.sign     = 0U;

  f  = *(float *) &ft;
  d  = f;
  dt = *(double_t *) &d;

  printf("float(0x%x, 0x%x, 0x%x) -> double(0x%x:0x%x, 0x%x, 0x%x)\n",
         ft.mantissa, ft.exponent, ft.sign,
         dt.mantissah, dt.mantissal, dt.exponent, dt.sign);

  return(EXIT_SUCCESS);
}
---End t-nan4.c---

This produces this output for me:

float(0x1, 0x7f, 0x0) -> double(0x0:0x20000000, 0x3ff, 0x0)

The float nan(0x1) has been converted into a double version. This would get
formatted by sprintf as "nan(0x20000000)". But then strtof will convert it to
an all-ones NaN, which is not the same as we started with.

> There's not much we can do about *printf()'s problem forcing it into
> double. But this will let a coder that really wants a certain bit
> pattern in a float use ``strtof("nan(0x1)", NULL)'' to achive this
> (except for the automatical silencing of SNaNs).
> 
> If *printf() will handle NaN in a double separately from long doubles
> this should make ``double value1 =
> extreme_cpu_use_generating_unusual_nans();
> double value2 = strtod(sprintf(s, "%d", value1), NULL)'' make the bit
> pattern of value1 == the bit pattern of value2.

I'm starting to think that printf should not output nan(0x...), if
strtox(sprintf(X)) == X identities don't all hold. But it seems wrong to have
asymmetric support in printf & strto*.

Thanks, bye, Rich =]

-- 
Richard Dawe [ http://www.phekda.freeserve.co.uk/richdawe/ ]

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019