Date: Sun, 24 Jan 1999 10:22:07 +0200 (IST) From: Eli Zaretskii X-Sender: eliz AT is To: DJ Delorie cc: djgpp-workers AT delorie DOT com, Robert Hoehne Subject: Re: Bug when printing long doubles In-Reply-To: Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Reply-To: djgpp-workers AT delorie DOT com Here's a patch for doprnt.c that takes care of printing unnormals. I don't think we've agreed on what exactly to print; the patch below prints "Unnormal" (with a sign, if necessary), but you can change that by modifying a single string that gets assigned to UNNORMAL_REP[]. *** src/libc/ansi/stdio/doprnt.c~1 Fri Jan 15 14:31:58 1999 --- src/libc/ansi/stdio/doprnt.c Sat Jan 23 20:39:22 1999 *************** static int isspeciall(long double d, cha *** 71,76 **** --- 71,77 ---- #endif static char NULL_REP[] = "(null)"; + static char UNNORMAL_REP[] = "Unnormal"; int _doprnt(const char *fmt0, va_list argp, FILE *fp) *************** cvtl(long double number, int prec, int f *** 549,556 **** /* * get integer portion of number; put into the end of the buffer; the * .01 is added for modf(356.0 / 10, &integer) returning .59999999... */ ! for (; integer; ++expcnt) { tmp = modfl(integer * 0.1L , &integer); *p-- = tochar((int)((tmp + .01L) * 10)); --- 550,560 ---- /* * get integer portion of number; put into the end of the buffer; the * .01 is added for modf(356.0 / 10, &integer) returning .59999999... + * The test p >= startp is due to paranoia: buffer length is guaranteed + * to be large enough, but if tmp is somehow a NaN, this loop could + * eventually blow away the stack. */ ! for (; integer && p >= startp; ++expcnt) { tmp = modfl(integer * 0.1L , &integer); *p-- = tochar((int)((tmp + .01L) * 10)); *************** isspeciall(long double d, char *bufp) *** 863,868 **** --- 867,882 ---- } *ip = (struct IEEExp *)&d; nan = 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->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)