From 373efa085dcea5fe6b4539cd875b6bd8645f16fa Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Sun, 13 May 2018 10:02:01 +0200 Subject: 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 --- Src/Modules/mathfunc.c | 43 ------------------------------------------- 1 file changed, 43 deletions(-) (limited to 'Src/Modules/mathfunc.c') diff --git a/Src/Modules/mathfunc.c b/Src/Modules/mathfunc.c index a7e8b294c..a62154c50 100644 --- a/Src/Modules/mathfunc.c +++ b/Src/Modules/mathfunc.c @@ -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; -- cgit v1.2.3 From a93abe1170a438d45d94b3a7f924553f5cf69cee Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Sun, 13 May 2018 10:13:42 +0200 Subject: 42488: test cases for 42369 and address some issues in the code --- ChangeLog | 4 ++++ Src/Modules/mathfunc.c | 51 +++++++++++++++++--------------------------------- Src/builtin.c | 10 ++++++++-- Src/math.c | 37 ++++++++++++++++++------------------ Test/B03print.ztst | 11 +++++++++++ Test/C01arith.ztst | 34 +++++++++++++++++++++++++++++++++ Test/V03mathfunc.ztst | 4 ++-- 7 files changed, 95 insertions(+), 56 deletions(-) (limited to 'Src/Modules/mathfunc.c') diff --git a/ChangeLog b/ChangeLog index 7d0c66bd1..50a32653d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2018-05-13 Oliver Kiddle + * 42488: Src/Modules/mathfunc.c, Src/builtin.c, Src/math.c, + Test/B03print.ztst, Test/C01arith.ztst, Test/V03mathfunc.ztst: + test cases for 42369 and address some issues in the code + * 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 diff --git a/Src/Modules/mathfunc.c b/Src/Modules/mathfunc.c index a62154c50..01a2913ef 100644 --- a/Src/Modules/mathfunc.c +++ b/Src/Modules/mathfunc.c @@ -93,22 +93,6 @@ MS_RAND48 * conversion), atan2. */ -/* Flags for bounds. Note these must start at 1, not 0. */ - -enum { - BF_POS = 1, /* must be positive */ - BF_NONNEG = 2, /* must be non-negative */ - BF_FRAC = 3, /* must be -1 <= x <= 1 */ - BF_GE1 = 4, /* must be >= 1 */ - BF_FRACO = 5, /* must be in open range -1 < x < 1 */ - BF_INTPOS = 6, /* must be non-integer or positive */ - BF_GTRM1 = 7, /* must be > -1 */ - BF_NONZ = 8, /* must be nonzero */ - BF_POS2 = 9 /* second argument must be positive */ -}; - -#define BFLAG(x) ((x) << 8) - /* * Flags for type of function: unlike the above, these must * be individually bit-testable. @@ -121,18 +105,18 @@ enum { TF_NOASS = 8 /* don't assign result as double */ }; -#define TFLAG(x) ((x) << 16) +#define TFLAG(x) ((x) << 8) static struct mathfunc mftab[] = { - NUMMATHFUNC("abs", math_func, 1, 1, MF_ABS | BFLAG(BF_FRAC) | + NUMMATHFUNC("abs", math_func, 1, 1, MF_ABS | TFLAG(TF_NOCONV|TF_NOASS)), - NUMMATHFUNC("acos", math_func, 1, 1, MF_ACOS | BFLAG(BF_FRAC)), - NUMMATHFUNC("acosh", math_func, 1, 1, MF_ACOSH | BFLAG(BF_GE1)), - NUMMATHFUNC("asin", math_func, 1, 1, MF_ASIN | BFLAG(BF_FRAC)), + NUMMATHFUNC("acos", math_func, 1, 1, MF_ACOS), + NUMMATHFUNC("acosh", math_func, 1, 1, MF_ACOSH), + NUMMATHFUNC("asin", math_func, 1, 1, MF_ASIN), NUMMATHFUNC("asinh", math_func, 1, 1, MF_ASINH), NUMMATHFUNC("atan", math_func, 1, 2, MF_ATAN), - NUMMATHFUNC("atanh", math_func, 1, 1, MF_ATANH | BFLAG(BF_FRACO)), + NUMMATHFUNC("atanh", math_func, 1, 1, MF_ATANH), NUMMATHFUNC("cbrt", math_func, 1, 1, MF_CBRT), NUMMATHFUNC("ceil", math_func, 1, 1, MF_CEIL), NUMMATHFUNC("copysign", math_func, 2, 2, MF_COPYSIGN), @@ -146,20 +130,19 @@ static struct mathfunc mftab[] = { NUMMATHFUNC("float", math_func, 1, 1, MF_FLOAT), NUMMATHFUNC("floor", math_func, 1, 1, MF_FLOOR), NUMMATHFUNC("fmod", math_func, 2, 2, MF_FMOD), - NUMMATHFUNC("gamma", math_func, 1, 1, MF_GAMMA | BFLAG(BF_INTPOS)), + NUMMATHFUNC("gamma", math_func, 1, 1, MF_GAMMA), NUMMATHFUNC("hypot", math_func, 2, 2, MF_HYPOT), - NUMMATHFUNC("ilogb", math_func, 1, 1, MF_ILOGB | BFLAG(BF_NONZ) | - TFLAG(TF_NOASS)), + NUMMATHFUNC("ilogb", math_func, 1, 1, MF_ILOGB | TFLAG(TF_NOASS)), NUMMATHFUNC("int", math_func, 1, 1, MF_INT | TFLAG(TF_NOASS)), NUMMATHFUNC("j0", math_func, 1, 1, MF_J0), NUMMATHFUNC("j1", math_func, 1, 1, MF_J1), NUMMATHFUNC("jn", math_func, 2, 2, MF_JN | TFLAG(TF_INT1)), NUMMATHFUNC("ldexp", math_func, 2, 2, MF_LDEXP | TFLAG(TF_INT2)), - NUMMATHFUNC("lgamma", math_func, 1, 1, MF_LGAMMA | BFLAG(BF_INTPOS)), - NUMMATHFUNC("log", math_func, 1, 1, MF_LOG | BFLAG(BF_POS)), - NUMMATHFUNC("log10", math_func, 1, 1, MF_LOG10 | BFLAG(BF_POS)), - NUMMATHFUNC("log1p", math_func, 1, 1, MF_LOG1P | BFLAG(BF_GTRM1)), - NUMMATHFUNC("logb", math_func, 1, 1, MF_LOGB | BFLAG(BF_NONZ)), + NUMMATHFUNC("lgamma", math_func, 1, 1, MF_LGAMMA), + NUMMATHFUNC("log", math_func, 1, 1, MF_LOG), + NUMMATHFUNC("log10", math_func, 1, 1, MF_LOG10), + NUMMATHFUNC("log1p", math_func, 1, 1, MF_LOG1P), + NUMMATHFUNC("logb", math_func, 1, 1, MF_LOGB), NUMMATHFUNC("nextafter", math_func, 2, 2, MF_NEXTAFTER), #ifdef HAVE_ERAND48 STRMATHFUNC("rand48", math_string, MS_RAND48), @@ -171,12 +154,12 @@ static struct mathfunc mftab[] = { #endif NUMMATHFUNC("sin", math_func, 1, 1, MF_SIN), NUMMATHFUNC("sinh", math_func, 1, 1, MF_SINH), - NUMMATHFUNC("sqrt", math_func, 1, 1, MF_SQRT | BFLAG(BF_NONNEG)), + NUMMATHFUNC("sqrt", math_func, 1, 1, MF_SQRT), NUMMATHFUNC("tan", math_func, 1, 1, MF_TAN), NUMMATHFUNC("tanh", math_func, 1, 1, MF_TANH), - NUMMATHFUNC("y0", math_func, 1, 1, MF_Y0 | BFLAG(BF_POS)), - NUMMATHFUNC("y1", math_func, 1, 1, MF_Y1 | BFLAG(BF_POS)), - NUMMATHFUNC("yn", math_func, 2, 2, MF_YN | BFLAG(BF_POS2) | TFLAG(TF_INT1)) + NUMMATHFUNC("y0", math_func, 1, 1, MF_Y0), + NUMMATHFUNC("y1", math_func, 1, 1, MF_Y1), + NUMMATHFUNC("yn", math_func, 2, 2, MF_YN | TFLAG(TF_INT1)) }; /**/ diff --git a/Src/builtin.c b/Src/builtin.c index 73cfe7ad1..931605c6e 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -5234,8 +5234,14 @@ bin_print(char *name, char **args, Options ops, int func) errflag &= ~ERRFLAG_ERROR; ret = 1; } - print_val(doubleval) - break; + /* force consistent form for Inf/NaN output */ + if (isnan(doubleval)) + count += fputs("nan", fout); + else if (isinf(doubleval)) + count += fputs((doubleval < 0.0) ? "-inf" : "inf", fout); + else + print_val(doubleval) + break; case 3: #ifdef ZSH_64_BIT_UTYPE *d++ = 'l'; diff --git a/Src/math.c b/Src/math.c index cdfe80bb4..32bccc6e9 100644 --- a/Src/math.c +++ b/Src/math.c @@ -593,7 +593,6 @@ isinf(double x) #endif #if !defined(HAVE_ISNAN) -/**/ static double store(double *x) { @@ -816,27 +815,11 @@ zzlex(void) ptr++; break; } - case ' ': + case ' ': /* Fall through! */ case '\t': case '\n': 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 == '#') { @@ -860,6 +843,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; @@ -1114,6 +1111,10 @@ callmathfunc(char *o) static int notzero(mnumber a) { + if ((a.type & MN_INTEGER) && a.u.l == 0) { + zerr("division by zero"); + return 0; + } return 1; } diff --git a/Test/B03print.ztst b/Test/B03print.ztst index c65568ad9..0ef3743ce 100644 --- a/Test/B03print.ztst +++ b/Test/B03print.ztst @@ -86,6 +86,17 @@ >123.45 678 >90.1 0 + nan=0 inf=1 Infinity=2 + printf '%.1f\n' -inf Infinity Inf nan NaN -Inf -0.0 +0:infinity constants +>-inf +>inf +>inf +>nan +>nan +>-inf +>-0.0 + print -f 'arg: %b\n' -C2 '\x41' '\x42' '\x43' 0:override -C when -f was given >arg: A diff --git a/Test/C01arith.ztst b/Test/C01arith.ztst index 30409adf3..77a46ebd5 100644 --- a/Test/C01arith.ztst +++ b/Test/C01arith.ztst @@ -302,6 +302,40 @@ ?(eval):1: bad math expression: operator expected at `2 ' # ` for emacs shell mode + in=1 info=2 Infinity=3 Inf=4 + print $(( in )) $(( info )) $(( Infinity )) $(( $Inf )) $(( inf )) $(( INF )) $(( Inf )) $(( iNF )) +0:Infinity parsing +>1 2 3 4 Inf Inf Inf Inf + + integer Inf + print $(( Inf[0] )) +1:Refer to Inf with an array subscript +?(eval):2: bad base syntax + + (( NaN = 1 )) +2:Assign to NaN +?(eval):1: bad math expression: lvalue required + + a='Inf' + (( b = 1e500 )) + print $((1e500)) $(($((1e500)))) $(( a )) $b $(( b )) $(( 3.0 / 0 )) +0:Overflow to infinity +>Inf Inf Inf Inf Inf Inf + + print $((1e500)) + print $(( $((1e500)) )) +0:Reinput infinity value into math context +>Inf +>Inf + + print $((1e500/1e500)) $((-1e500/1e500)) $(( 24. % 0 )) +0:NaN results +>NaN NaN NaN + + (( 3 / 0 )) +2:Integer division by zero +?(eval):1: division by zero + integer varassi print $(( varassi = 5.5 / 2.0 )) print $varassi diff --git a/Test/V03mathfunc.ztst b/Test/V03mathfunc.ztst index 1edb7a279..d6b4e0987 100644 --- a/Test/V03mathfunc.ztst +++ b/Test/V03mathfunc.ztst @@ -100,8 +100,8 @@ F:This test fails if your math library doesn't have erand48(). >1.50000 print $(( sqrt(-1) )) -1:Non-negative argument checking for square roots. -?(eval):1: math: argument to sqrt out of range +0:Non-negative argument checking for square roots. +>NaN # Simple test that the pseudorandom number generators are producing # something that could conceivably be pseudorandom numbers in a -- cgit v1.2.3 From 96ec8cbbf4b115bac0f3468beacae40e017541d8 Mon Sep 17 00:00:00 2001 From: Eitan Adler Date: Wed, 6 Jun 2018 05:59:58 +0000 Subject: 42938: name argument to math_func is not unused --- ChangeLog | 3 +++ Src/Modules/mathfunc.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'Src/Modules/mathfunc.c') diff --git a/ChangeLog b/ChangeLog index 500ba10bd..9de7d953b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2018-06-06 Peter Stephenson + * Eitan: 42938: Src/Modules/mathfunc.c: name argument to + math_func is not unused. + * Eitan: 42939: Src/Zle/zle_params.c: pm argument to set_registers is not unused. diff --git a/Src/Modules/mathfunc.c b/Src/Modules/mathfunc.c index 01a2913ef..d1c3e089a 100644 --- a/Src/Modules/mathfunc.c +++ b/Src/Modules/mathfunc.c @@ -164,7 +164,7 @@ static struct mathfunc mftab[] = { /**/ static mnumber -math_func(char *name, int argc, mnumber *argv, int id) +math_func(UNUSED(char *name), int argc, mnumber *argv, int id) { mnumber ret; double argd = 0, argd2 = 0, retd = 0; -- cgit v1.2.3 From b21a641d4c63fce45736b635314e079ae360e5b2 Mon Sep 17 00:00:00 2001 From: dana Date: Sun, 12 Aug 2018 03:20:37 -0500 Subject: 43275: Add log2 to match func --- ChangeLog | 5 +++++ Doc/Zsh/mod_mathfunc.yo | 6 +++--- Src/Modules/mathfunc.c | 10 ++++++++++ Test/V03mathfunc.ztst | 6 ++++++ configure.ac | 1 + 5 files changed, 25 insertions(+), 3 deletions(-) (limited to 'Src/Modules/mathfunc.c') diff --git a/ChangeLog b/ChangeLog index 110f8636d..c5ffd0b7c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2018-08-13 Peter Stephenson + + * dana: 43275: Doc/Zsh/mod_mathfunc.yo, Src/Modules/mathfunc.c, + Test/V03mathfunc.ztst, configure.ac: Add log2 to mathfunc. + 2018-08-12 Marc Cornellà * unposted (PR #26): Completion/Unix/Command/_git: __git_files: diff --git a/Doc/Zsh/mod_mathfunc.yo b/Doc/Zsh/mod_mathfunc.yo index 8b72de3ab..428a5be47 100644 --- a/Doc/Zsh/mod_mathfunc.yo +++ b/Doc/Zsh/mod_mathfunc.yo @@ -24,9 +24,9 @@ The following functions take a single floating point argument: tt(acos), tt(acosh), tt(asin), tt(asinh), tt(atan), tt(atanh), tt(cbrt), tt(ceil), tt(cos), tt(cosh), tt(erf), tt(erfc), tt(exp), tt(expm1), tt(fabs), tt(floor), tt(gamma), tt(j0), tt(j1), tt(lgamma), tt(log), tt(log10), -tt(log1p), tt(logb), tt(sin), tt(sinh), tt(sqrt), tt(tan), tt(tanh), -tt(y0), tt(y1). The tt(atan) function can optionally take a second -argument, in which case it behaves like the C function tt(atan2). +tt(log1p), tt(log2), tt(logb), tt(sin), tt(sinh), tt(sqrt), tt(tan), +tt(tanh), tt(y0), tt(y1). The tt(atan) function can optionally take a +second argument, in which case it behaves like the C function tt(atan2). The tt(ilogb) function takes a single floating point argument, but returns an integer. diff --git a/Src/Modules/mathfunc.c b/Src/Modules/mathfunc.c index d1c3e089a..fc2593dca 100644 --- a/Src/Modules/mathfunc.c +++ b/Src/Modules/mathfunc.c @@ -65,6 +65,7 @@ MF_LGAMMA, MF_LOG, MF_LOG10, MF_LOG1P, +MF_LOG2, MF_LOGB, MF_NEXTAFTER, MF_RINT, @@ -142,6 +143,7 @@ static struct mathfunc mftab[] = { NUMMATHFUNC("log", math_func, 1, 1, MF_LOG), NUMMATHFUNC("log10", math_func, 1, 1, MF_LOG10), NUMMATHFUNC("log1p", math_func, 1, 1, MF_LOG1P), + NUMMATHFUNC("log2", math_func, 1, 1, MF_LOG2), NUMMATHFUNC("logb", math_func, 1, 1, MF_LOGB), NUMMATHFUNC("nextafter", math_func, 2, 2, MF_NEXTAFTER), #ifdef HAVE_ERAND48 @@ -338,6 +340,14 @@ math_func(UNUSED(char *name), int argc, mnumber *argv, int id) retd = log1p(argd); break; + case MF_LOG2: +#ifdef HAVE_LOG2 + retd = log2(argd); +#else + retd = log(argd) / log(2); +#endif + break; + case MF_LOGB: retd = logb(argd); break; diff --git a/Test/V03mathfunc.ztst b/Test/V03mathfunc.ztst index d6b4e0987..9a297d69d 100644 --- a/Test/V03mathfunc.ztst +++ b/Test/V03mathfunc.ztst @@ -139,3 +139,9 @@ F:This test fails if your math library doesn't have erand48(). print $g, $l 0:Test Gamma function gamma and lgamma >1.00000, 0.00000 + + float -F 5 a b c + (( a = log2(0.5), b = log2(1.5), c = log2(99) )) + print -r - "$a, $b, $c" +0:log2 +>-1.00000, 0.58496, 6.62936 diff --git a/configure.ac b/configure.ac index 53c30c2cf..5e13c0f11 100644 --- a/configure.ac +++ b/configure.ac @@ -1266,6 +1266,7 @@ AC_CHECK_FUNCS(strftime strptime mktime timelocal \ isblank iswblank \ uname \ signgam tgamma \ + log2 \ scalbn \ putenv getenv setenv unsetenv xw\ brk sbrk \ -- cgit v1.2.3