C99: support INF, INFINITY, NAN and NAN(n-char-sequence-opt) arguments.

This commit is contained in:
kleink 2002-01-28 00:10:04 +00:00
parent 8e6a975576
commit f100d16fcf
2 changed files with 81 additions and 5 deletions

View File

@ -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

View File

@ -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') ;