delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2008/03/16/08:29:08

X-Authentication-Warning: delorie.com: mail set sender to djgpp-workers-bounces using -f
X-Recipient: djgpp-workers AT delorie DOT com
X-Authenticated: #27081556
X-Provags-ID: V01U2FsdGVkX1/HLYEWIbbHtZVjDBMUjSKvEOdCaRWs1WBdK+RstI
e0BY/XtORH4QGf
From: Juan Manuel Guerrero <juan DOT guerrero AT gmx DOT de>
To: djgpp-workers AT delorie DOT com
Subject: Retrun string for pseudo-nan and others.
Date: Sun, 16 Mar 2008 14:28:48 +0100
User-Agent: KMail/1.9.5
MIME-Version: 1.0
Message-Id: <200803161428.49368.juan.guerrero@gmx.de>
X-Y-GMX-Trusted: 0
Reply-To: djgpp-workers AT delorie DOT com

Modern configure scripts check what does printf return for Quiet NaN,
Signalling NaN, Pseudo-NaN, Pseudo-Infinity, Pseudo-Zero, Pseudo-Denormal
and denormalized numbers (unnormal).  DJGPP's printf returns "Unnormal"
for all except for Quiet NaN and Signalling NaN making the test case fail.
According to:
  <http://sourceware.org/ml/glibc-bugs/2007-06/msg00002.html>
all of them shall return nan/NAN.  The patch below will fix the issue and
make printf a little bit more glibc compatible.  Neitherless this will
introduce backward compatibility problems because "Unnormal" is no longer
issued.

Regards,
Juan M. Guerrero


2008-03-16  Juan Manuell Guerrero  <juan DOT guerrero AT gmx DOT de>

	* src/libc/ansi/stdio/doprnt.c: Macro UPPERCASE added to select the
	appropiate inf and nan representation.
	(_doprnt): For E, F, G, X set flags to UPPERCASE.
	(exponentl): Variable flags added to argument list.
	(isspeciall): Variable flags added to argument list.  Use it to select
	the appropiate inf and nan representation.  Return nan/NAN for Quiet NaN,
	Signalling NaN, Pseudo-NaN, Pseudo-Infinity, Pseudo-Zero, Pseudo-Denormal
	and denormalized numbers (unnormal) instead of "Unnormal".



diff -aprNU3 djgpp.orig/src/libc/ansi/stdio/doprnt.c djgpp/src/libc/ansi/stdio/doprnt.c
--- djgpp.orig/src/libc/ansi/stdio/doprnt.c	2008-03-14 22:26:54 +0000
+++ djgpp/src/libc/ansi/stdio/doprnt.c	2008-03-16 14:12:00 +0000
@@ -58,26 +58,26 @@ static __inline__ char tochar(int n)
 
 /* have to deal with the negative buffer count kludge */
 
-#define	LONGINT		0x01		/* long integer */
-#define	LONGDBL		0x02		/* long double */
-#define	SHORTINT	0x04		/* short integer */
-#define	CHARINT		0x08		/* char */
-#define	ALT		0x10		/* alternate form */
-#define	LADJUST		0x20		/* left adjustment */
-#define	ZEROPAD		0x40		/* zero (as opposed to blank) pad */
-#define	HEXPREFIX	0x80		/* add 0x or 0X prefix */
+#define	LONGINT		0x001		/* long integer */
+#define	LONGDBL		0x002		/* long double */
+#define	SHORTINT	0x004		/* short integer */
+#define	CHARINT		0x008		/* char */
+#define	ALT		0x010		/* alternate form */
+#define	LADJUST		0x020		/* left adjustment */
+#define	ZEROPAD		0x040		/* zero (as opposed to blank) pad */
+#define	HEXPREFIX	0x080		/* add 0x or 0X prefix */
+#define	UPPERCASE	0x100		/* INF/NAN for [AEFG] */
 
 static int cvtl(long double number, int prec, int flags, char *signp,
 	        unsigned char fmtch, char *startp, char *endp);
 static char *doprnt_roundl(long double fract, int *expv, char *start,
 			   char *end, char ch, char *signp);
-static char *exponentl(char *p, int expv, unsigned char fmtch);
+static char *exponentl(char *p, int expv, unsigned char fmtch, int flags);
 #ifdef __GO32__
-static int isspeciall(long double d, char *bufp);
+static int isspeciall(long double d, char *bufp, int flags);
 #endif
 
 static char NULL_REP[] = "(null)";
-static char UNNORMAL_REP[] = "Unnormal";
 
 int
 _doprnt(const char *fmt0, va_list argp, FILE *fp)
@@ -237,11 +237,13 @@ _doprnt(const char *fmt0, va_list argp, 
       }
       base = 10;
       goto number;
-    case 'e':
     case 'E':
+    case 'F':
+    case 'G':
+      flags |= UPPERCASE;
+    case 'e':
     case 'f':
     case 'g':
-    case 'G':
       if (flags & LONGDBL)
 	_ldouble = va_arg(argp, long double);
       else
@@ -377,6 +379,7 @@ _doprnt(const char *fmt0, va_list argp, 
       goto nosign;
     case 'X':
       digs = "0123456789ABCDEF";
+      flags |= UPPERCASE;
       /* FALLTHROUGH */
     case 'x':
       ARG(unsigned);
@@ -533,7 +536,7 @@ cvtl(long double number, int prec, int f
   int doingzero=0;     /* We're displaying 0.0 */
   long double integer, tmp;
 
-  if ((expcnt = isspeciall(number, startp)))
+  if ((expcnt = isspeciall(number, startp, flags)))
     return(expcnt);
 
   dotrim = expcnt = gformat = 0;
@@ -723,7 +726,7 @@ cvtl(long double number, int prec, int f
 	--t;
       ++t;
     }
-    t = exponentl(t, expcnt, fmtch);
+    t = exponentl(t, expcnt, fmtch, flags);
     break;
   case 'g':
   case 'G':
@@ -867,7 +870,7 @@ doprnt_roundl(long double fract, int *ex
 }
 
 static char *
-exponentl(char *p, int expv, unsigned char fmtch)
+exponentl(char *p, int expv, unsigned char fmtch, int flags)
 {
   char *t;
   char expbuf[MAXEXPLD];
@@ -898,44 +901,73 @@ exponentl(char *p, int expv, unsigned ch
 }
 
 static int
-isspeciall(long double d, char *bufp)
+isspeciall(long double d, char *bufp, int flags)
 {
-  typedef struct {
-    unsigned manl:32;
-    unsigned manh:32;
-    unsigned exp:15;
-    unsigned sign:1;
-  } IEEExp;
-
-  typedef union {
-    IEEExp ip;
-    long double ldouble;  /* double and long double precision arguments */
-  } ip_union;
-
-  ip_union ip;
-
-  ip.ldouble = 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.  */
-  if ((ip.ip.manh & 0x80000000U) == 0 && ip.ip.exp != 0)
-  {
-    if (ip.ip.sign)
-      *bufp++ = '-';
-    strcpy(bufp, UNNORMAL_REP);
-    return strlen(bufp) + ip.ip.sign;
-  }
-  if (ip.ip.exp != 0x7fff)
-    return(0);
-  if ((ip.ip.manh & 0x7fffffff) || ip.ip.manl)
-  {
-    strcpy(bufp, "NaN");
-    nan_p = ip.ip.sign ? -1 : 1; /* kludge: we don't need the sign, it's
-				    not nice, but it should work */
+  /*
+   *  For intel's 80 bit floating point number identify
+   *  the following special values:
+   *
+   *  Supported Floating-Point Encodings (generated by processor as an operation result)
+   *                      exp             mantissa high                     mantissa low
+   *  Quiet NaN:        0x7FFF, 11NNNNNNNNNNNNNNNNNNNNNNNNNNNNNN, NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+   *  Signalling NaN:   0x7FFF, 10NNNNNNNNNNNNNNNNNNNNNNNNNNNNNN, NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+   *  Infinity:         0x7FFF, 10000000000000000000000000000000, 00000000000000000000000000000000
+   *  Pseudo-Denormal:  0x0000, 1NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN, NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN1
+   *
+   *  Unsupported Floating-Point Encodings (not generated by processor as an operation result)
+   *                      exp             mantissa high                     mantissa low
+   *  Pseudo-NaN:       0x7FFF, 0NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN, NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN1
+   *  Pseudo-Infinity:  0x7FFF, 00000000000000000000000000000000, 00000000000000000000000000000000
+   *  Pseudo-Zero:      0xNNN1, 00000000000000000000000000000000, 00000000000000000000000000000000
+   *  Unnormal:         0xNNN1, 0NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN, NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+   *
+   *  Patterns of the values according to:
+   *    Intel IA-64 Architecture Software Developer's Manual, Volume 1:
+   *    Application Architecture.
+   *    5.1.3 "Representation of Values in Floating-Point Registers"
+   *    Table 5-2 "Floating-Point Register Encodings"
+   *    Figure 5-11 "Floating-Point Exception Fault Prioritization"
+   *
+   *  To be compatible with printf of glibc Quiet NaN, signalling NaN, Pseudo-NaN,
+   *  Pseudo-Infinity, Pseudo-Zero, Pseudo-Denormal and denormalized numbers (unnormal)
+   *  shall all return nan/NAN.
+   */
+
+
+  static const char inf_representation[2][4] = {"inf", "INF"};
+  static const char nan_representation[2][4] = {"nan", "NAN"};
+  int style = (flags & UPPERCASE) ? 1 : 0;
+  _longdouble_union_t ldvalue;
+
+  ldvalue.ld = d;
+  if (ldvalue.ldt.exponent == 0x7FFF)
+  {
+    if (ldvalue.ldt.mantissah == 0x80000000 && ldvalue.ldt.mantissal == 0x00000000)
+      strcpy(bufp, inf_representation[style]);
+    else
+    {
+      /*  Quiet NaN, signalling NaN, Pseudo-NaN and Pseudo-Infinity.  */
+      strcpy(bufp, nan_representation[style]);
+      nan_p = ldvalue.ldt.sign ? -1 : 1; /* kludge: we don't need the sign, it's
+                                            not nice, but it should work */
+    }
+    return 3;
+  }
+  else if (ldvalue.ldt.exponent != 0x0000 && !(ldvalue.ldt.mantissah & 0x80000000))
+  {
+    /*  Pseudo-Zero and denormalized numbers (unnormal).  */
+    strcpy(bufp, nan_representation[style]);
+    nan_p = ldvalue.ldt.sign ? -1 : 1; /* kludge: we don't need the sign, it's
+                                          not nice, but it should work */
+    return 3;
+  }
+  else if (ldvalue.ldt.exponent == 0x0000 && ldvalue.ldt.mantissah & 0x80000000)
+  {
+    /*  Pseudo-Denormal.  */
+    strcpy(bufp, nan_representation[style]);
+    nan_p = ldvalue.ldt.sign ? -1 : 1; /* kludge: we don't need the sign, it's
+                                          not nice, but it should work */
+    return 3;
   }
-  else
-    (void)strcpy(bufp, "Inf");
-  return(3);
+  return 0;
 }

- Raw text -


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