delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2000/03/20/13:54:15

Message-Id: <200003201828.NAA28377@delorie.com>
From: "Dieter Buerssner" <buers AT gmx DOT de>
To: Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
Date: Mon, 20 Mar 2000 19:28:58 +0100
MIME-Version: 1.0
Subject: Re: Unnormals???
CC: djgpp-workers AT delorie DOT com
References: <200003201722 DOT TAA27859 AT is DOT elta DOT co DOT il>
In-reply-to: <Pine.SUN.3.91.1000320192330.27773D-100000@is>
X-mailer: Pegasus Mail for Win32 (v3.12b)
Reply-To: djgpp-workers AT delorie DOT com

On 20 Mar 00,  Eli Zaretskii wrote:

> Did you try this?  latest versions of GCC play dirty tricks with such
> special patterns, when compiled with -O2.  See the comments in the
> source of nan() and nanf() in libm, for some examples.
> 

Compiling this program with gcc -O2  (2.95.2)

#include <stdio.h>

#define ld(x) ((long double)(*(long double *)(x)))
static const unsigned short pos_nanshort[] = {0,0,0,1,0x7fff,0};
static const unsigned short neg_nanshort[] = {0,0,0,1,0xffff,0};

int main (void)
{
  long double pnan, nnan;
  pnan = ld(pos_nanshort);
  nnan = ld(pos_nanshort);
  printf("%+Lf, %+Lf\n", pnan, nnan);
  return 0;
}

yields
+NAN, -NAN

with my version of _doprnt. 

The original version has a bug in isspeciall, so it prints +unnormal, 
--unnormal

static int
isspeciall(long double d, char *bufp)
{
  struct IEEExp {
    unsigned manl:32;
    unsigned manh:32;
    unsigned exp:15;
    unsigned sign:1;
  } *ip = (struct IEEExp *)&d;

  nan_p = 0;  /* don't assume the static is 0 (emacs) */

  /* Unnormals: the MSB of mantissa is non-zero, but the exponent is
     not zero either.  */
 /* Should probably read:
  if ((ip->manh & 0x80000000U) == 0 && ip->exp != 0 
       && ip->exp != 0x7fff) 
*/

  if ((ip->manh & 0x80000000U) == 0 && ip->exp != 0) 
  {
    if (ip->sign)
      *bufp++ = '-';
    strcpy(bufp, UNNORMAL_REP);
    return strlen(bufp) + ip->sign;
  }
  if (ip->exp != 0x7fff)
    return(0);
  if ((ip->manh & 0x7fffffff) || ip->manl)
  {
    strcpy(bufp, "NaN");
    nan_p = ip->sign ? -1 : 1; /* kludge: we don't need the sign, 
it's
                                not nice, but it should work */
  }
  else
    (void)strcpy(bufp, "Inf");
  return(3);
}

> > The last example even has the advantage, that it can trigger a
> > floating point exception (when unmasked, as may be advisable when
> > debugging, especially when the code is not prepared to handle NaNs).

> But I don't understand why did you say exceptions are advisable under
> a debugger: in DJGPP versions of debuggers it is actually the other
> way around.

I don't meant under a debugger, but while debugging. This may have 
been unclear. What I meant is, make a test run of a still buggy 
program. The program calls a math function yielding a domain error.
When the invalid exception is unmasked, you will get a trace back.
With the invalid exception is masked, the error may be more difficult
to notice. 
 


- Raw text -


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