From e27071de780630b3a8279a7239336f450738d0cd Mon Sep 17 00:00:00 2001 From: ceriel Date: Tue, 19 Mar 1991 16:39:40 +0000 Subject: [PATCH] Check for Nan --- lang/cem/libcc.ansi/math/.distr | 1 + lang/cem/libcc.ansi/math/LIST | 1 + lang/cem/libcc.ansi/math/Makefile | 2 +- lang/cem/libcc.ansi/math/asin.c | 5 +++++ lang/cem/libcc.ansi/math/atan.c | 5 +++++ lang/cem/libcc.ansi/math/exp.c | 4 ++++ lang/cem/libcc.ansi/math/ldexp.c | 8 ++++++++ lang/cem/libcc.ansi/math/log.c | 8 ++++++++ lang/cem/libcc.ansi/math/log10.c | 4 ++++ lang/cem/libcc.ansi/math/sin.c | 20 ++++++++++++++------ lang/cem/libcc.ansi/math/sinh.c | 4 ++++ lang/cem/libcc.ansi/math/sqrt.c | 7 +++++++ lang/cem/libcc.ansi/math/tan.c | 8 ++++++++ lang/cem/libcc.ansi/math/tanh.c | 5 +++++ 14 files changed, 75 insertions(+), 7 deletions(-) diff --git a/lang/cem/libcc.ansi/math/.distr b/lang/cem/libcc.ansi/math/.distr index 60a71bed5..3a27813a4 100644 --- a/lang/cem/libcc.ansi/math/.distr +++ b/lang/cem/libcc.ansi/math/.distr @@ -21,3 +21,4 @@ sinh.c sqrt.c tan.c tanh.c +isnan.c diff --git a/lang/cem/libcc.ansi/math/LIST b/lang/cem/libcc.ansi/math/LIST index 720a4f4d2..09a0b3c06 100644 --- a/lang/cem/libcc.ansi/math/LIST +++ b/lang/cem/libcc.ansi/math/LIST @@ -19,3 +19,4 @@ floor.c hugeval.c frexp.e modf.e +isnan.c diff --git a/lang/cem/libcc.ansi/math/Makefile b/lang/cem/libcc.ansi/math/Makefile index a929104bc..1081596a0 100644 --- a/lang/cem/libcc.ansi/math/Makefile +++ b/lang/cem/libcc.ansi/math/Makefile @@ -1,4 +1,4 @@ clean: rm -f asin.o atan2.o atan.o ceil.o fabs.o pow.o log10.o \ log.o sin.o sinh.o sqrt.o tan.o tanh.o exp.o ldexp.o \ - fmod.o floor.o hugeval.o frexp.o modf.o OLIST + fmod.o floor.o hugeval.o frexp.o modf.o isnan.o OLIST diff --git a/lang/cem/libcc.ansi/math/asin.c b/lang/cem/libcc.ansi/math/asin.c index c316b9b1f..ea90fce89 100644 --- a/lang/cem/libcc.ansi/math/asin.c +++ b/lang/cem/libcc.ansi/math/asin.c @@ -32,6 +32,11 @@ asin_acos(double x, int cosfl) 1.0 }; + if (__IsNan(x)) { + errno = EDOM; + return x; + } + if (negative) { x = -x; } diff --git a/lang/cem/libcc.ansi/math/atan.c b/lang/cem/libcc.ansi/math/atan.c index 23cb63609..ff1c91275 100644 --- a/lang/cem/libcc.ansi/math/atan.c +++ b/lang/cem/libcc.ansi/math/atan.c @@ -8,6 +8,7 @@ #include #include +#include #include "localmath.h" double @@ -42,6 +43,10 @@ atan(double x) int n; double g; + if (__IsNan(x)) { + errno = EDOM; + return x; + } if (neg) { x = -x; } diff --git a/lang/cem/libcc.ansi/math/exp.c b/lang/cem/libcc.ansi/math/exp.c index d416fea75..ff76afb17 100644 --- a/lang/cem/libcc.ansi/math/exp.c +++ b/lang/cem/libcc.ansi/math/exp.c @@ -36,6 +36,10 @@ exp(double x) int n; int negative = x < 0; + if (__IsNan(x)) { + errno = EDOM; + return x; + } if (x < M_LN_MIN_D) { errno = ERANGE; return 0.0; diff --git a/lang/cem/libcc.ansi/math/ldexp.c b/lang/cem/libcc.ansi/math/ldexp.c index 5ec83a8fd..501dac452 100644 --- a/lang/cem/libcc.ansi/math/ldexp.c +++ b/lang/cem/libcc.ansi/math/ldexp.c @@ -14,11 +14,19 @@ ldexp(double fl, int exp) int sign = 1; int currexp; + if (__IsNan(fl)) { + errno = EDOM; + return fl; + } if (fl == 0.0) return 0.0; if (fl<0) { fl = -fl; sign = -1; } + if (fl > DBL_MAX) { /* for infinity */ + errno = ERANGE; + return sign * fl; + } fl = frexp(fl,&currexp); exp += currexp; if (exp > 0) { diff --git a/lang/cem/libcc.ansi/math/log.c b/lang/cem/libcc.ansi/math/log.c index 48f77a743..e6a673984 100644 --- a/lang/cem/libcc.ansi/math/log.c +++ b/lang/cem/libcc.ansi/math/log.c @@ -7,6 +7,7 @@ /* $Header$ */ #include +#include #include #include "localmath.h" @@ -32,6 +33,10 @@ log(double x) double znum, zden, z, w; int exponent; + if (__IsNan(x)) { + errno = EDOM; + return x; + } if (x < 0) { errno = EDOM; return -HUGE_VAL; @@ -41,6 +46,9 @@ log(double x) return -HUGE_VAL; } + if (x <= DBL_MAX) { + } + else return x; /* for infinity and Nan */ x = frexp(x, &exponent); if (x > M_1_SQRT2) { znum = (x - 0.5) - 0.5; diff --git a/lang/cem/libcc.ansi/math/log10.c b/lang/cem/libcc.ansi/math/log10.c index 147472201..85e4296e2 100644 --- a/lang/cem/libcc.ansi/math/log10.c +++ b/lang/cem/libcc.ansi/math/log10.c @@ -13,6 +13,10 @@ double log10(double x) { + if (__IsNan(x)) { + errno = EDOM; + return x; + } if (x < 0) { errno = EDOM; return -HUGE_VAL; diff --git a/lang/cem/libcc.ansi/math/sin.c b/lang/cem/libcc.ansi/math/sin.c index cd3d204ff..24f501923 100644 --- a/lang/cem/libcc.ansi/math/sin.c +++ b/lang/cem/libcc.ansi/math/sin.c @@ -7,6 +7,8 @@ /* $Header$ */ #include +#include +#include #include "localmath.h" static double @@ -30,14 +32,18 @@ sinus(double x, int cos_flag) double xsqr; double y; - int neg = 0; + int neg = 1; + if (__IsNan(x)) { + errno = EDOM; + return x; + } if (x < 0) { x = -x; - neg = 1; + neg = -1; } if (cos_flag) { - neg = 0; + neg = 1; y = M_PI_2 + x; } else y = x; @@ -46,6 +52,8 @@ sinus(double x, int cos_flag) y = y * M_1_PI + 0.5; + if (y >= DBL_MAX/M_PI) return 0.0; + /* Use extended precision to calculate reduced argument. Here we used 12 bits of the mantissa for a1. Also split x in integer part x1 and fraction part x2. @@ -56,7 +64,7 @@ sinus(double x, int cos_flag) double x1, x2; modf(y, &y); - if (modf(0.5*y, &x1)) neg = !neg; + if (modf(0.5*y, &x1)) neg = -neg; if (cos_flag) y -= 0.5; x2 = modf(x, &x1); x = x1 - y * A1; @@ -67,7 +75,7 @@ sinus(double x, int cos_flag) } if (x < 0) { - neg = !neg; + neg = -neg; x = -x; } @@ -75,7 +83,7 @@ sinus(double x, int cos_flag) y = x * x; x += x * y * POLYNOM7(y, r); - return neg ? -x : x; + return neg==-1 ? -x : x; } double diff --git a/lang/cem/libcc.ansi/math/sinh.c b/lang/cem/libcc.ansi/math/sinh.c index ccb010e74..356604a52 100644 --- a/lang/cem/libcc.ansi/math/sinh.c +++ b/lang/cem/libcc.ansi/math/sinh.c @@ -34,6 +34,10 @@ sinh_cosh(double x, int cosh_flag) int negative = x < 0; double y = negative ? -x : x; + if (__IsNan(x)) { + errno = EDOM; + return x; + } if (! cosh_flag && y <= 1.0) { /* ??? check for underflow ??? */ y = y * y; diff --git a/lang/cem/libcc.ansi/math/sqrt.c b/lang/cem/libcc.ansi/math/sqrt.c index f41f3aafd..e02638812 100644 --- a/lang/cem/libcc.ansi/math/sqrt.c +++ b/lang/cem/libcc.ansi/math/sqrt.c @@ -7,6 +7,7 @@ /* $Header$ */ #include +#include #include #define NITER 5 @@ -17,11 +18,17 @@ sqrt(double x) int exponent; double val; + if (__IsNan(x)) { + errno = EDOM; + return x; + } if (x <= 0) { if (x < 0) errno = EDOM; return 0; } + if (x > DBL_MAX) return x; /* for infinity */ + val = frexp(x, &exponent); if (exponent & 1) { exponent--; diff --git a/lang/cem/libcc.ansi/math/tan.c b/lang/cem/libcc.ansi/math/tan.c index b125fd99c..809b49a26 100644 --- a/lang/cem/libcc.ansi/math/tan.c +++ b/lang/cem/libcc.ansi/math/tan.c @@ -7,6 +7,8 @@ /* $Header$ */ #include +#include +#include #include "localmath.h" double @@ -34,12 +36,18 @@ tan(double x) 0.49819433993786512270e-6 }; + if (__IsNan(x)) { + errno = EDOM; + return x; + } if (negative) x = -x; /* ??? avoid loss of significance, error if x is too large ??? */ y = x * M_2_PI + 0.5; + if (y >= DBL_MAX/M_PI_2) return 0.0; + /* Use extended precision to calculate reduced argument. Here we used 12 bits of the mantissa for a1. Also split x in integer part x1 and fraction part x2. diff --git a/lang/cem/libcc.ansi/math/tanh.c b/lang/cem/libcc.ansi/math/tanh.c index 636a9df39..ea29c61b6 100644 --- a/lang/cem/libcc.ansi/math/tanh.c +++ b/lang/cem/libcc.ansi/math/tanh.c @@ -8,6 +8,7 @@ #include #include +#include #include "localmath.h" double @@ -31,6 +32,10 @@ tanh(double x) }; int negative = x < 0; + if (__IsNan(x)) { + errno = EDOM; + return x; + } if (negative) x = -x; if (x >= 0.5*M_LN_MAX_D) { -- 2.34.1