mirror of git://git.code.sf.net/p/zsh/code
Nelson H. F. Beebe: 19597 (rebased 42369): return Inf, NaN etc from floating point operations instead of errors to allow non-stop IEEE 754 arithmetic
This commit is contained in:
parent
f0c2cf8607
commit
373efa085d
|
@ -1,5 +1,10 @@
|
|||
2018-05-13 Oliver Kiddle <okiddle@yahoo.co.uk>
|
||||
|
||||
* Nelson H. F. Beebe: 19597 (rebased 42369): Src/math.c,
|
||||
Src/params.c. Src/Modules/mathfunc.c, configure.ac:
|
||||
return Inf, NaN etc from floating point operations instead
|
||||
of errors to allow non-stop IEEE 754 arithmetic
|
||||
|
||||
* 42760: Src/Zle/zle_thingy.c: move stack variable outside
|
||||
while loop scope as it is accessed in the while condition
|
||||
|
||||
|
|
|
@ -208,49 +208,6 @@ math_func(char *name, int argc, mnumber *argv, int id)
|
|||
if (errflag)
|
||||
return ret;
|
||||
|
||||
if (id & 0xff00) {
|
||||
int rtst = 0;
|
||||
|
||||
switch ((id >> 8) & 0xff) {
|
||||
case BF_POS:
|
||||
rtst = (argd <= 0.0);
|
||||
break;
|
||||
|
||||
case BF_NONNEG:
|
||||
rtst = (argd < 0.0);
|
||||
break;
|
||||
|
||||
case BF_FRAC:
|
||||
rtst = (fabs(argd) > 1.0);
|
||||
break;
|
||||
|
||||
case BF_GE1:
|
||||
rtst = (argd < 1.0);
|
||||
break;
|
||||
|
||||
case BF_FRACO:
|
||||
rtst = (fabs(argd) >= 1.0);
|
||||
break;
|
||||
|
||||
case BF_INTPOS:
|
||||
rtst = (argd <= 0 && (double)(zlong)argd == argd);
|
||||
break;
|
||||
|
||||
case BF_GTRM1:
|
||||
rtst = (argd <= -1);
|
||||
break;
|
||||
|
||||
case BF_POS2:
|
||||
rtst = (argd2 <= 0.0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (rtst) {
|
||||
zerr("math: argument to %s out of range", name);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
switch (id & 0xff) {
|
||||
case MF_ABS:
|
||||
ret.type = argv->type;
|
||||
|
|
50
Src/math.c
50
Src/math.c
|
@ -578,6 +578,37 @@ int outputradix;
|
|||
/**/
|
||||
int outputunderscore;
|
||||
|
||||
#ifndef HAVE_ISINF
|
||||
/**/
|
||||
int
|
||||
isinf(double x)
|
||||
{
|
||||
if ((-1.0 < x) && (x < 1.0)) /* x is small, and thus finite */
|
||||
return (0);
|
||||
else if ((x + x) == x) /* only true if x == Infinity */
|
||||
return (1);
|
||||
else /* must be finite (normal or subnormal), or NaN */
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_ISNAN)
|
||||
/**/
|
||||
static double
|
||||
store(double *x)
|
||||
{
|
||||
return (*x);
|
||||
}
|
||||
|
||||
/**/
|
||||
int
|
||||
isnan(double x)
|
||||
{
|
||||
/* (x != x) should be sufficient, but some compilers incorrectly optimize it away */
|
||||
return (store(&x) != store(&x));
|
||||
}
|
||||
#endif
|
||||
|
||||
/**/
|
||||
static int
|
||||
zzlex(void)
|
||||
|
@ -791,6 +822,21 @@ zzlex(void)
|
|||
break;
|
||||
/* Fall through! */
|
||||
default:
|
||||
if (strcmp(ptr-1, "NaN") == 0) {
|
||||
yyval.type = MN_FLOAT;
|
||||
yyval.u.d = 0.0;
|
||||
yyval.u.d /= yyval.u.d;
|
||||
ptr += 2;
|
||||
return NUM;
|
||||
}
|
||||
else if (strcmp(ptr-1, "Inf") == 0) {
|
||||
yyval.type = MN_FLOAT;
|
||||
yyval.u.d = 0.0;
|
||||
yyval.u.d = 1.0 / yyval.u.d;
|
||||
ptr += 2;
|
||||
return NUM;
|
||||
}
|
||||
|
||||
if (idigit(*--ptr) || *ptr == '.')
|
||||
return lexconstant();
|
||||
if (*ptr == '#') {
|
||||
|
@ -1068,10 +1114,6 @@ callmathfunc(char *o)
|
|||
static int
|
||||
notzero(mnumber a)
|
||||
{
|
||||
if ((a.type & MN_INTEGER) ? a.u.l == 0 : a.u.d == 0.0) {
|
||||
zerr("division by zero");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
16
Src/params.c
16
Src/params.c
|
@ -36,6 +36,8 @@
|
|||
#else
|
||||
#include "patchlevel.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
/* If removed from the ChangeLog for some reason */
|
||||
#ifndef ZSH_PATCHLEVEL
|
||||
#define ZSH_PATCHLEVEL "unknown"
|
||||
|
@ -5431,10 +5433,16 @@ convfloat(double dval, int digits, int flags, FILE *fout)
|
|||
ret = NULL;
|
||||
} else {
|
||||
VARARR(char, buf, 512 + digits);
|
||||
sprintf(buf, fmt, digits, dval);
|
||||
if (!strchr(buf, 'e') && !strchr(buf, '.'))
|
||||
strcat(buf, ".");
|
||||
ret = dupstring(buf);
|
||||
if (isinf(dval))
|
||||
ret = dupstring((dval < 0.0) ? "-Inf" : "Inf");
|
||||
else if (isnan(dval))
|
||||
ret = dupstring("NaN");
|
||||
else {
|
||||
sprintf(buf, fmt, digits, dval);
|
||||
if (!strchr(buf, 'e') && !strchr(buf, '.'))
|
||||
strcat(buf, ".");
|
||||
ret = dupstring(buf);
|
||||
}
|
||||
}
|
||||
#ifdef USE_LOCALE
|
||||
if (prev_locale) setlocale(LC_NUMERIC, prev_locale);
|
||||
|
|
|
@ -1317,6 +1317,7 @@ AC_CHECK_FUNCS(strftime strptime mktime timelocal \
|
|||
erand48 open_memstream \
|
||||
posix_openpt \
|
||||
wctomb iconv \
|
||||
isinf isnan \
|
||||
grantpt unlockpt ptsname \
|
||||
htons ntohs \
|
||||
regcomp regexec regerror regfree \
|
||||
|
|
Loading…
Reference in New Issue