delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2000/03/17/10:19:43

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

- Raw text -


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