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 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> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit 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 #include #include 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/ ]