Inf and NaN values fixed and printing improved. "This time for sure!"
This commit is contained in:
parent
982a574e32
commit
8909e00b57
8
FIXES
8
FIXES
@ -25,6 +25,14 @@ THIS SOFTWARE.
|
|||||||
This file lists all bug fixes, changes, etc., made since the AWK book
|
This file lists all bug fixes, changes, etc., made since the AWK book
|
||||||
was sent to the printers in August, 1987.
|
was sent to the printers in August, 1987.
|
||||||
|
|
||||||
|
December 18, 2020:
|
||||||
|
Fix problems converting inf and NaN values in lib.c:is_valid_number.
|
||||||
|
Enhance number to string conversion to do the right thing for
|
||||||
|
NaN and inf values. Things are now pretty much the same as in
|
||||||
|
gawk. (Found a gawk bug while we're at it.) Added a torture
|
||||||
|
test for these values. Thanks to Arnold Robbins. Allows closing
|
||||||
|
of PR #101.
|
||||||
|
|
||||||
December 15, 2020:
|
December 15, 2020:
|
||||||
Merge PR #99, which gets the right header for strcasecmp.
|
Merge PR #99, which gets the right header for strcasecmp.
|
||||||
Thanks to GitHub user michaelforney.
|
Thanks to GitHub user michaelforney.
|
||||||
|
4
bugs-fixed/inf-nan-torture.awk
Normal file
4
bugs-fixed/inf-nan-torture.awk
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
for (i = 1; i <= NF; i++)
|
||||||
|
print i, $i, $i + 0
|
||||||
|
}
|
1
bugs-fixed/inf-nan-torture.in
Normal file
1
bugs-fixed/inf-nan-torture.in
Normal file
@ -0,0 +1 @@
|
|||||||
|
-inf -inform inform -nan -nancy nancy -123 0 123 +123 nancy +nancy +nan inform +inform +inf
|
16
bugs-fixed/inf-nan-torture.ok
Normal file
16
bugs-fixed/inf-nan-torture.ok
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
1 -inf -inf
|
||||||
|
2 -inform 0
|
||||||
|
3 inform 0
|
||||||
|
4 -nan -nan
|
||||||
|
5 -nancy 0
|
||||||
|
6 nancy 0
|
||||||
|
7 -123 -123
|
||||||
|
8 0 0
|
||||||
|
9 123 123
|
||||||
|
10 +123 123
|
||||||
|
11 nancy 0
|
||||||
|
12 +nancy 0
|
||||||
|
13 +nan +nan
|
||||||
|
14 inform 0
|
||||||
|
15 +inform 0
|
||||||
|
16 +inf +inf
|
32
lib.c
32
lib.c
@ -784,46 +784,48 @@ bool is_valid_number(const char *s, bool trailing_stuff_ok,
|
|||||||
double r;
|
double r;
|
||||||
char *ep;
|
char *ep;
|
||||||
bool retval = false;
|
bool retval = false;
|
||||||
|
bool is_nan = false;
|
||||||
|
bool is_inf = false;
|
||||||
|
|
||||||
if (no_trailing)
|
if (no_trailing)
|
||||||
*no_trailing = false;
|
*no_trailing = false;
|
||||||
|
|
||||||
while (*s == ' ' || *s == '\t' || *s == '\n' || *s == '\r')
|
while (isspace(*s))
|
||||||
s++;
|
s++;
|
||||||
|
|
||||||
if (s[0] == '0' && tolower(s[1]) == 'x') // no hex floating point, sorry
|
// no hex floating point, sorry
|
||||||
|
if (s[0] == '0' && tolower(s[1]) == 'x')
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// allow +nan, -nan, +inf, -inf, any other letter, no
|
// allow +nan, -nan, +inf, -inf, any other letter, no
|
||||||
if (s[0] == '+' || s[0] == '-') {
|
if (s[0] == '+' || s[0] == '-') {
|
||||||
if (strcasecmp(s+1, "nan") == 0 || strcasecmp(s+1, "inf") == 0)
|
is_nan = (strncasecmp(s+1, "nan", 3) == 0);
|
||||||
return true;
|
is_inf = (strncasecmp(s+1, "inf", 3) == 0);
|
||||||
|
if ((is_nan || is_inf)
|
||||||
|
&& (isspace(s[4]) || s[4] == '\0'))
|
||||||
|
goto convert;
|
||||||
else if (! isdigit(s[1]) && s[1] != '.')
|
else if (! isdigit(s[1]) && s[1] != '.')
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (! isdigit(s[0]) && s[0] != '.')
|
else if (! isdigit(s[0]) && s[0] != '.')
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
convert:
|
||||||
errno = 0;
|
errno = 0;
|
||||||
r = strtod(s, &ep);
|
r = strtod(s, &ep);
|
||||||
if (ep == s || r == HUGE_VAL || errno == ERANGE)
|
if (ep == s || errno == ERANGE)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (isnan(r) && s[0] == '-' && signbit(r) == 0)
|
||||||
|
r = -r;
|
||||||
|
|
||||||
if (result != NULL)
|
if (result != NULL)
|
||||||
*result = r;
|
*result = r;
|
||||||
|
|
||||||
/*
|
retval = (isspace(*ep) || *ep == '\0' || trailing_stuff_ok);
|
||||||
* check for trailing stuff
|
|
||||||
* allow \r as well. windows files aren't going to go away.
|
|
||||||
*/
|
|
||||||
while (*ep == ' ' || *ep == '\t' || *ep == '\n' || *ep == '\r')
|
|
||||||
ep++;
|
|
||||||
|
|
||||||
if (no_trailing)
|
if (no_trailing != NULL)
|
||||||
*no_trailing = (*ep == '\0');
|
*no_trailing = (*ep == '\0');
|
||||||
|
|
||||||
// return true if found the end, or trailing stuff is allowed
|
|
||||||
retval = (*ep == '\0') || trailing_stuff_ok;
|
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
2
main.c
2
main.c
@ -22,7 +22,7 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
|||||||
THIS SOFTWARE.
|
THIS SOFTWARE.
|
||||||
****************************************************************/
|
****************************************************************/
|
||||||
|
|
||||||
const char *version = "version 20201215";
|
const char *version = "version 20201218";
|
||||||
|
|
||||||
#define DEBUG
|
#define DEBUG
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
15
tran.c
15
tran.c
@ -418,10 +418,21 @@ Awkfloat getfval(Cell *vp) /* get float val of a Cell */
|
|||||||
return(vp->fval);
|
return(vp->fval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *get_inf_nan(double d)
|
||||||
|
{
|
||||||
|
if (isinf(d)) {
|
||||||
|
return (d < 0 ? "-inf" : "+inf");
|
||||||
|
} else if (isnan(d)) {
|
||||||
|
return (signbit(d) != 0 ? "-nan" : "+nan");
|
||||||
|
} else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static char *get_str_val(Cell *vp, char **fmt) /* get string val of a Cell */
|
static char *get_str_val(Cell *vp, char **fmt) /* get string val of a Cell */
|
||||||
{
|
{
|
||||||
char s[256];
|
char s[256];
|
||||||
double dtemp;
|
double dtemp;
|
||||||
|
char *p;
|
||||||
|
|
||||||
if ((vp->tval & (NUM | STR)) == 0)
|
if ((vp->tval & (NUM | STR)) == 0)
|
||||||
funnyvar(vp, "read value of");
|
funnyvar(vp, "read value of");
|
||||||
@ -458,7 +469,9 @@ static char *get_str_val(Cell *vp, char **fmt) /* get string val of a Cel
|
|||||||
{ \
|
{ \
|
||||||
if (freeable(vp)) \
|
if (freeable(vp)) \
|
||||||
xfree(vp->sval); \
|
xfree(vp->sval); \
|
||||||
if (modf(vp->fval, &dtemp) == 0) /* it's integral */ \
|
if ((p = get_inf_nan(vp->fval)) != NULL) \
|
||||||
|
strcpy(s, p); \
|
||||||
|
else if (modf(vp->fval, &dtemp) == 0) /* it's integral */ \
|
||||||
snprintf(s, sizeof (s), "%.30g", vp->fval); \
|
snprintf(s, sizeof (s), "%.30g", vp->fval); \
|
||||||
else \
|
else \
|
||||||
snprintf(s, sizeof (s), *fmt, vp->fval); \
|
snprintf(s, sizeof (s), *fmt, vp->fval); \
|
||||||
|
Loading…
Reference in New Issue
Block a user