summaryrefslogtreecommitdiff
path: root/Src/math.c
diff options
context:
space:
mode:
authorAxel Beckert <abe@deuxchevaux.org>2018-08-27 13:31:04 +0200
committerAxel Beckert <abe@deuxchevaux.org>2018-08-27 13:31:04 +0200
commit719a715614f2182a76b30ad27a327d70a86f34f1 (patch)
treea437eb29da8035bf7c2e30506c08fe6f15719871 /Src/math.c
parent7da8d19c224860ae4d6aa3f077fca7f734f20d88 (diff)
parentef61918398517473b9b594690a3be375f607cebe (diff)
downloadzsh-719a715614f2182a76b30ad27a327d70a86f34f1.tar.gz
zsh-719a715614f2182a76b30ad27a327d70a86f34f1.zip
Merge tag 'zsh-5.5.1-test-2' into debian
Test release: 5.5.1-test-2.
Diffstat (limited to 'Src/math.c')
-rw-r--r--Src/math.c70
1 files changed, 62 insertions, 8 deletions
diff --git a/Src/math.c b/Src/math.c
index c3831602b..b08e05cb4 100644
--- a/Src/math.c
+++ b/Src/math.c
@@ -535,7 +535,7 @@ lexconstant(void)
for (ptr2 = ptr; ptr2 < nptr; ptr2++) {
if (*ptr2 == '_') {
int len = nptr - ptr;
- ptr = ztrdup(ptr);
+ ptr = dupstring(ptr);
for (ptr2 = ptr; len; len--) {
if (*ptr2 == '_')
chuck(ptr2);
@@ -578,6 +578,36 @@ 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)
@@ -610,8 +640,19 @@ zzlex(void)
}
if (unary) {
if (idigit(*ptr) || *ptr == '.') {
- ptr--;
- return lexconstant();
+ int ctype = lexconstant();
+ if (ctype == NUM)
+ {
+ if (yyval.type == MN_FLOAT)
+ {
+ yyval.u.d = -yyval.u.d;
+ }
+ else
+ {
+ yyval.u.l = -yyval.u.l;
+ }
+ }
+ return ctype;
} else
return UMINUS;
} else
@@ -785,11 +826,10 @@ zzlex(void)
ptr++;
break;
}
- case ' ':
+ case ' ': /* Fall through! */
case '\t':
case '\n':
break;
- /* Fall through! */
default:
if (idigit(*--ptr) || *ptr == '.')
return lexconstant();
@@ -814,6 +854,20 @@ zzlex(void)
p = ptr;
ptr = ie;
+ if (ie - p == 3) {
+ if (strncasecmp(p, "NaN", 3) == 0) {
+ yyval.type = MN_FLOAT;
+ yyval.u.d = 0.0;
+ yyval.u.d /= yyval.u.d;
+ return NUM;
+ }
+ else if (strncasecmp(p, "Inf", 3) == 0) {
+ yyval.type = MN_FLOAT;
+ yyval.u.d = 0.0;
+ yyval.u.d = 1.0 / yyval.u.d;
+ return NUM;
+ }
+ }
if (*ptr == '[' || (!cct && *ptr == '(')) {
char op = *ptr, cp = ((*ptr == '[') ? ']' : ')');
int l;
@@ -1068,9 +1122,9 @@ 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;
+ if ((a.type & MN_INTEGER) && a.u.l == 0) {
+ zerr("division by zero");
+ return 0;
}
return 1;
}