summaryrefslogtreecommitdiff
path: root/lib/libc/stdlib
diff options
context:
space:
mode:
authorkleink <kleink@NetBSD.org>2002-01-28 00:10:04 +0000
committerkleink <kleink@NetBSD.org>2002-01-28 00:10:04 +0000
commitf100d16fcf17c795a4fa1f93eee4d2a9fec3dfde (patch)
treec69abd1153721d41dcc45c06ad688933ba9c2d9b /lib/libc/stdlib
parent8e6a975576292265de484038ecfed0af52494706 (diff)
C99: support INF, INFINITY, NAN and NAN(n-char-sequence-opt) arguments.
Diffstat (limited to 'lib/libc/stdlib')
-rw-r--r--lib/libc/stdlib/strtod.342
-rw-r--r--lib/libc/stdlib/strtod.c44
2 files changed, 81 insertions, 5 deletions
diff --git a/lib/libc/stdlib/strtod.3 b/lib/libc/stdlib/strtod.3
index 5a9b3628a99..cc7cad9a33b 100644
--- a/lib/libc/stdlib/strtod.3
+++ b/lib/libc/stdlib/strtod.3
@@ -1,4 +1,4 @@
-.\" $NetBSD: strtod.3,v 1.10 2001/09/16 01:31:53 wiz Exp $
+.\" $NetBSD: strtod.3,v 1.11 2002/01/28 00:10:04 kleink Exp $
.\"
.\" Copyright (c) 1990, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -37,7 +37,7 @@
.\"
.\" from: @(#)strtod.3 8.1 (Berkeley) 6/4/93
.\"
-.Dd March 21, 2001
+.Dd January 28, 2002
.Dt STRTOD 3
.Os
.Sh NAME
@@ -62,10 +62,27 @@ to
representation.
.Pp
The expected form of the string is an optional plus (``+'') or minus
-sign (``\-'') followed by a sequence of digits optionally containing
+sign (``\-'') followed by one of the following:
+.Bl -dash
+.It
+a sequence of digits optionally containing
a decimal-point character, optionally followed by an exponent.
An exponent consists of an ``E'' or ``e'', followed by an optional plus
or minus sign, followed by a sequence of digits.
+.It
+one of
+.Li INF
+or
+.Li INFINITY ,
+ignoring case.
+.It
+one of
+.Li NAN
+or
+.Li NAN(n-char-sequence-opt) ,
+ignoring case.
+This implementation currently does not interpret such a sequence.
+.El
.Pp
Leading white-space characters in the string (as defined by the
.Xr isspace 3
@@ -75,6 +92,24 @@ The
.Fn strtod
function returns the converted value, if any.
.Pp
+A character sequence
+.Li INF
+or
+.Li INFINITY
+is converted to \*(If,
+if supported, else to the largest finite floating-point number representable
+on the machine (i.e.,
+.Tn VAX Ns ).
+.Pp
+A character sequence
+.Li NAN
+or
+.Li NAN(n-char-sequence-opt)
+is converted to a quiet \*(Na, if supported, else to a
+.Dq reserved operand
+for that machine (i.e.,
+.Tn VAX Ns ).
+.Pp
If
.Fa endptr
is not
@@ -108,6 +143,7 @@ Overflow or underflow occurred.
.Xr atof 3 ,
.Xr atoi 3 ,
.Xr atol 3 ,
+.Xr math 3 ,
.Xr strtol 3 ,
.Xr strtoul 3
.Sh STANDARDS
diff --git a/lib/libc/stdlib/strtod.c b/lib/libc/stdlib/strtod.c
index d90a7f73562..2238dae84f4 100644
--- a/lib/libc/stdlib/strtod.c
+++ b/lib/libc/stdlib/strtod.c
@@ -1,4 +1,4 @@
-/* $NetBSD: strtod.c,v 1.38 2001/12/15 03:39:53 thorpej Exp $ */
+/* $NetBSD: strtod.c,v 1.39 2002/01/28 00:10:04 kleink Exp $ */
/****************************************************************
*
@@ -93,7 +93,7 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: strtod.c,v 1.38 2001/12/15 03:39:53 thorpej Exp $");
+__RCSID("$NetBSD: strtod.c,v 1.39 2002/01/28 00:10:04 kleink Exp $");
#endif /* LIBC_SCCS and not lint */
#define Unsigned_Shifts
@@ -1282,6 +1282,46 @@ strtod
goto ret;
}
+ /* "INF" or "INFINITY" */
+ if (tolower(*s) == 'i' && strncasecmp(s, "inf", 3) == 0) {
+ if (strncasecmp(s + 3, "inity", 5) == 0)
+ s += 8;
+ else
+ s += 3;
+
+ value(rv) = HUGE_VAL;
+ goto ret;
+ }
+
+ /* "NAN" or "NAN(n-char-sequence-opt)" */
+ if (tolower(*s) == 'n' && strncasecmp(s, "nan", 3) == 0) {
+#ifdef IEEE_Arith
+ /* Build a quiet NaN. */
+ word0(rv) = Exp_mask | ((1 << Exp_shift) - 1);
+ word1(rv) = 0;
+#else
+#ifdef VAX
+ /* Lacking a quiet NaN, build a reserved operand. */
+ word0(rv) = Sign_bit;
+ word1(rv) = 0;
+#endif
+#endif
+ s+= 3;
+
+ /* Don't interpret (n-char-sequence-opt), for now. */
+ if (*s == '(') {
+ s0 = s;
+ for (s++; *s != ')' && *s != '\0'; s++)
+ ;
+ if (*s == ')')
+ s++; /* Skip over closing paren ... */
+ else
+ s = s0; /* ... otherwise go back. */
+ }
+
+ goto ret;
+ }
+
if (*s == '0') {
nz0 = 1;
while(*++s == '0') ;