Discussion:
strtod ("nan") returns negative NaN
Masamichi Hosoda
2018-08-14 15:05:39 UTC
Permalink
Hi

I've found that strtod ("nan") returns negative NaN on Cygwin 64 bit.
https://cygwin.com/ml/cygwin/2018-08/msg00168.html

On Linux with glibc, both strtod ("nan")
and strtod ("-nan") return positive NaN.

So I've created the patch that behaves like glibc.
Both strtod ("nan") and strtod ("-nan") return positive NaN.

Sample code:
```
#include <stdio.h>
#include <stdlib.h>

int main (void)
{
printf ("strtof (\"nan\", NULL) = %f\n", strtof ("nan", NULL));
printf ("strtof (\"-nan\", NULL) = %f\n", strtof ("-nan", NULL));
printf ("strtod (\"nan\", NULL) = %f\n", strtod ("nan", NULL));
printf ("strtod (\"-nan\", NULL) = %f\n", strtod ("-nan", NULL));
printf ("strtold (\"nan\", NULL) = %Lf\n", strtold ("nan", NULL));
printf ("strtold (\"-nan\", NULL) = %Lf\n", strtold ("-nan", NULL));
}
```

The result of Cygwin (newlib) without my patch:
```
strtof ("nan", NULL) = nan
strtof ("-nan", NULL) = nan
strtod ("nan", NULL) = -nan
strtod ("-nan", NULL) = nan
strtold ("nan", NULL) = -nan
strtold ("-nan", NULL) = -nan
```

The result of Linux (glibc, Ubuntu 16.04):
```
strtof ("nan", NULL) = nan
strtof ("-nan", NULL) = nan
strtod ("nan", NULL) = nan
strtod ("-nan", NULL) = nan
strtold ("nan", NULL) = nan
strtold ("-nan", NULL) = nan
```

The result of FreeBSD 10.1 (BSD libc):
```
strtof ("nan", NULL) = nan
strtof ("-nan", NULL) = nan
strtod ("nan", NULL) = nan
strtod ("-nan", NULL) = nan
strtold ("nan", NULL) = nan
strtold ("-nan", NULL) = nan
```

The result of Cygwin (newlib) with my patch:
```
strtof ("nan", NULL) = nan
strtof ("-nan", NULL) = nan
strtod ("nan", NULL) = nan
strtod ("-nan", NULL) = nan
strtold ("nan", NULL) = nan
strtold ("-nan", NULL) = nan
```

Thanks.
Corinna Vinschen
2018-08-14 16:01:13 UTC
Permalink
Post by Masamichi Hosoda
Hi
I've found that strtod ("nan") returns negative NaN on Cygwin 64 bit.
https://cygwin.com/ml/cygwin/2018-08/msg00168.html
On Linux with glibc, both strtod ("nan")
and strtod ("-nan") return positive NaN.
So I've created the patch that behaves like glibc.
Both strtod ("nan") and strtod ("-nan") return positive NaN.
Looks good on Cygwin. Any comments from non-Cygwin devs?
If nobody has a problem I push the patch in the next days.


Thanks,
Corinna
--
Corinna Vinschen
Cygwin Maintainer
Red Hat
Craig Howland
2018-08-14 17:43:49 UTC
Permalink
Post by Masamichi Hosoda
Hi
I've found that strtod ("nan") returns negative NaN on Cygwin 64 bit.
https://cygwin.com/ml/cygwin/2018-08/msg00168.html
On Linux with glibc, both strtod ("nan")
and strtod ("-nan") return positive NaN.
So I've created the patch that behaves like glibc.
Both strtod ("nan") and strtod ("-nan") return positive NaN.
```
#include <stdio.h>
#include <stdlib.h>
int main (void)
{
printf ("strtof (\"nan\", NULL) = %f\n", strtof ("nan", NULL));
printf ("strtof (\"-nan\", NULL) = %f\n", strtof ("-nan", NULL));
printf ("strtod (\"nan\", NULL) = %f\n", strtod ("nan", NULL));
printf ("strtod (\"-nan\", NULL) = %f\n", strtod ("-nan", NULL));
printf ("strtold (\"nan\", NULL) = %Lf\n", strtold ("nan", NULL));
printf ("strtold (\"-nan\", NULL) = %Lf\n", strtold ("-nan", NULL));
}
```
```
strtof ("nan", NULL) = nan
strtof ("-nan", NULL) = nan
strtod ("nan", NULL) = -nan
strtod ("-nan", NULL) = nan
strtold ("nan", NULL) = -nan
strtold ("-nan", NULL) = -nan
```
...
Thanks.
The Newlib math functions generally do support signed NANs.  The C standard says
(in section 5.2.4.2.2 Characteristics of floating types <float.h>) NANs can be
treated as having a sign or not.  But since the math library does support signed
NANs, the proper behavior for the strtox() functions would be to listen to the
sign rather than ignoring it.  So while the current Cygwin 64 behavior is
clearly incorrect, the given patch needs to be adjusted to listen to sign.

(It can be seen that the math functions support signed NANs by looking, for
example, at s_copysign.c.  it blindly copies the sign without checking the type
of the arguments.  The standard requires requests to set sign to be ignored when
NANs are not treated as having signs.)

I cannot generate git diffs at this time (corporate firewall), but here is how I
think strtof() would need to be fixed after strtod() is:

$ diff -pu strtod.c.20180420 strtod.c
--- strtod.c.20180420    2018-04-20 10:32:36.974479745 -0400
+++ strtod.c    2018-08-14 13:27:57.958177691 -0400
@@ -1285,7 +1285,7 @@ strtof_l (const char *__restrict s00, ch
 {
   double val = _strtod_l (_REENT, s00, se, loc);
   if (isnan (val))
-    return nanf (NULL);
+    return copysign( nanf (NULL), signbit(val) ? -1.0f : 1.0f);
   float retval = (float) val;
 #ifndef NO_ERRNO
   if (isinf (retval) && !isinf (val))
@@ -1300,7 +1300,7 @@ strtof (const char *__restrict s00,
 {
   double val = _strtod_l (_REENT, s00, se, __get_current_locale ());
   if (isnan (val))
-    return nanf (NULL);
+    return copysign( nanf (NULL), signbit(val) ? -1.0f : 1.0f);
   float retval = (float) val;
 #ifndef NO_ERRNO
   if (isinf (retval) && !isinf (val))


By the way, here are the results of the test prints from an embedded 64-bit ARM:

strtof ("nan", NULL) = 0.000000
strtof ("-nan", NULL) = 0.000000
strtod ("nan", NULL) = nan
strtod ("-nan", NULL) = nan
strtold ("nan", NULL) = inf
strtold ("-nan", NULL) = 2315841784746322880031071374419981810209660594968745666
57923565917084799991808.000000

Craig
Masamichi Hosoda
2018-08-15 00:32:04 UTC
Permalink
[...]
Post by Craig Howland
strtof ("nan", NULL) = 0.000000
strtof ("-nan", NULL) = 0.000000
strtod ("nan", NULL) = nan
strtod ("-nan", NULL) = nan
strtold ("nan", NULL) = inf
strtold ("-nan", NULL) =
2315841784746322880031071374419981810209660594968745666
57923565917084799991808.000000
If I understand correctly, qNaN definition for 64-bit ARM is wrong
like x86_64 and i386 definition was wrong.

The following code can generate the correct definition.

```
/* gcc arch-nans.c */

#include <inttypes.h>
#include <math.h>
#include <stdio.h>
#include <stdint.h>

int main (void)
{
union
{
float f;
uint32_t u;
} fb;

union
{
double d;
uint32_t u[2];
} db;

union
{
long double ld;
uint32_t u[4];
uint16_t us[5];
} ldb;

fb.u = 0;
fb.f = nanf ("");
printf ("#define f_QNAN 0x%"PRIx32"\n", fb.u);

db.u[0] = 0;
db.u[1] = 0;
db.d = nan ("");
printf ("#define d_QNAN0 0x%"PRIx32"\n"
"#define d_QNAN1 0x%"PRIx32"\n", db.u[0], db.u[1]);

ldb.u[0] = 0;
ldb.u[1] = 0;
ldb.u[2] = 0;
ldb.u[3] = 0;
ldb.ld = nanl ("");
printf ("#define ld_QNAN0 0x%"PRIx32"\n"
"#define ld_QNAN1 0x%"PRIx32"\n"
"#define ld_QNAN2 0x%"PRIx32"\n"
"#define ld_QNAN2 0x%"PRIx32"\n",
ldb.u[0], ldb.u[1], ldb.u[2], ldb.u[3]);
printf ("#define ldus_QNAN0 0x%"PRIx16"\n"
"#define ldus_QNAN1 0x%"PRIx16"\n"
"#define ldus_QNAN2 0x%"PRIx16"\n"
"#define ldus_QNAN3 0x%"PRIx16"\n"
"#define ldus_QNAN4 0x%"PRIx16"\n",
ldb.us[0], ldb.us[1], ldb.us[2], ldb.us[3], ldb.us[4]);
}
```

The result on Cygwin 64 bit (x86_64) and 32 bit (i386):
```
#define f_QNAN 0x7fc00000
#define d_QNAN0 0x0
#define d_QNAN1 0x7ff80000
#define ld_QNAN0 0x0
#define ld_QNAN1 0xc0000000
#define ld_QNAN2 0x7fff
#define ld_QNAN2 0x0
#define ldus_QNAN0 0x0
#define ldus_QNAN1 0x0
#define ldus_QNAN2 0x0
#define ldus_QNAN3 0xc000
#define ldus_QNAN4 0x7fff
```

My patch
0001-Fix-strtod-nan-returns-negative-NaN.patch
v2-0001-Fix-strtod-nan-returns-negative-NaN.patch
uses the generated definition.
Joseph Myers
2018-08-14 19:44:15 UTC
Permalink
Post by Masamichi Hosoda
On Linux with glibc, both strtod ("nan")
and strtod ("-nan") return positive NaN.
So I've created the patch that behaves like glibc.
Both strtod ("nan") and strtod ("-nan") return positive NaN.
I would suggest that you should not consider fixed bugs in glibc (bug
23007 in this case) to be appropriate to emulate in other libraries.
--
Joseph S. Myers
***@codesourcery.com
Masamichi Hosoda
2018-08-15 00:02:02 UTC
Permalink
Post by Joseph Myers
Post by Masamichi Hosoda
On Linux with glibc, both strtod ("nan")
and strtod ("-nan") return positive NaN.
So I've created the patch that behaves like glibc.
Both strtod ("nan") and strtod ("-nan") return positive NaN.
I would suggest that you should not consider fixed bugs in glibc (bug
23007 in this case) to be appropriate to emulate in other libraries.
I've create the patch that behaves to preserve the sign bit.

The result on Cygwin 64 bit (newlib, x86_64) with the patch:
```
strtof ("nan", NULL) = nan
strtof ("-nan", NULL) = -nan
strtod ("nan", NULL) = nan
strtod ("-nan", NULL) = -nan
strtold ("nan", NULL) = nan
strtold ("-nan", NULL) = -nan
```

Thank you for your suggestion.
Craig Howland
2018-08-15 02:24:45 UTC
Permalink
Post by Masamichi Hosoda
Post by Joseph Myers
Post by Masamichi Hosoda
On Linux with glibc, both strtod ("nan")
and strtod ("-nan") return positive NaN.
So I've created the patch that behaves like glibc.
Both strtod ("nan") and strtod ("-nan") return positive NaN.
I would suggest that you should not consider fixed bugs in glibc (bug
23007 in this case) to be appropriate to emulate in other libraries.
I've create the patch that behaves to preserve the sign bit.
```
strtof ("nan", NULL) = nan
strtof ("-nan", NULL) = -nan
strtod ("nan", NULL) = nan
strtod ("-nan", NULL) = -nan
strtold ("nan", NULL) = nan
strtold ("-nan", NULL) = -nan
```
Thank you for your suggestion.
     The f_QNAN value should be 0x7fc00000 regardless of byte ordering.  In
addition, the d_QNAN* values should be 0x0 and 0x7FF80000, with only the index
changing based on byte ordering.  So instead of them being inside of a
x86/x86_64 define, they should just have their values corrected in the
LITTLE_ENDIAN clause.
     x86 does use a different coding for their 80-bit long double, so the
ldus_QNAN* defines could belong within an x86 define.  On the other hand, the
ldus_QNAN* defines only apply for Intel 80-bit, so in that respect don't need to
be within a guard.
     The ld_QNAN defines are not actually used anywhere.  If they were,
however, Intel 80-bit would require different values than 128-bit.  However, the
long double support in Newlib really only works when long double is the same
size as double.  Some functions can work with Intel 80-bit, but almost none of
them work with 128-bit.
     Given the prior considerations, I suggest that only the values get fixed
so that Cygwin works, but the #if x86 is not added.  For this to work on other
platforms (128-bit long double), more work will be needed.  Again, sorry that I
can't provide a git diff patch, but here's a suggested one with diff -pu.  It
contains the value corrections from Masamichi, but skips the #if x86 and adds a
comments about some of the deficiencies.
     The changes to strtod.c look OK.
                Craig
Masamichi Hosoda
2018-08-15 06:29:51 UTC
Permalink
Post by Craig Howland
Post by Masamichi Hosoda
Post by Joseph Myers
Post by Masamichi Hosoda
On Linux with glibc, both strtod ("nan")
and strtod ("-nan") return positive NaN.
So I've created the patch that behaves like glibc.
Both strtod ("nan") and strtod ("-nan") return positive NaN.
I would suggest that you should not consider fixed bugs in glibc (bug
23007 in this case) to be appropriate to emulate in other libraries.
I've create the patch that behaves to preserve the sign bit.
```
strtof ("nan", NULL) = nan
strtof ("-nan", NULL) = -nan
strtod ("nan", NULL) = nan
strtod ("-nan", NULL) = -nan
strtold ("nan", NULL) = nan
strtold ("-nan", NULL) = -nan
```
Thank you for your suggestion.
     The f_QNAN value should be 0x7fc00000 regardless of byte
ordering.  In addition, the d_QNAN* values should be 0x0 and
0x7FF80000, with only the index changing based on byte ordering.  So
instead of them being inside of a x86/x86_64 define, they should just
have their values corrected in the LITTLE_ENDIAN clause.
     x86 does use a different coding for their 80-bit long double, so
the ldus_QNAN* defines could belong within an x86 define.  On the
other hand, the ldus_QNAN* defines only apply for Intel 80-bit, so in
that respect don't need to be within a guard.
     The ld_QNAN defines are not actually used anywhere.  If they
were, however, Intel 80-bit would require different values than
128-bit.  However, the long double support in Newlib really only works
when long double is the same size as double.  Some functions can work
with Intel 80-bit, but almost none of them work with 128-bit.
     Given the prior considerations, I suggest that only the values
get fixed so that Cygwin works, but the #if x86 is not added.  For
this to work on other platforms (128-bit long double), more work will
be needed.  Again, sorry that I can't provide a git diff patch, but
here's a suggested one with diff -pu.  It contains the value
corrections from Masamichi, but skips the #if x86 and adds a comments
about some of the deficiencies.
     The changes to strtod.c look OK.
Thank you for your suggestion.
Here's patch v3.
Corinna Vinschen
2018-08-15 09:07:31 UTC
Permalink
Post by Masamichi Hosoda
Post by Masamichi Hosoda
Post by Joseph Myers
Post by Masamichi Hosoda
On Linux with glibc, both strtod ("nan")
and strtod ("-nan") return positive NaN.
So I've created the patch that behaves like glibc.
Both strtod ("nan") and strtod ("-nan") return positive NaN.
I would suggest that you should not consider fixed bugs in glibc (bug
23007 in this case) to be appropriate to emulate in other libraries.
I've create the patch that behaves to preserve the sign bit.
```
strtof ("nan", NULL) = nan
strtof ("-nan", NULL) = -nan
strtod ("nan", NULL) = nan
strtod ("-nan", NULL) = -nan
strtold ("nan", NULL) = nan
strtold ("-nan", NULL) = -nan
```
Thank you for your suggestion.
     The f_QNAN value should be 0x7fc00000 regardless of byte
ordering.  In addition, the d_QNAN* values should be 0x0 and
0x7FF80000, with only the index changing based on byte ordering.  So
instead of them being inside of a x86/x86_64 define, they should just
have their values corrected in the LITTLE_ENDIAN clause.
     x86 does use a different coding for their 80-bit long double, so
the ldus_QNAN* defines could belong within an x86 define.  On the
other hand, the ldus_QNAN* defines only apply for Intel 80-bit, so in
that respect don't need to be within a guard.
     The ld_QNAN defines are not actually used anywhere.  If they
were, however, Intel 80-bit would require different values than
128-bit.  However, the long double support in Newlib really only works
when long double is the same size as double.  Some functions can work
with Intel 80-bit, but almost none of them work with 128-bit.
     Given the prior considerations, I suggest that only the values
get fixed so that Cygwin works, but the #if x86 is not added.  For
this to work on other platforms (128-bit long double), more work will
be needed.  Again, sorry that I can't provide a git diff patch, but
here's a suggested one with diff -pu.  It contains the value
corrections from Masamichi, but skips the #if x86 and adds a comments
about some of the deficiencies.
     The changes to strtod.c look OK.
Thank you for your suggestion.
Here's patch v3.
Looks good on Cygwin. Everybody ok with this patch?


Thanks,
Corinna
--
Corinna Vinschen
Cygwin Maintainer
Red Hat
Joseph Myers
2018-08-15 15:38:04 UTC
Permalink
Post by Craig Howland
     The f_QNAN value should be 0x7fc00000 regardless of byte ordering.  In
It would be better to use __builtin_nan ("") (and __builtin_nanf,
__builtin_nanl for other types) rather than using an integer
representation at all (of course that requires changes to other code to
avoid requiring an integer representation there).

* Older MIPS processors have a reversed convention for what is a quiet NaN
and what is a signaling NaN. The present newlib code has __mips and
__mips_nan2008 conditionals to handle that. But that doesn't handle hppa,
which has the same reversed convention, or sh, which also does (GCC
doesn't know about sh doing this at present, resulting in a load of glibc
test failures, but if you used __builtin_nan* then fewer places would need
fixing for sh).

* Different processors have different preferences for what a "default"
quiet NaN (e.g. one produced by an operation without NaN operands) should
look like. Some clear all the lower mantissa bits, some set them. If you
use the built-in functions then you generate NaNs following GCC's
knowledge of such processor conventions.
--
Joseph S. Myers
***@codesourcery.com
Joseph Myers
2018-08-15 15:40:38 UTC
Permalink
Post by Joseph Myers
Post by Craig Howland
     The f_QNAN value should be 0x7fc00000 regardless of byte ordering.  In
It would be better to use __builtin_nan ("") (and __builtin_nanf,
__builtin_nanl for other types) rather than using an integer
representation at all (of course that requires changes to other code to
avoid requiring an integer representation there).
(This is not an objection to any of the present patch proposals, just an
observation that a different approach would avoid a series of problems
that result from trying to hardcode information about such choices of
bit-patterns for NaNs.)
--
Joseph S. Myers
***@codesourcery.com
Craig Howland
2018-08-15 15:51:35 UTC
Permalink
Post by Joseph Myers
Post by Joseph Myers
Post by Craig Howland
     The f_QNAN value should be 0x7fc00000 regardless of byte ordering.  In
It would be better to use __builtin_nan ("") (and __builtin_nanf,
__builtin_nanl for other types) rather than using an integer
representation at all (of course that requires changes to other code to
avoid requiring an integer representation there).
I totally agree.  To add it to the record, in conjunction with this, the strtod
implementation really should be upgraded to David Gay's more recent version,
which is 128-bit friendly.  (I almost had this done some time ago, but didn't
quite finish.)
Post by Joseph Myers
(This is not an objection to any of the present patch proposals, just an
observation that a different approach would avoid a series of problems
that result from trying to hardcode information about such choices of
bit-patterns for NaNs.)
Also agreed.  If I had had time yesterday I might have tried it as I had briefly
thought of it, but didn't think to get the idea out to the list, so I'm glad you
did.
Corinna Vinschen
2018-08-15 16:05:44 UTC
Permalink
Post by Joseph Myers
Post by Joseph Myers
     The f_QNAN value should be 0x7fc00000 regardless of byte ordering.  In
It would be better to use __builtin_nan ("") (and __builtin_nanf,
__builtin_nanl for other types) rather than using an integer
representation at all (of course that requires changes to other code to
avoid requiring an integer representation there).
I totally agree.  To add it to the record, in conjunction with this, the
strtod implementation really should be upgraded to David Gay's more recent
version, which is 128-bit friendly.  (I almost had this done some time ago,
but didn't quite finish.)
Post by Joseph Myers
(This is not an objection to any of the present patch proposals, just an
observation that a different approach would avoid a series of problems
that result from trying to hardcode information about such choices of
bit-patterns for NaNs.)
Also agreed.  If I had had time yesterday I might have tried it as I had
briefly thought of it, but didn't think to get the idea out to the list, so
I'm glad you did.
Sounds like a nice followup patch...?


Corinna
--
Corinna Vinschen
Cygwin Maintainer
Red Hat
Masamichi Hosoda
2018-08-16 01:22:20 UTC
Permalink
Post by Corinna Vinschen
Post by Craig Howland
Post by Joseph Myers
Post by Joseph Myers
Post by Craig Howland
     The f_QNAN value should be 0x7fc00000 regardless of byte ordering.  In
It would be better to use __builtin_nan ("") (and __builtin_nanf,
__builtin_nanl for other types) rather than using an integer
representation at all (of course that requires changes to other code to
avoid requiring an integer representation there).
I totally agree.  To add it to the record, in conjunction with this, the
strtod implementation really should be upgraded to David Gay's more recent
version, which is 128-bit friendly.  (I almost had this done some time ago,
but didn't quite finish.)
Post by Joseph Myers
(This is not an objection to any of the present patch proposals, just an
observation that a different approach would avoid a series of problems
that result from trying to hardcode information about such choices of
bit-patterns for NaNs.)
Also agreed.  If I had had time yesterday I might have tried it as I had
briefly thought of it, but didn't think to get the idea out to the list, so
I'm glad you did.
Sounds like a nice followup patch...?
Here's patch v4.
It uses {nan|nanl} ("") instead of the integer representations of NaN.
It also removes the unused definitions of them.
Corinna Vinschen
2018-08-16 09:56:21 UTC
Permalink
Post by Masamichi Hosoda
Post by Corinna Vinschen
Post by Joseph Myers
Post by Joseph Myers
     The f_QNAN value should be 0x7fc00000 regardless of byte ordering.  In
It would be better to use __builtin_nan ("") (and __builtin_nanf,
__builtin_nanl for other types) rather than using an integer
representation at all (of course that requires changes to other code to
avoid requiring an integer representation there).
I totally agree.  To add it to the record, in conjunction with this, the
strtod implementation really should be upgraded to David Gay's more recent
version, which is 128-bit friendly.  (I almost had this done some time ago,
but didn't quite finish.)
Post by Joseph Myers
(This is not an objection to any of the present patch proposals, just an
observation that a different approach would avoid a series of problems
that result from trying to hardcode information about such choices of
bit-patterns for NaNs.)
Also agreed.  If I had had time yesterday I might have tried it as I had
briefly thought of it, but didn't think to get the idea out to the list, so
I'm glad you did.
Sounds like a nice followup patch...?
Here's patch v4.
It uses {nan|nanl} ("") instead of the integer representations of NaN.
It also removes the unused definitions of them.
Still looks good on Cygwin. I'll push this tomorrow, unless somebody
objects.


Thanks,
Corinna
--
Corinna Vinschen
Cygwin Maintainer
Red Hat
Corinna Vinschen
2018-08-17 09:38:31 UTC
Permalink
Post by Corinna Vinschen
Post by Masamichi Hosoda
Post by Corinna Vinschen
Post by Joseph Myers
Post by Joseph Myers
     The f_QNAN value should be 0x7fc00000 regardless of byte ordering.  In
It would be better to use __builtin_nan ("") (and __builtin_nanf,
__builtin_nanl for other types) rather than using an integer
representation at all (of course that requires changes to other code to
avoid requiring an integer representation there).
I totally agree.  To add it to the record, in conjunction with this, the
strtod implementation really should be upgraded to David Gay's more recent
version, which is 128-bit friendly.  (I almost had this done some time ago,
but didn't quite finish.)
Post by Joseph Myers
(This is not an objection to any of the present patch proposals, just an
observation that a different approach would avoid a series of problems
that result from trying to hardcode information about such choices of
bit-patterns for NaNs.)
Also agreed.  If I had had time yesterday I might have tried it as I had
briefly thought of it, but didn't think to get the idea out to the list, so
I'm glad you did.
Sounds like a nice followup patch...?
Here's patch v4.
It uses {nan|nanl} ("") instead of the integer representations of NaN.
It also removes the unused definitions of them.
Still looks good on Cygwin. I'll push this tomorrow, unless somebody
objects.
Pushed.


Thanks a lot,
Corinna
--
Corinna Vinschen
Cygwin Maintainer
Red Hat
Paul Koning
2018-08-15 16:45:01 UTC
Permalink
Post by Joseph Myers
...
* Different processors have different preferences for what a "default"
quiet NaN (e.g. one produced by an operation without NaN operands) should
look like. Some clear all the lower mantissa bits, some set them. If you
use the built-in functions then you generate NaNs following GCC's
knowledge of such processor conventions.
But does that matter? It should be sufficient to generate a legal NaN when one is requested. Given that there are don't care bits in the representation of NaN, it might look different from one generated by the hardware as the output of some operation, but a NaN is a Nan so long as it matches what the spec says -- right?

paul
Joseph Myers
2018-08-15 16:51:37 UTC
Permalink
Post by Paul Koning
Post by Joseph Myers
* Different processors have different preferences for what a "default"
quiet NaN (e.g. one produced by an operation without NaN operands) should
look like. Some clear all the lower mantissa bits, some set them. If you
use the built-in functions then you generate NaNs following GCC's
knowledge of such processor conventions.
But does that matter? It should be sufficient to generate a legal NaN
when one is requested. Given that there are don't care bits in the
representation of NaN, it might look different from one generated by the
hardware as the output of some operation, but a NaN is a Nan so long as
it matches what the spec says -- right?
Well, it mattered enough for ARM to send a patch to the NaN bits set in
ARM glibc fma
<https://sourceware.org/ml/libc-alpha/2014-02/msg00740.html>.
--
Joseph S. Myers
***@codesourcery.com
Brian Inglis
2018-08-15 17:33:32 UTC
Permalink
Post by Paul Koning
Post by Joseph Myers
* Different processors have different preferences for what a "default"
quiet NaN (e.g. one produced by an operation without NaN operands) should
look like. Some clear all the lower mantissa bits, some set them. If you
use the built-in functions then you generate NaNs following GCC's
knowledge of such processor conventions.
But does that matter? It should be sufficient to generate a legal NaN
when one is requested. Given that there are don't care bits in the
representation of NaN, it might look different from one generated by the
hardware as the output of some operation, but a NaN is a Nan so long as
it matches what the spec says -- right?
Signalling NaNs are useful in development and for mathematicians who want to
ensure rigorous correctness: most of us and most apps would prefer NaNs remain
quiet, and interchanged data with NaNs not to create a fuss: non-zero mantissa
bits which do not constitute a signalling NaN on any known platform [NaN with
all zero mantissa bits is Inf]. Some old K-C-S draft-based or low cost
implementations may cheap out on how many or which bit(s) to check.
--
Take care. Thanks, Brian Inglis, Calgary, Alberta, Canada
Loading...