Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-7]: src/lib/libc/stdlib Pull up following revision(s) (requested ...



details:   https://anonhg.NetBSD.org/src/rev/f37291d2a00b
branches:  netbsd-7
changeset: 800071:f37291d2a00b
user:      snj <snj%NetBSD.org@localhost>
date:      Sun Dec 18 06:31:01 2016 +0000

description:
Pull up following revision(s) (requested by riastradh in ticket #1311):
        lib/libc/stdlib/strtod.3: revisions 1.21-1.29
        lib/libc/stdlib/strtol.3: revision 1.36-1.38
        lib/libc/stdlib/strtoul.3: revision 1.36
strtod yields ERANGE for below-subnormal magnitudes, not underflow.
For a floating-point computation, in the language of IEEE 754,
`underflow' means the output was rounded and is too small to be
represented *normally*.
There are many nonzero floating-point numbers to which the exact
output may have been rounded -- namely subnormals.  The condition
under which strtod returns ERANGE for small magnitudes is when the
magnitude of the exact result is so small it is rounded to zero, not
even to a subnormal.
While here, use parallel language about large magnitudes instead of
the (albeit correct) word `overflow', to avoid temptation to treat
`underflow' as the opposite notion with zero instead of infinity.
--
Bump date for previous.
--
Fix description of ERANGE cases again.
Do use the technical terms `overflow' and `underflow', because strtod
sets ERANGE precisely to indicate either of these two conditions, and
they are the right keywords that one might be looking for.
Note that strtod may set ERANGE even if it returns noninfinity and
nonzero -- specifically, if the result is subnormal.  This part was
wrong before I `fixed' it and remained wrong after I `fixed' it
earlier this year.
--
Add example for strtod.
This illustrates all the cases you might be interested in and asserts
theorems in those cases.
--
Fix infinity detection with isinf(d), not d == HUGE_VAL.
Negative infinity counts as overflow too.
Simplify.
--
EXIT_FAILURE police
--
Distinguish altogether invalid syntax from trailing garbage.
--
Distinguish invalid syntax from trailing garbage cases.  Clarify.
--
Simplify error condition case.
Add assertions to reflect its implications.
--
Tidy up the second example too.
--
Update strtoul(3) example to reflect clarifications in strtol(3).
--
Fix phrasing about `out-of-band' and `sentinel value'.
Either an out-of-band channel, or an in-band sentinel value, could
indicate an error, but an out-of-band sentinel value is a silly
proposition.
Noted by uwe@.
--
Use the keywords `underflow' and `overflow' in ERANGE summary.

diffstat:

 lib/libc/stdlib/strtod.3  |  57 ++++++++++++++++++++++++++++++++++++++++++----
 lib/libc/stdlib/strtol.3  |  21 ++++++++++++----
 lib/libc/stdlib/strtoul.3 |  11 ++++++--
 3 files changed, 74 insertions(+), 15 deletions(-)

diffs (164 lines):

diff -r 30ae30bbd739 -r f37291d2a00b lib/libc/stdlib/strtod.3
--- a/lib/libc/stdlib/strtod.3  Sun Dec 18 06:23:22 2016 +0000
+++ b/lib/libc/stdlib/strtod.3  Sun Dec 18 06:31:01 2016 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: strtod.3,v 1.20 2007/10/24 13:42:10 reed Exp $
+.\"    $NetBSD: strtod.3,v 1.20.50.1 2016/12/18 06:31:01 snj Exp $
 .\"
 .\" Copyright (c) 1990, 1991, 1993
 .\"    The Regents of the University of California.  All rights reserved.
@@ -33,7 +33,7 @@
 .\"
 .\"     from: @(#)strtod.3     8.1 (Berkeley) 6/4/93
 .\"
-.Dd March 12, 2006
+.Dd November 4, 2016
 .Dt STRTOD 3
 .Os
 .Sh NAME
@@ -151,7 +151,9 @@
 is stored in the location referenced by
 .Fa endptr .
 .Pp
-If the correct value would cause overflow, plus or minus
+If the correct value is too large in magnitude to be represented
+.Pq Sq overflow ,
+plus or minus
 .Dv HUGE_VAL ,
 .Dv HUGE_VALF ,
 or
@@ -160,15 +162,58 @@
 .Dv ERANGE
 is stored in
 .Va errno .
-If the correct value would cause underflow, zero is
-returned and
+.Pp
+If the correct value is too small in magnitude to be represented
+normally with full precision
+.Pq Sq underflow ,
+the closest subnormal value, or zero, is returned, and
 .Dv ERANGE
 is stored in
 .Va errno .
+.Sh EXAMPLES
+Since there is no out-of-band channel or sentinel value to indicate an
+error, callers who wish to know whether there was overflow or underflow
+must set
+.Va errno
+to zero before calling
+.Fn strtod ,
+.Fn strtof ,
+or
+.Fn strtold ;
+in the case of no underflow or overflow, these functions preserve
+.Va errno .
+.Pp
+To check for syntax errors, callers must
+.Em also
+check whether
+.Fa endptr
+was updated to reflect the true end of the string in order to determine
+whether the full string was consumed or whether there were additional
+erroneous characters in it.
+.Bd -literal -offset abcd
+char *end;
+double d;
+
+\&...
+
+errno = 0;
+d = strtod(s, &end);
+if (end == s)
+       errx(EXIT_FAILURE, "invalid syntax");
+if (end[0] != '\e0')
+       errx(EXIT_FAILURE, "trailing garbage");
+if (errno) {
+       assert(errno == ERANGE);
+       assert(isinf(d) || d == 0 ||
+           fpclassify(d) == FP_SUBNORMAL);
+       warnx("%s", isinf(d) ? "overflow" : "underflow");
+}
+/* d is the best floating-point approximation to the number in s */
+.Ed
 .Sh ERRORS
 .Bl -tag -width Er
 .It Bq Er ERANGE
-Overflow or underflow occurred.
+The conversion resulted in floating-point underflow or overflow.
 .El
 .Sh SEE ALSO
 .Xr atof 3 ,
diff -r 30ae30bbd739 -r f37291d2a00b lib/libc/stdlib/strtol.3
--- a/lib/libc/stdlib/strtol.3  Sun Dec 18 06:23:22 2016 +0000
+++ b/lib/libc/stdlib/strtol.3  Sun Dec 18 06:31:01 2016 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: strtol.3,v 1.26.24.2 2015/05/16 17:58:46 snj Exp $
+.\"    $NetBSD: strtol.3,v 1.26.24.3 2016/12/18 06:31:01 snj Exp $
 .\"
 .\" Copyright (c) 1990, 1991, 1993
 .\"    The Regents of the University of California.  All rights reserved.
@@ -213,10 +213,15 @@
 
 errno = 0;
 lval = strtol(buf, \*[Am]ep, 10);
-if (buf[0] == '\e0' || *ep != '\e0')
+if (ep == buf)
        goto not_a_number;
-if (errno == ERANGE \*[Am]\*[Am] (lval == LONG_MAX || lval == LONG_MIN))
+if (*ep != '\e0')
+       goto trailing_garbage;
+if (errno) {
+       assert(errno == ERANGE);
+       assert(lval == LONG_MAX || lval == LONG_MIN);
        goto out_of_range;
+}
 .Ed
 .Pp
 This example will accept
@@ -249,11 +254,15 @@
 
 errno = 0;
 lval = strtol(buf, \*[Am]ep, 10);
-if (buf[0] == '\e0' || *ep != '\e0')
+if (ep == buf)
        goto not_a_number;
-if ((errno == ERANGE \*[Am]\*[Am] (lval == LONG_MAX || lval == LONG_MIN)) ||
-    (lval \*[Gt] INT_MAX || lval \*[Lt] INT_MIN))
+if (*ep != '\e0')
+       goto trailing_garbage;
+if (errno == ERANGE || lval < INT_MIN || INT_MAX < lval)
        goto out_of_range;
+assert(errno == 0);
+assert(INT_MIN <= lval);
+assert(lval <= INT_MAX);
 ival = lval;
 .Ed
 .Sh ERRORS
diff -r 30ae30bbd739 -r f37291d2a00b lib/libc/stdlib/strtoul.3
--- a/lib/libc/stdlib/strtoul.3 Sun Dec 18 06:23:22 2016 +0000
+++ b/lib/libc/stdlib/strtoul.3 Sun Dec 18 06:31:01 2016 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: strtoul.3,v 1.25.24.2 2015/05/16 17:58:47 snj Exp $
+.\"    $NetBSD: strtoul.3,v 1.25.24.3 2016/12/18 06:31:01 snj Exp $
 .\"
 .\" Copyright (c) 1990, 1991, 1993
 .\"    The Regents of the University of California.  All rights reserved.
@@ -215,10 +215,15 @@
 
 errno = 0;
 ulval = strtoul(buf, \*[Am]ep, 10);
-if (buf[0] == '\e0' || *ep != '\e0')
+if (ep == buf)
        goto not_a_number;
-if (errno == ERANGE \*[Am]\*[Am] ulval == ULONG_MAX)
+if (*ep != '\e0')
+       goto trailing_garbage;
+if (errno) {
+       assert(errno == ERANGE);
+       assert(ulval == ULONG_MAX);
        goto out_of_range;
+}
 .Ed
 .Pp
 This example will accept



Home | Main Index | Thread Index | Old Index