Added variable argument functions, mostly by Benjamin Fransken.
MIN, MAX, FINITE and ISINF can now take any number of arguments.
This commit is contained in:
@@ -1,10 +1,9 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* $Id$ */
|
||||
@@ -44,6 +43,7 @@ epicsShareFunc long
|
||||
double *ptop; /* stack pointer */
|
||||
double top; /* value from top of stack */
|
||||
int itop; /* integer from top of stack */
|
||||
char nargs;
|
||||
|
||||
/* initialize */
|
||||
ptop = stack;
|
||||
@@ -158,15 +158,21 @@ epicsShareFunc long
|
||||
break;
|
||||
|
||||
case MAX:
|
||||
top = *ptop--;
|
||||
if (*ptop < top || isnan(top))
|
||||
*ptop = top;
|
||||
nargs = *++pinst;
|
||||
while (--nargs) {
|
||||
top = *ptop--;
|
||||
if (*ptop < top || isnan(top))
|
||||
*ptop = top;
|
||||
}
|
||||
break;
|
||||
|
||||
case MIN:
|
||||
top = *ptop--;
|
||||
if (*ptop > top || isnan(top))
|
||||
*ptop = top;
|
||||
nargs = *++pinst;
|
||||
while (--nargs) {
|
||||
top = *ptop--;
|
||||
if (*ptop > top || isnan(top))
|
||||
*ptop = top;
|
||||
}
|
||||
break;
|
||||
|
||||
case SQU_RT:
|
||||
@@ -223,7 +229,13 @@ epicsShareFunc long
|
||||
break;
|
||||
|
||||
case FINITE:
|
||||
*ptop = finite(*ptop);
|
||||
nargs = *++pinst;
|
||||
top = finite(*ptop);
|
||||
while (--nargs) {
|
||||
--ptop;
|
||||
top = top && finite(*ptop);
|
||||
}
|
||||
*ptop = top;
|
||||
break;
|
||||
|
||||
case ISINF:
|
||||
@@ -231,7 +243,13 @@ epicsShareFunc long
|
||||
break;
|
||||
|
||||
case ISNAN:
|
||||
*ptop = isnan(*ptop);
|
||||
nargs = *++pinst;
|
||||
top = isnan(*ptop);
|
||||
while (--nargs) {
|
||||
--ptop;
|
||||
top = top || isnan(*ptop);
|
||||
}
|
||||
*ptop = top;
|
||||
break;
|
||||
|
||||
case NINT:
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* $Id$
|
||||
@@ -36,6 +35,7 @@ typedef enum {
|
||||
LITERAL_OPERAND,
|
||||
STORE_OPERATOR,
|
||||
UNARY_OPERATOR,
|
||||
VARARG_OPERATOR,
|
||||
BINARY_OPERATOR,
|
||||
SEPERATOR,
|
||||
CLOSE_PAREN,
|
||||
@@ -61,6 +61,8 @@ typedef struct expression_element{
|
||||
* NOTE: Keep these lists sorted. Elements are searched in reverse order,
|
||||
* and where two names start with the same substring we must pick out the
|
||||
* longest name first (hence the sort requirement).
|
||||
* NOTE: All VARARG_OPERATORs have to be made known to the calcExprDump()
|
||||
* routine at the end of this file.
|
||||
*/
|
||||
static const ELEMENT operands[] = {
|
||||
/* name prio's stack element type opcode */
|
||||
@@ -94,22 +96,22 @@ static const ELEMENT operands[] = {
|
||||
{"E", 0, 0, 1, OPERAND, FETCH_E},
|
||||
{"EXP", 7, 8, 0, UNARY_OPERATOR, EXP},
|
||||
{"F", 0, 0, 1, OPERAND, FETCH_F},
|
||||
{"FINITE", 7, 8, 0, UNARY_OPERATOR, FINITE},
|
||||
{"FINITE", 7, 8, 0, VARARG_OPERATOR,FINITE},
|
||||
{"FLOOR", 7, 8, 0, UNARY_OPERATOR, FLOOR},
|
||||
{"G", 0, 0, 1, OPERAND, FETCH_G},
|
||||
{"H", 0, 0, 1, OPERAND, FETCH_H},
|
||||
{"I", 0, 0, 1, OPERAND, FETCH_I},
|
||||
{"INF", 0, 0, 1, LITERAL_OPERAND,LITERAL},
|
||||
{"ISINF", 7, 8, 0, UNARY_OPERATOR, ISINF},
|
||||
{"ISNAN", 7, 8, 0, UNARY_OPERATOR, ISNAN},
|
||||
{"ISNAN", 7, 8, 0, VARARG_OPERATOR,ISNAN},
|
||||
{"J", 0, 0, 1, OPERAND, FETCH_J},
|
||||
{"K", 0, 0, 1, OPERAND, FETCH_K},
|
||||
{"L", 0, 0, 1, OPERAND, FETCH_L},
|
||||
{"LN", 7, 8, 0, UNARY_OPERATOR, LOG_E},
|
||||
{"LOG", 7, 8, 0, UNARY_OPERATOR, LOG_10},
|
||||
{"LOGE", 7, 8, 0, UNARY_OPERATOR, LOG_E},
|
||||
{"MAX", 7, 8, -1, UNARY_OPERATOR, MAX},
|
||||
{"MIN", 7, 8, -1, UNARY_OPERATOR, MIN},
|
||||
{"MAX", 7, 8, 0, VARARG_OPERATOR,MAX},
|
||||
{"MIN", 7, 8, 0, VARARG_OPERATOR,MIN},
|
||||
{"NINT", 7, 8, 0, UNARY_OPERATOR, NINT},
|
||||
{"NAN", 0, 0, 1, LITERAL_OPERAND,LITERAL},
|
||||
{"NOT", 7, 8, 0, UNARY_OPERATOR, BIT_NOT},
|
||||
@@ -264,10 +266,14 @@ epicsShareFunc long
|
||||
break;
|
||||
|
||||
case UNARY_OPERATOR:
|
||||
case VARARG_OPERATOR:
|
||||
/* Move operators of >= priority to the output */
|
||||
while ((pstacktop > stack) &&
|
||||
(pstacktop->in_stack_pri >= pel->in_coming_pri)) {
|
||||
*pout++ = pstacktop->code;
|
||||
if (pstacktop->type == VARARG_OPERATOR) {
|
||||
*pout++ = 1 - pstacktop->runtime_effect;
|
||||
}
|
||||
runtime_depth += pstacktop->runtime_effect;
|
||||
pstacktop--;
|
||||
}
|
||||
@@ -282,6 +288,9 @@ epicsShareFunc long
|
||||
while ((pstacktop > stack) &&
|
||||
(pstacktop->in_stack_pri >= pel->in_coming_pri)) {
|
||||
*pout++ = pstacktop->code;
|
||||
if (pstacktop->type == VARARG_OPERATOR) {
|
||||
*pout++ = 1 - pstacktop->runtime_effect;
|
||||
}
|
||||
runtime_depth += pstacktop->runtime_effect;
|
||||
pstacktop--;
|
||||
}
|
||||
@@ -301,10 +310,14 @@ epicsShareFunc long
|
||||
goto bad;
|
||||
}
|
||||
*pout++ = pstacktop->code;
|
||||
if (pstacktop->type == VARARG_OPERATOR) {
|
||||
*pout++ = 1 - pstacktop->runtime_effect;
|
||||
}
|
||||
runtime_depth += pstacktop->runtime_effect;
|
||||
pstacktop--;
|
||||
}
|
||||
operand_needed = TRUE;
|
||||
pstacktop->runtime_effect -= 1;
|
||||
break;
|
||||
|
||||
case CLOSE_PAREN:
|
||||
@@ -315,10 +328,23 @@ epicsShareFunc long
|
||||
goto bad;
|
||||
}
|
||||
*pout++ = pstacktop->code;
|
||||
if (pstacktop->type == VARARG_OPERATOR) {
|
||||
*pout++ = 1 - pstacktop->runtime_effect;
|
||||
}
|
||||
runtime_depth += pstacktop->runtime_effect;
|
||||
pstacktop--;
|
||||
}
|
||||
pstacktop--; /* remove ( from stack */
|
||||
/* if there is a vararg operator before the opening paren,
|
||||
it inherits the (opening) paren's stack effect */
|
||||
if (pstacktop->type == VARARG_OPERATOR) {
|
||||
pstacktop->runtime_effect = (pstacktop+1)->runtime_effect;
|
||||
/* check for no arguments */
|
||||
if (pstacktop->runtime_effect > 0) {
|
||||
*perror = CALC_ERR_INCOMPLETE;
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CONDITIONAL:
|
||||
@@ -326,6 +352,9 @@ epicsShareFunc long
|
||||
while ((pstacktop > stack) &&
|
||||
(pstacktop->in_stack_pri > pel->in_coming_pri)) {
|
||||
*pout++ = pstacktop->code;
|
||||
if (pstacktop->type == VARARG_OPERATOR) {
|
||||
*pout++ = 1 - pstacktop->runtime_effect;
|
||||
}
|
||||
runtime_depth += pstacktop->runtime_effect;
|
||||
pstacktop--;
|
||||
}
|
||||
@@ -359,6 +388,9 @@ epicsShareFunc long
|
||||
goto bad;
|
||||
}
|
||||
*pout++ = pstacktop->code;
|
||||
if (pstacktop->type == VARARG_OPERATOR) {
|
||||
*pout++ = 1 - pstacktop->runtime_effect;
|
||||
}
|
||||
runtime_depth += pstacktop->runtime_effect;
|
||||
pstacktop--;
|
||||
}
|
||||
@@ -402,6 +434,9 @@ epicsShareFunc long
|
||||
goto bad;
|
||||
}
|
||||
*pout++ = pstacktop->code;
|
||||
if (pstacktop->type == VARARG_OPERATOR) {
|
||||
*pout++ = 1 - pstacktop->runtime_effect;
|
||||
}
|
||||
runtime_depth += pstacktop->runtime_effect;
|
||||
pstacktop--;
|
||||
}
|
||||
@@ -463,7 +498,7 @@ epicsShareFunc void
|
||||
static const char *opcodes[] = {
|
||||
"End Expression",
|
||||
/* Operands */
|
||||
"LITERAL",
|
||||
"LITERAL", "VAL",
|
||||
"FETCH_A", "FETCH_B", "FETCH_C", "FETCH_D", "FETCH_E", "FETCH_F",
|
||||
"FETCH_G", "FETCH_H", "FETCH_I", "FETCH_J", "FETCH_K", "FETCH_L",
|
||||
/* Assignment */
|
||||
@@ -534,13 +569,23 @@ epicsShareFunc void
|
||||
"NOT_GENERATED"
|
||||
};
|
||||
char op;
|
||||
double lit;
|
||||
|
||||
while ((op = *pinst) != END_EXPRESSION) {
|
||||
if (op == LITERAL) {
|
||||
double lit;
|
||||
switch (op) {
|
||||
case LITERAL:
|
||||
memcpy((void *)&lit, ++pinst, sizeof(double));
|
||||
printf("\tLiteral: %g\n", lit);
|
||||
pinst += sizeof(double);
|
||||
} else {
|
||||
break;
|
||||
case MIN:
|
||||
case MAX:
|
||||
case FINITE:
|
||||
case ISNAN:
|
||||
printf("\t%s, %d arg(s)\n", opcodes[(int) op], *++pinst);
|
||||
pinst++;
|
||||
break;
|
||||
default:
|
||||
printf("\t%s\n", opcodes[(int) op]);
|
||||
pinst++;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne
|
||||
* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
@@ -66,6 +66,20 @@ void testCalc(const char *expr, double expected) {
|
||||
return;
|
||||
}
|
||||
|
||||
void testBadExpr(const char *expr, short expected_err) {
|
||||
/* Parse an invalid expression, test against expected error code */
|
||||
char rpn[MAX_POSTFIX_SIZE];
|
||||
short err = 0;
|
||||
|
||||
postfix(expr, rpn, &err);
|
||||
if (!testOk(err == expected_err, "%s (bad expression)", expr)) {
|
||||
testDiag("Expected '%s', actually got '%s'",
|
||||
calcErrorStr(expected_err), calcErrorStr(err));
|
||||
calcExprDump(rpn);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Test an expression that is also valid C code */
|
||||
#define testExpr(expr) testCalc(#expr, expr);
|
||||
|
||||
@@ -83,13 +97,98 @@ void testCalc(const char *expr, double expected) {
|
||||
#define LN(x) log(x)
|
||||
#define LOG(x) log10(x)
|
||||
#define LOGE(x) log(x)
|
||||
#define MAX(a,b) epicsMax(a,b)
|
||||
#define MIN(a,b) epicsMin(a,b)
|
||||
#define NINT(x) (double)(long)((x) >= 0 ? (x)+0.5 : (x)-0.5)
|
||||
#define OR |
|
||||
#define SQR(x) sqrt(x)
|
||||
#define XOR ^
|
||||
|
||||
static inline double MAX(double a) {
|
||||
return a;
|
||||
}
|
||||
static inline double MAX(double a, double b) {
|
||||
return epicsMax(a,b);
|
||||
}
|
||||
static inline double MAX(double a, double b, double c) {
|
||||
return MAX(MAX(a,b),c);
|
||||
}
|
||||
static inline double MAX(double a, double b, double c, double d) {
|
||||
return MAX(MAX(a,b,c),d);
|
||||
}
|
||||
static inline double MAX(double a, double b, double c, double d, double e) {
|
||||
return MAX(MAX(a,b,c,d),e);
|
||||
}
|
||||
static inline double MAX(double a, double b, double c, double d, double e,
|
||||
double f) {
|
||||
return MAX(MAX(a,b,c,d,e),f);
|
||||
}
|
||||
static inline double MAX(double a, double b, double c, double d, double e,
|
||||
double f, double g) {
|
||||
return MAX(MAX(a,b,c,d,e,f),g);
|
||||
}
|
||||
static inline double MAX(double a, double b, double c, double d, double e,
|
||||
double f, double g, double h) {
|
||||
return MAX(MAX(a,b,c,d,e,f,g),h);
|
||||
}
|
||||
static inline double MAX(double a, double b, double c, double d, double e,
|
||||
double f, double g, double h, double i) {
|
||||
return MAX(MAX(a,b,c,d,e,f,g,h),i);
|
||||
}
|
||||
static inline double MAX(double a, double b, double c, double d, double e,
|
||||
double f, double g, double h, double i, double j) {
|
||||
return MAX(MAX(a,b,c,d,e,f,g,h,i),j);
|
||||
}
|
||||
static inline double MAX(double a, double b, double c, double d, double e,
|
||||
double f, double g, double h, double i, double j, double k) {
|
||||
return MAX(MAX(a,b,c,d,e,f,g,h,i,j),k);
|
||||
}
|
||||
static inline double MAX(double a, double b, double c, double d, double e,
|
||||
double f, double g, double h, double i, double j, double k, double l) {
|
||||
return MAX(MAX(a,b,c,d,e,f,g,h,i,j,k),l);
|
||||
}
|
||||
|
||||
static inline double MIN(double a) {
|
||||
return a;
|
||||
}
|
||||
static inline double MIN(double a, double b) {
|
||||
return epicsMin(a,b);
|
||||
}
|
||||
static inline double MIN(double a, double b, double c) {
|
||||
return MIN(MIN(a,b),c);
|
||||
}
|
||||
static inline double MIN(double a, double b, double c, double d) {
|
||||
return MIN(MIN(a,b,c),d);
|
||||
}
|
||||
static inline double MIN(double a, double b, double c, double d, double e) {
|
||||
return MIN(MIN(a,b,c,d),e);
|
||||
}
|
||||
static inline double MIN(double a, double b, double c, double d, double e,
|
||||
double f) {
|
||||
return MIN(MIN(a,b,c,d,e),f);
|
||||
}
|
||||
static inline double MIN(double a, double b, double c, double d, double e,
|
||||
double f, double g) {
|
||||
return MIN(MIN(a,b,c,d,e,f),g);
|
||||
}
|
||||
static inline double MIN(double a, double b, double c, double d, double e,
|
||||
double f, double g, double h) {
|
||||
return MIN(MIN(a,b,c,d,e,f,g),h);
|
||||
}
|
||||
static inline double MIN(double a, double b, double c, double d, double e,
|
||||
double f, double g, double h, double i) {
|
||||
return MIN(MIN(a,b,c,d,e,f,g,h),i);
|
||||
}
|
||||
static inline double MIN(double a, double b, double c, double d, double e,
|
||||
double f, double g, double h, double i, double j) {
|
||||
return MIN(MIN(a,b,c,d,e,f,g,h,i),j);
|
||||
}
|
||||
static inline double MIN(double a, double b, double c, double d, double e,
|
||||
double f, double g, double h, double i, double j, double k) {
|
||||
return MIN(MIN(a,b,c,d,e,f,g,h,i,j),k);
|
||||
}
|
||||
static inline double MIN(double a, double b, double c, double d, double e,
|
||||
double f, double g, double h, double i, double j, double k, double l) {
|
||||
return MIN(MIN(a,b,c,d,e,f,g,h,i,j,k),l);
|
||||
}
|
||||
|
||||
MAIN(epicsCalcTest)
|
||||
{
|
||||
@@ -101,7 +200,7 @@ MAIN(epicsCalcTest)
|
||||
Inf /= NaN;
|
||||
NaN /= NaN;
|
||||
|
||||
testPlan(392);
|
||||
testPlan(532);
|
||||
|
||||
/* LITERAL_OPERAND elements */
|
||||
testExpr(0);
|
||||
@@ -167,10 +266,21 @@ MAIN(epicsCalcTest)
|
||||
testExpr(cosh(0.5));
|
||||
testExpr(exp(1.));
|
||||
testExpr(floor(1.5));
|
||||
|
||||
testExpr(finite(0));
|
||||
testExpr(finite(Inf));
|
||||
testExpr(finite(-Inf));
|
||||
testExpr(finite(NaN));
|
||||
testCalc("finite(0,1,2)", 1);
|
||||
testCalc("finite(0,1,NaN)", 0);
|
||||
testCalc("finite(0,NaN,2)", 0);
|
||||
testCalc("finite(NaN,1,2)", 0);
|
||||
testCalc("finite(0,1,Inf)", 0);
|
||||
testCalc("finite(0,Inf,2)", 0);
|
||||
testCalc("finite(Inf,1,2)", 0);
|
||||
testCalc("finite(0,1,-Inf)", 0);
|
||||
testCalc("finite(0,-Inf,2)", 0);
|
||||
testCalc("finite(-Inf,1,2)", 0);
|
||||
testExpr(isinf(0));
|
||||
testExpr(isinf(Inf));
|
||||
testExpr(isinf(-Inf));
|
||||
@@ -178,20 +288,146 @@ MAIN(epicsCalcTest)
|
||||
testExpr(isnan(0));
|
||||
testExpr(isnan(Inf));
|
||||
testExpr(isnan(NaN));
|
||||
testCalc("isnan(0,1,2)", 0);
|
||||
testCalc("isnan(0,1,NaN)", 1);
|
||||
testCalc("isnan(0,NaN,2)", 1);
|
||||
testCalc("isnan(NaN,1,2)", 1);
|
||||
testCalc("isnan(0,1,-Inf)", 0);
|
||||
testCalc("isnan(0,-Inf,2)", 0);
|
||||
testCalc("isnan(-Inf,1,2)", 0);
|
||||
|
||||
testExpr(LN(5.));
|
||||
testExpr(LOG(5.));
|
||||
testExpr(LOGE(2.));
|
||||
testExpr(MAX(1,2));
|
||||
testExpr(MAX(1.,Inf));
|
||||
testExpr(MAX(1.,-Inf));
|
||||
testExpr(MAX(1.,NaN));
|
||||
testExpr(MAX(NaN,1.));
|
||||
testExpr(MIN(1,2));
|
||||
|
||||
testExpr(MAX(-99));
|
||||
testExpr(MAX( 1., 2.));
|
||||
testExpr(MAX( 1., Inf));
|
||||
testExpr(MAX( 1.,-Inf));
|
||||
testExpr(MAX( 1., NaN));
|
||||
testExpr(MAX( Inf, 1.));
|
||||
testExpr(MAX(-Inf, 1.));
|
||||
testExpr(MAX( NaN, 1.));
|
||||
testExpr(MAX( 1., 2.,3.));
|
||||
testExpr(MAX( 1., 3.,2.));
|
||||
testExpr(MAX( 2., 1.,3.));
|
||||
testExpr(MAX( 2., 3.,1.));
|
||||
testExpr(MAX( 3., 1.,2.));
|
||||
testExpr(MAX( 3., 2.,1.));
|
||||
testExpr(MAX( 1., 2., Inf));
|
||||
testExpr(MAX( 1., 2.,-Inf));
|
||||
testExpr(MAX( 1., 2., NaN));
|
||||
testExpr(MAX( 1., Inf,2.));
|
||||
testExpr(MAX( 1.,-Inf,2.));
|
||||
testExpr(MAX( 1., NaN,2.));
|
||||
testExpr(MAX( Inf, 1.,2.));
|
||||
testExpr(MAX(-Inf, 1.,2.));
|
||||
testExpr(MAX( NaN, 1.,2.));
|
||||
testExpr(MAX( 1., 2., 3., 4.));
|
||||
testExpr(MAX( 1., 2., 4., 3.));
|
||||
testExpr(MAX( 1., 4., 3., 2.));
|
||||
testExpr(MAX( 4., 2., 3., 1.));
|
||||
testExpr(MAX( 1., 2., 3.,NaN));
|
||||
testExpr(MAX( 1., 2.,NaN, 3.));
|
||||
testExpr(MAX( 1.,NaN, 3., 2.));
|
||||
testExpr(MAX(NaN, 2., 3., 1.));
|
||||
testExpr(MAX( 1., 2., 3., 4., 5.));
|
||||
testExpr(MAX( 1., 2., 3., 5., 4.));
|
||||
testExpr(MAX( 1., 2., 5., 4., 3.));
|
||||
testExpr(MAX( 1., 5., 3., 4., 2.));
|
||||
testExpr(MAX( 5., 2., 3., 4., 1.));
|
||||
testExpr(MAX( 1., 2., 3., 4.,NaN));
|
||||
testExpr(MAX( 1., 2., 3.,NaN, 4.));
|
||||
testExpr(MAX( 1., 2.,NaN, 4., 3.));
|
||||
testExpr(MAX( 1.,NaN, 3., 4., 2.));
|
||||
testExpr(MAX(NaN, 2., 3., 4., 1.));
|
||||
testExpr(MAX( 1., 2., 3., 4., 5., 6.));
|
||||
testExpr(MAX( 1., 2., 3., 4., 6., 5.));
|
||||
testExpr(MAX( 1., 2., 3., 6., 5., 4.));
|
||||
testExpr(MAX( 1., 2., 6., 4., 5., 3.));
|
||||
testExpr(MAX( 1., 6., 3., 4., 5., 2.));
|
||||
testExpr(MAX( 6., 2., 3., 4., 5., 1.));
|
||||
testExpr(MAX( 1., 2., 3., 4., 5.,NaN));
|
||||
testExpr(MAX( 1., 2., 3., 4.,NaN, 5.));
|
||||
testExpr(MAX( 1., 2., 3.,NaN, 5., 4.));
|
||||
testExpr(MAX( 1., 2.,NaN, 4., 5., 3.));
|
||||
testExpr(MAX( 1.,NaN, 3., 4., 5., 2.));
|
||||
testExpr(MAX(NaN, 2., 3., 4., 5., 1.));
|
||||
testExpr(MAX( 1., 2., 3., 4., 5.,Inf));
|
||||
testExpr(MAX( 1., 2., 3., 4.,Inf, 5.));
|
||||
testExpr(MAX( 1., 2., 3.,Inf, 5., 4.));
|
||||
testExpr(MAX( 1., 2.,Inf, 4., 5., 3.));
|
||||
testExpr(MAX( 1.,Inf, 3., 4., 5., 2.));
|
||||
testExpr(MAX(Inf, 2., 3., 4., 5., 1.));
|
||||
testExpr(MAX(1,2,3,4,5,6,7,8,9,10));
|
||||
testExpr(MAX(5,4,3,2,1,0,-1,-2,-3,-4));
|
||||
testExpr(MAX(-1,1,0));
|
||||
|
||||
testExpr(MIN(99));
|
||||
testExpr(MIN(1.,2.));
|
||||
testExpr(MIN(1.,Inf));
|
||||
testExpr(MIN(1.,-Inf));
|
||||
testExpr(MIN(1.,NaN));
|
||||
testExpr(MIN(NaN,1.));
|
||||
testExpr(MIN( 1., 2.,3.));
|
||||
testExpr(MIN( 1., 3.,2.));
|
||||
testExpr(MIN( 2., 1.,3.));
|
||||
testExpr(MIN( 2., 3.,1.));
|
||||
testExpr(MIN( 3., 1.,2.));
|
||||
testExpr(MIN( 3., 2.,1.));
|
||||
testExpr(MIN( 1., 2., Inf));
|
||||
testExpr(MIN( 1., 2.,-Inf));
|
||||
testExpr(MIN( 1., 2., NaN));
|
||||
testExpr(MIN( 1., Inf,2.));
|
||||
testExpr(MIN( 1.,-Inf,2.));
|
||||
testExpr(MIN( 1., NaN,2.));
|
||||
testExpr(MIN( Inf, 1.,2.));
|
||||
testExpr(MIN(-Inf, 1.,2.));
|
||||
testExpr(MIN( NaN, 1.,2.));
|
||||
testExpr(MIN( 1., 2., 3., 4.));
|
||||
testExpr(MIN( 1., 2., 4., 3.));
|
||||
testExpr(MIN( 1., 4., 3., 2.));
|
||||
testExpr(MIN( 4., 2., 3., 1.));
|
||||
testExpr(MIN( 1., 2., 3.,NaN));
|
||||
testExpr(MIN( 1., 2.,NaN, 3.));
|
||||
testExpr(MIN( 1.,NaN, 3., 2.));
|
||||
testExpr(MIN(NaN, 2., 3., 1.));
|
||||
testExpr(MIN( 1., 2., 3., 4., 5.));
|
||||
testExpr(MIN( 1., 2., 3., 5., 4.));
|
||||
testExpr(MIN( 1., 2., 5., 4., 3.));
|
||||
testExpr(MIN( 1., 5., 3., 4., 2.));
|
||||
testExpr(MIN( 5., 2., 3., 4., 1.));
|
||||
testExpr(MIN( 1., 2., 3., 4.,NaN));
|
||||
testExpr(MIN( 1., 2., 3.,NaN, 4.));
|
||||
testExpr(MIN( 1., 2.,NaN, 4., 3.));
|
||||
testExpr(MIN( 1.,NaN, 3., 4., 2.));
|
||||
testExpr(MIN(NaN, 2., 3., 4., 1.));
|
||||
testExpr(MIN( 1., 2., 3., 4., 5., 6.));
|
||||
testExpr(MIN( 2., 1., 3., 4., 5., 6.));
|
||||
testExpr(MIN( 3., 2., 1., 4., 5., 6.));
|
||||
testExpr(MIN( 4., 2., 3., 1., 5., 6.));
|
||||
testExpr(MIN( 5., 2., 3., 4., 1., 6.));
|
||||
testExpr(MIN( 6., 2., 3., 4., 5., 1.));
|
||||
testExpr(MIN( 1., 2., 3., 4., 5.,NaN));
|
||||
testExpr(MIN( 1., 2., 3., 4.,NaN, 5.));
|
||||
testExpr(MIN( 1., 2., 3.,NaN, 5., 4.));
|
||||
testExpr(MIN( 1., 2.,NaN, 4., 5., 3.));
|
||||
testExpr(MIN( 1.,NaN, 3., 4., 5., 2.));
|
||||
testExpr(MIN(NaN, 2., 3., 4., 5., 1.));
|
||||
testExpr(MIN( 1., 2., 3., 4., 5.,-Inf));
|
||||
testExpr(MIN( 1., 2., 3., 4.,-Inf, 5.));
|
||||
testExpr(MIN( 1., 2., 3.,-Inf, 5., 4.));
|
||||
testExpr(MIN( 1., 2.,-Inf, 4., 5., 3.));
|
||||
testExpr(MIN( 1.,-Inf, 3., 4., 5., 2.));
|
||||
testExpr(MIN(-Inf, 2., 3., 4., 5., 1.));
|
||||
testExpr(MIN(1,2,3,4,5,6,7,8,9,10));
|
||||
testExpr(MIN(5,4,3,2,1,0,-1,-2,-3,-4));
|
||||
testExpr(MIN(1,-1,0));
|
||||
testExpr(MAX(MIN(0,2),MAX(0),MIN(3,2,1)));
|
||||
|
||||
testExpr(NINT(0.4));
|
||||
testExpr(NINT(0.6));
|
||||
testExpr(NINT(-0.4));
|
||||
testExpr(NINT(-0.6));
|
||||
testExpr(sin(0.5));
|
||||
testExpr(sinh(0.5));
|
||||
@@ -545,6 +781,16 @@ MAIN(epicsCalcTest)
|
||||
testCalc("1+(1|2)**3", 1+pow((double) (1 | 2), 3.));// 8 6
|
||||
testExpr(1+(1?(1<2):(1>2))*2);
|
||||
|
||||
// Malformed expressions
|
||||
testBadExpr("MIN", CALC_ERR_INCOMPLETE);
|
||||
testBadExpr("MIN()", CALC_ERR_SYNTAX);
|
||||
testBadExpr("MIN(A,)", CALC_ERR_SYNTAX);
|
||||
testBadExpr("MIN(A,B,)", CALC_ERR_SYNTAX);
|
||||
testBadExpr("MAX", CALC_ERR_INCOMPLETE);
|
||||
testBadExpr("MAX()", CALC_ERR_SYNTAX);
|
||||
testBadExpr("MAX(A,)", CALC_ERR_SYNTAX);
|
||||
testBadExpr("MAX(A,B,)", CALC_ERR_SYNTAX);
|
||||
|
||||
return testDone();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user