Date: Fri, 17 Mar 2000 09:18:08 -0600 From: Eric Rudd <rudd AT cyberoptics DOT com> Subject: Re: Unnormals??? To: djgpp-workers AT delorie DOT com Message-id: <38D24CB0.7BA8FEB7@cyberoptics.com> Organization: CyberOptics MIME-version: 1.0 X-Mailer: Mozilla 4.72 [en] (Win95; U) Content-type: text/plain; charset=us-ascii Content-transfer-encoding: 7bit X-Accept-Language: en References: <Pine DOT LNX DOT 4 DOT 10 DOT 10003171254580 DOT 23502-100000 AT acp3bf> Reply-To: djgpp-workers AT delorie DOT com Hans-Bernhard Broeker wrote: > On Thu, 16 Mar 2000, Eric Rudd wrote: > > > Hans-Bernhard Broeker wrote: > > > The NaN without the sign bit set is a "signaling NaN". > > No, it isn't. The sign bit is not the one that distinguishes between > signaling and quiet NaN. The second bit of the mantissa does that. Oops, you're right; I wasn't reading the Intel docs closely enough. > > -NaN * -NaN => -NaN > > The third one is where the trouble lies: I have no documentation about what > happens to the sign bits of operands in such operation with NaN, it seems. There is the cryptic statement in the Pentium Pro manual, vol. 2, 7.6: "The sign bit of a NaN is not interpreted." What do you suppose they mean by that? > Anyone? Or will we have to do an experiment? I had already done the experiment to produce the table in my earlier message; I only incorrectly labeled +NaN as SNaN. Here is a hacky little program to try these things: #include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { double x[2], z; long long nd; int i; char qs[100], xys[2][100]; while (1) { printf("\n Supply x, y. "); fgets(qs, 100, stdin); if (sscanf(qs, "%[^ ,\t]%*[ ,\t]%[^ ,\t]", xys[0], xys[1]) < 2) return 0; for (i=0; i<2; i++) { if (strchr(xys[i], '.')) { /* Floating-point input */ x[i] = atof(xys[i]); } else { if (xys[i][1] == '$') { /* Motorola hex format */ xys[i][1] = xys[i][0]; sscanf(&xys[i][1], "%llx", &nd); } else if (xys[i][0] == '$') { sscanf(&xys[i][1], "%llx", &nd); } else { /* C hex format, decimal, or octal */ sscanf(xys[i], "%lli", &nd); } x[i] = *((double *) &nd); } } z = x[0]*x[1]; printf(" $%016llX = $%016llX * $%016llX\n", *((unsigned long long *) &z), *((unsigned long long *) &x[0]), *((unsigned long long *) &x[1]) ); printf(" %22.15E = %22.15E * %22.15E\n", z, x[0], x[1]); } } On my Pentium II, I found that -NaN = -NaN * -NaN; all other sign combinations produced +NaN. > The C99 explicitly mentions signs of NaNs in its output specification for > *printf(), and also in strtod()/*scanf() input. I don't think we can just > say the a NaN with the sign bit set is *not* negative. Yes, by footnote 220 7.19.6.1 Library 7.19.6.1 220When applied to infinite and NaN values, the -, +, and space flag characters have their usual meaning; the # and 0 flag characters have no effect. it seems that "real indefinite" must be printed out as negative. But I think my argument still stands that "-" cannot have its "usual meaning," since NaN has no numerical value. Thus my issue is with the C99 standard. -Eric Rudd rudd AT cyberoptics DOT com