*BSD News Article 13212


Return to BSD News archive

Xref: sserve comp.os.linux:30854 comp.os.386bsd.questions:966
Path: sserve!newshost.anu.edu.au!munnari.oz.au!news.Hawaii.Edu!ames!agate!howland.reston.ans.net!zaphod.mps.ohio-state.edu!uwm.edu!ogicse!news.u.washington.edu!serval!hlu
From: hlu@eecs.wsu.edu (HJ Lu)
Newsgroups: comp.os.linux,comp.os.386bsd.questions
Subject: Re: 386bsd, linux: which runs more out of the box?
Message-ID: <1993Mar23.192313.18299@serval.net.wsu.edu>
Date: 23 Mar 93 19:23:13 GMT
Article-I.D.: serval.1993Mar23.192313.18299
References: <1ome2o$1lu6@hal.gnu.ai.mit.edu> <1993Mar23.085058.13670@serval.net.wsu.edu> <CGD.93Mar23030821@erewhon.CS.Berkeley.EDU> <hastyC4CpLr.247@netcom.com>
Sender: news@serval.net.wsu.edu (USENET News System)
Organization: School of EECS, Washington State University
Lines: 356

In article <hastyC4CpLr.247@netcom.com>, hasty@netcom.com (Amancio Hasty Jr) writes:
|> In article <CGD.93Mar23030821@erewhon.CS.Berkeley.EDU> cgd@erewhon.CS.Berkeley.EDU (Chris G. Demetriou) writes:
|> >In article <1993Mar23.085058.13670@serval.net.wsu.edu> hlu@luke.eecs.wsu.edu (HJ Lu) writes:
|> >>Linux can do POSIX, SYSV and most of BSD.
|> >
|> >however, consider this:
|> >
|> >for a while, the slogan went: "all the world's a vax (running BSD)".
|> >then, it more or less became: "all the world's a sun (running a
|> >					BSD-derivative, if SunOS < 5.0)."
|> >
|> >
|> >so 386bsd will do most of posix, and basically all of BSD stuff.
|> >
|> >and i think that, at this stage of the game, except for GNU software
|> >(which tends to be fine-tuned per platform), you'll end up
|> >being able to compile things just as, if not more easily
|> >under 386bsd...
|> >
|> >
|> >and i'm not sure the problems you had w/386bsd's strtod, but they
|> >might be fixed now...  (but i'm not a libc hacker, so...  8-)
|> >
|> >
|> >chris
|> >--
|> >Chris G. Demetriou                                    cgd@cs.berkeley.edu
|> >
|> >                 MENTALLY CONTAMINATED and proud of it!
|> 
|> Well, here is strtod.c which works tested with interviews, tk/tcl,
|> P3D, rayshared-4.0, etc...
|> 
|> Enjoy,
|> 	Amancio


Sorry to say that. That is a junk to me. You can try this

--------
#include <stdio.h>
#include <stdlib.h>

main ()
{
  double tmp;
  char buf [256];

  while (gets (buf) != NULL) {
     tmp = strod (buf, NULL);
     printf ("%lf\n", tmp);
  }
}
--------

Please try different FP numbers with the hightest precisions to see
if they agree.

BTW, the code below only works on paper. That is the difference
math and CS. Just give you a hint: if you see some FP * or / in strtod (),
that must be junk. Even FP + or - may not be accurate.


H.J.
---------
|> 
|> =======================begin to hack now===========================
|> #include <stdlib.h>
|> #include <stddef.h>
|> #include <ctype.h>
|> /* 
|>  * strtod.c --
|>  *
|>  *	Source code for the "strtod" library procedure.
|>  *
|>  * Copyright 1988-1992 Regents of the University of California
|>  * Permission to use, copy, modify, and distribute this
|>  * software and its documentation for any purpose and without
|>  * fee is hereby granted, provided that the above copyright
|>  * notice appear in all copies.  The University of California
|>  * makes no representations about the suitability of this
|>  * software for any purpose.  It is provided "as is" without
|>  * express or implied warranty.
|>  */
|> 
|> 
|> #ifndef TRUE
|> #define TRUE 1
|> #define FALSE 0
|> #endif
|> #ifndef NULL
|> #define NULL 0
|> #endif
|> 
|> static int maxExponent = 511;	/* Largest possible base 10 exponent.  Any
|> 				 * exponent larger than this will already
|> 				 * produce underflow or overflow, so there's
|> 				 * no need to worry about additional digits.
|> 				 */
|> static double powersOf10[] = {	/* Table giving binary powers of 10.  Entry */
|>     10.,			/* is 10^2^i.  Used to convert decimal */
|>     100.,			/* exponents into floating-point numbers. */
|>     1.0e4,
|>     1.0e8,
|>     1.0e16,
|>     1.0e32,
|>     1.0e64,
|>     1.0e128,
|>     1.0e256
|> };
|> 
|> 
|> 
|> 
|> 
|> 
|> 
|> 
|> 
|> 
|> 
|> 
|> 
|> 
|> 
|> /*
|>  *----------------------------------------------------------------------
|>  *
|>  * strtod --
|>  *
|>  *	This procedure converts a floating-point number from an ASCII
|>  *	decimal representation to internal double-precision format.
|>  *
|>  * Results:
|>  *	The return value is the double-precision floating-point
|>  *	representation of the characters in string.  If endPtr isn't
|>  *	NULL, then *endPtr is filled in with the address of the
|>  *	next character after the last one that was part of the
|>  *	floating-point number.
|>  *
|>  * Side effects:
|>  *	None.
|>  *
|>  *----------------------------------------------------------------------
|>  */
|> 
|> double
|> strtod(string, endPtr)
|>     const char *string;		/* A decimal ASCII floating-point number,
|> 				 * optionally preceded by white space.
|> 				 * Must have form "-I.FE-X", where I is the
|> 				 * integer part of the mantissa, F is the
|> 				 * fractional part of the mantissa, and X
|> 				 * is the exponent.  Either of the signs
|> 				 * may be "+", "-", or omitted.  Either I
|> 				 * or F may be omitted, or both.  The decimal
|> 				 * point isn't necessary unless F is present.
|> 				 * The "E" may actually be an "e".  E and X
|> 				 * may both be omitted (but not just one).
|> 				 */
|>     char **endPtr;		/* If non-NULL, store terminating character's
|> 				 * address here. */
|> {
|>     int sign, expSign = FALSE;
|>     double fraction, dblExp, *d;
|>     double tmp1, tmp2;
|>     char *p, c;
|>     int exp = 0;		/* Exponent read from "EX" field. */
|>     int fracExp = 0;		/* Exponent that derives from the fractional
|> 				 * part.  Under normal circumstatnces, it is
|> 				 * the negative of the number of digits in F.
|> 				 * However, if I is very long, the last digits
|> 				 * of I get dropped (otherwise a long I with a
|> 				 * large negative exponent could cause an
|> 				 * unnecessary overflow on I alone).  In this
|> 				 * case, fracExp is incremented one for each
|> 				 * dropped digit.
|> 				 */
|>     int mantSize;		/* Number of digits in mantissa. */
|>     int decPt;			/* Number of mantissa digits BEFORE decimal
|> 				 * point.
|> 				 */
|>     char *pExp;			/* Temporarily holds location of exponent
|> 				 * in string.
|> 				 */
|> 
|>     /*
|>      * Strip off leading blanks and check for a sign.
|>      */
|> 
|>     p = string;
|>     while (isspace(*p)) {
|> 	p += 1;
|>     }
|>     if (*p == '-') {
|> 	sign = TRUE;
|> 	p += 1;
|>     } else {
|> 	if (*p == '+') {
|> 	    p += 1;
|> 	}
|> 	sign = FALSE;
|>     }
|> 
|>     /*
|>      * Count the number of digits in the mantissa (including the decimal
|>      * point), and also locate the decimal point.
|>      */
|> 
|>     decPt = -1;
|>     for (mantSize = 0; ; mantSize += 1)
|>     {
|> 	c = *p;
|> 	if (!isdigit(c)) {
|> 	    if ((c != '.') || (decPt >= 0)) {
|> 		break;
|> 	    }
|> 	    decPt = mantSize;
|> 	}
|> 	p += 1;
|>     }
|> 
|>     /*
|>      * Now suck up the digits in the mantissa.  Use two integers to
|>      * collect 9 digits each (this is faster than using floating-point).
|>      * If the mantissa has more than 18 digits, ignore the extras, since
|>      * they can't affect the value anyway.
|>      */
|>     
|>     pExp  = p;
|>     p -= mantSize;
|>     if (decPt < 0) {
|> 	decPt = mantSize;
|>     } else {
|> 	mantSize -= 1;			/* One of the digits was the point. */
|>     }
|>     if (mantSize > 18) {
|> 	fracExp = decPt - 18;
|> 	mantSize = 18;
|>     } else {
|> 	fracExp = decPt - mantSize;
|>     }
|>     if (mantSize == 0) {
|> 	fraction = 0.0;
|> 	p = string;
|> 	goto done;
|>     } else {
|> 	int frac1, frac2;
|> 	frac1 = 0;
|> 	for ( ; mantSize > 9; mantSize -= 1)
|> 	{
|> 	    c = *p;
|> 	    p += 1;
|> 	    if (c == '.') {
|> 		c = *p;
|> 		p += 1;
|> 	    }
|> 	    frac1 = 10*frac1 + (c - '0');
|> 	}
|> 	frac2 = 0;
|> 	for (; mantSize > 0; mantSize -= 1)
|> 	{
|> 	    c = *p;
|> 	    p += 1;
|> 	    if (c == '.') {
|> 		c = *p;
|> 		p += 1;
|> 	    }
|> 	    frac2 = 10*frac2 + (c - '0');
|> 	}
|> 	tmp1 = frac1;
|> 	tmp2 = frac2;
|> /*	fraction = (1.0e9 * frac1) + frac2; */
|> 	fraction = (1.0e9 * tmp1) + tmp2;
|> 
|>     }
|> 
|>     /*
|>      * Skim off the exponent.
|>      */
|> 
|>     p = pExp;
|>     if ((*p == 'E') || (*p == 'e')) {
|> 	p += 1;
|> 	if (*p == '-') {
|> 	    expSign = TRUE;
|> 	    p += 1;
|> 	} else {
|> 	    if (*p == '+') {
|> 		p += 1;
|> 	    }
|> 	    expSign = FALSE;
|> 	}
|> 	while (isdigit(*p)) {
|> 	    exp = exp * 10 + (*p - '0');
|> 	    p += 1;
|> 	}
|>     }
|>     if (expSign) {
|> 	exp = fracExp - exp;
|>     } else {
|> 	exp = fracExp + exp;
|>     }
|> 
|>     /*
|>      * Generate a floating-point number that represents the exponent.
|>      * Do this by processing the exponent one bit at a time to combine
|>      * many powers of 2 of 10. Then combine the exponent with the
|>      * fraction.
|>      */
|>     
|>     if (exp < 0) {
|> 	expSign = TRUE;
|> 	exp = -exp;
|>     } else {
|> 	expSign = FALSE;
|>     }
|>     if (exp > maxExponent) {
|> 	exp = maxExponent;
|>     }
|>     dblExp = 1.0;
|>     for (d = powersOf10; exp != 0; exp >>= 1, d += 1) {
|> 	if (exp & 01) {
|> 	    dblExp *= *d;
|> 	}
|>     }
|>     if (expSign) {
|> 	fraction /= dblExp;
|>     } else {
|> 	fraction *= dblExp;
|>     }
|> 
|> done:
|>     if (endPtr != NULL) {
|> 	*endPtr = p;
|>     }
|> 
|>     if (sign) {
|> 	return (-1.00 * fraction);
|>     }
|>     return fraction;
|> }
|> 
|> 
|> double
|> atof(ascii)
|>      const   char *ascii;
|> {
|>         return(strtod(ascii, (char **)NULL));
|> }
|> 
|> -- 
|> This message brought to you by the letters X and S and the number 3
|> Amancio Hasty           |  
|> Home: (415) 495-3046    |  ftp-site depository of all my work:
|> e-mail hasty@netcom.com	|  sunvis.rtpnc.epa.gov:/pub/386bsd/incoming