BSD 4_3_Net_2 release
[unix-history] / usr / src / lib / libc / hp300 / stdlib / atof.c
index 5b2bfdc..e8ec7a9 100644 (file)
@@ -6,40 +6,56 @@
  * the Systems Programming Group of the University of Utah Computer
  * Science Department.
  *
  * the Systems Programming Group of the University of Utah Computer
  * Science Department.
  *
- * Redistribution and use in source and binary forms are permitted
- * provided that: (1) source distributions retain this entire copyright
- * notice and comment, and (2) distributions including binaries display
- * the following acknowledgement:  ``This product includes software
- * developed by the University of California, Berkeley and its contributors''
- * in the documentation or other materials provided with the distribution
- * and in all advertising materials mentioning features or use of this
- * software. Neither the name of the University nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)atof.c     5.1 (Berkeley) 5/12/90";
+static char sccsid[] = "@(#)atof.c     5.2 (Berkeley) 4/12/91";
 #endif /* LIBC_SCCS and not lint */
 
 #endif /* LIBC_SCCS and not lint */
 
+/*
+ * simple atof() for IEEE 754 architectures
+ */
+
+#include <machine/endian.h>
+#include <stdlib.h>
+#include <math.h>
 #include <ctype.h>
 
 #include <ctype.h>
 
-double _twoemax =
-#ifdef IEEE
-       9007199254740992.;      /*2^53*/
-#else
-       72057594037927936.;     /*2^56*/
-#endif
+static double twoemax = 9007199254740992.;     /*2^53*/
 
 
-#ifdef hp300
 /* attempt to be as exact as possible */
 /* attempt to be as exact as possible */
-struct {
-       long d_high;
-       long d_low;
-} _exp5[] = {
+static struct {
+       long low_word;
+       long high_word;
+} exp5[] = {
+#if    BYTE_ORDER == BIG_ENDIAN
        { 0x40140000, 0x00000000 },     /* 5 */
        { 0x40390000, 0x00000000 },     /* 25 */
        { 0x40838800, 0x00000000 },     /* 625 */
        { 0x40140000, 0x00000000 },     /* 5 */
        { 0x40390000, 0x00000000 },     /* 25 */
        { 0x40838800, 0x00000000 },     /* 625 */
@@ -49,64 +65,85 @@ struct {
        { 0x49384f03, 0xe93ff9f6 },     /* 5.42101086242753e+044 */
        { 0x52827748, 0xf9301d33 },     /* 2.93873587705572e+089 */
        { 0x65154fdd, 0x7f73bf3f }      /* 8.63616855509445e+178 */
        { 0x49384f03, 0xe93ff9f6 },     /* 5.42101086242753e+044 */
        { 0x52827748, 0xf9301d33 },     /* 2.93873587705572e+089 */
        { 0x65154fdd, 0x7f73bf3f }      /* 8.63616855509445e+178 */
-};
-#else
-double _exp5[] = {
-       5.,
-       25.,
-       625.,
-       390625.,
-       152587890625.,
-       23283064365386962890625.,
-#ifdef IEEE
-       5.4210108624275231e+044,
-       2.9387358770557196e+089,
-       8.6361685550944492e+178,
+#else  /* BYTE_ORDER == LITTLE_ENDIAN */
+       { 0x00000000, 0x40140000 },     /* 5 */
+       { 0x00000000, 0x40390000 },     /* 25 */
+       { 0x00000000, 0x40838800 },     /* 625 */
+       { 0x00000000, 0x4117d784 },     /* 390625 */
+       { 0x37e08000, 0x4241c379 },     /* 152587890625 */
+       { 0xb5056e17, 0x4493b8b5 },     /* 2.3283064365387e+022 */
+       { 0xe93ff9f6, 0x49384f03 },     /* 5.42101086242753e+044 */
+       { 0xf9301d33, 0x52827748 },     /* 2.93873587705572e+089 */
+       { 0x7f73bf3f, 0x65154fdd }      /* 8.63616855509445e+178 */
 #endif
 };
 #endif
 };
-#endif
 
 double
 atof(p)
 
 double
 atof(p)
-register char *p;
+       register const char *p;
 {
 {
-       extern double ldexp();
-       register c, exp = 0, eexp = 0;
-       double fl = 0, flexp = 1.0;
-       int bexp, neg = 1, negexp = 1;
+       register int c;
+       register int exp = 0;
+       register int eexp = 0;
+       double fl = 0;
+       double flexp = 1.0;
+       int bexp;
+       int neg = 1;
+       int negexp = 1;
+
+       while (isspace(*p))
+               ++p;
 
 
-       while((c = *p++) == ' ');
-       if (c == '-') neg = -1; else if (c == '+'); else --p;
+       if ((c = *p++) == '-')
+               neg = -1;
+       else if (c == '+')
+               /* skip it */;
+       else
+               --p;
+
+       while ((c = *p++) && isdigit(c))
+               if (fl < twoemax)
+                       fl = 10 * fl + (c-'0');
+               else
+                       ++exp;
 
 
-       while ((c = *p++), isdigit(c))
-               if (fl < _twoemax) fl = 10*fl + (c-'0'); else exp++;
        if (c == '.')
        if (c == '.')
-       while ((c = *p++), isdigit(c))
-               if (fl < _twoemax)
-               {
-                       fl = 10*fl + (c-'0');
-                       exp--;
-               }
-       if ((c == 'E') || (c == 'e'))
-       {
-               if ((c= *p++) == '+'); else if (c=='-') negexp = -1; else --p;
-               while ((c = *p++), isdigit(c)) eexp = 10*eexp + (c-'0');
-               if (negexp < 0) eexp = -eexp; exp += eexp;
+               while ((c = *p++) && isdigit(c))
+                       if (fl < twoemax) {
+                               fl = 10 * fl + (c-'0');
+                               --exp;
+                       }
+
+       if (c == 'E' || c == 'e') {
+               if ((c = *p++) == '-')
+                       negexp = -1;
+               else if (c == '+')
+                       /* skip it */;
+               else
+                       --p;
+               while ((c = *p++) && isdigit(c))
+                       eexp = 10 * eexp + (c-'0');
+               if (negexp < 0)
+                       eexp = -eexp;
+               exp += eexp;
        }
        }
+
        bexp = exp;
        bexp = exp;
-       if (exp < 0) exp = -exp;
-
-       for (c = 0; c < sizeof(_exp5)/sizeof(_exp5[0]); c++)
-       {
-#ifdef hp300
-               if (exp & 01) flexp *= *(double *)&_exp5[c];
-#else
-               if (exp & 01) flexp *= _exp5[c];
-#endif
-               exp >>= 1; if (exp == 0) break;
+       if (exp < 0)
+               exp = -exp;
+
+       for (c = 0; exp && c < sizeof exp5 / sizeof exp5[0]; ++c) {
+               if (exp & 1)
+                       flexp *= *(double *)&exp5[c];
+               exp >>= 1;
        }
 
        }
 
-       if (bexp < 0) fl /= flexp; else fl *= flexp;
+       if (bexp < 0)
+               fl /= flexp;
+       else
+               fl *= flexp;
+
        fl = ldexp(fl, bexp);
        fl = ldexp(fl, bexp);
-       if (neg < 0) return(-fl); else return(fl);
+
+       return neg < 0 ? -fl : fl;
 }
 }