summaryrefslogtreecommitdiff
path: root/Src/math.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/math.c')
-rw-r--r--Src/math.c50
1 files changed, 46 insertions, 4 deletions
diff --git a/Src/math.c b/Src/math.c
index c3831602b..cdfe80bb4 100644
--- a/Src/math.c
+++ b/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;
}