Fixed conversion overflows in tests
Minor tidying-up, added comments about casting for bitwise operations.
This commit is contained in:
@@ -45,6 +45,7 @@ epicsShareFunc long
|
||||
double *ptop; /* stack pointer */
|
||||
double top; /* value from top of stack */
|
||||
epicsInt32 itop; /* integer from top of stack */
|
||||
epicsUInt32 utop; /* unsigned integer from top of stack */
|
||||
int op;
|
||||
int nargs;
|
||||
|
||||
@@ -262,7 +263,7 @@ epicsShareFunc long
|
||||
|
||||
case NINT:
|
||||
top = *ptop;
|
||||
*ptop = (double)(epicsInt32)(top >= 0 ? top + 0.5 : top - 0.5);
|
||||
*ptop = (epicsInt32) (top >= 0 ? top + 0.5 : top - 0.5);
|
||||
break;
|
||||
|
||||
case RANDOM:
|
||||
@@ -283,34 +284,45 @@ epicsShareFunc long
|
||||
*ptop = ! *ptop;
|
||||
break;
|
||||
|
||||
/* For bitwise operations on values with bit 31 set, double values
|
||||
* must first be cast to unsigned to correctly set that bit; the
|
||||
* double value must be negative in that case. The result must be
|
||||
* cast to a signed integer before converting to the double result.
|
||||
*/
|
||||
|
||||
case BIT_OR:
|
||||
itop = (epicsUInt32) *ptop--;
|
||||
*ptop = (epicsInt32) ((epicsUInt32)*ptop | itop);
|
||||
utop = *ptop--;
|
||||
*ptop = (epicsInt32) ((epicsUInt32) *ptop | utop);
|
||||
break;
|
||||
|
||||
case BIT_AND:
|
||||
itop = (epicsUInt32) *ptop--;
|
||||
*ptop = (epicsInt32) ((epicsUInt32) *ptop & itop);
|
||||
utop = *ptop--;
|
||||
*ptop = (epicsInt32) ((epicsUInt32) *ptop & utop);
|
||||
break;
|
||||
|
||||
case BIT_EXCL_OR:
|
||||
itop = (epicsUInt32) *ptop--;
|
||||
*ptop = (epicsInt32) ((epicsUInt32) *ptop ^ itop);
|
||||
utop = *ptop--;
|
||||
*ptop = (epicsInt32) ((epicsUInt32) *ptop ^ utop);
|
||||
break;
|
||||
|
||||
case BIT_NOT:
|
||||
itop = (epicsUInt32) *ptop;
|
||||
*ptop = ~itop;
|
||||
utop = *ptop;
|
||||
*ptop = (epicsInt32) ~utop;
|
||||
break;
|
||||
|
||||
/* The shift operators use signed integers, so a right-shift will
|
||||
* extend the sign bit into the left-hand end of the value. The
|
||||
* double-casting through unsigned here is important, see above.
|
||||
*/
|
||||
|
||||
case RIGHT_SHIFT:
|
||||
itop = (epicsInt32) *ptop--;
|
||||
*ptop = (epicsInt32) (epicsUInt32) *ptop >> itop;
|
||||
utop = *ptop--;
|
||||
*ptop = ((epicsInt32) (epicsUInt32) *ptop) >> (utop & 31);
|
||||
break;
|
||||
|
||||
case LEFT_SHIFT:
|
||||
itop = (epicsInt32) *ptop--;
|
||||
*ptop = (epicsInt32) ((epicsUInt32) *ptop << itop);
|
||||
utop = *ptop--;
|
||||
*ptop = ((epicsInt32) (epicsUInt32) *ptop) << (utop & 31);
|
||||
break;
|
||||
|
||||
case NOT_EQ:
|
||||
|
||||
@@ -602,13 +602,13 @@ epicsShareFunc void
|
||||
while ((op = *pinst) != END_EXPRESSION) {
|
||||
switch (op) {
|
||||
case LITERAL_DOUBLE:
|
||||
memcpy(&lit_d, ++pinst, sizeof(double));
|
||||
memcpy(&lit_d, ++pinst, sizeof(double));
|
||||
printf("\tDouble %g\n", lit_d);
|
||||
pinst += sizeof(double);
|
||||
break;
|
||||
case LITERAL_INT:
|
||||
memcpy(&lit_i, ++pinst, sizeof(epicsInt32));
|
||||
printf("\tInteger %d (0x%x)\n", lit_i, lit_i);
|
||||
memcpy(&lit_i, ++pinst, sizeof(epicsInt32));
|
||||
printf("\tInteger %d (0x%x)\n", lit_i, lit_i);
|
||||
pinst += sizeof(int);
|
||||
break;
|
||||
case MIN:
|
||||
|
||||
@@ -64,7 +64,6 @@ void testCalc(const char *expr, double expected) {
|
||||
testDiag("Expected result is %g, actually got %g", expected, result);
|
||||
calcExprDump(rpn);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void testUInt32Calc(const char *expr, epicsUInt32 expected) {
|
||||
@@ -93,7 +92,6 @@ void testUInt32Calc(const char *expr, epicsUInt32 expected) {
|
||||
expected, expected, uresult, uresult);
|
||||
calcExprDump(rpn);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void testArgs(const char *expr, unsigned long einp, unsigned long eout) {
|
||||
@@ -931,16 +929,16 @@ MAIN(epicsCalcTest)
|
||||
testUInt32Calc("a:=0xaaaaaaaa; ~~a", 0xaaaaaaaau);
|
||||
testUInt32Calc("a:=0xaaaaaaaa; a >> 8", 0xffaaaaaau);
|
||||
testUInt32Calc("a:=0xaaaaaaaa; a << 8", 0xaaaaaa00u);
|
||||
// using double operands (what the calc record does)
|
||||
// 0xaaaaaaaa = 2863311530.0
|
||||
// 0xffff0000 = 4294901760.0
|
||||
testUInt32Calc("a:=2863311530.0; b:=4294901760.0; a AND b", 0xaaaa0000u);
|
||||
testUInt32Calc("a:=2863311530.0; b:=4294901760.0; a OR b", 0xffffaaaau);
|
||||
testUInt32Calc("a:=2863311530.0; b:=4294901760.0; a XOR b", 0x5555aaaau);
|
||||
testUInt32Calc("a:=2863311530.0; ~a", 0x55555555u);
|
||||
testUInt32Calc("a:=2863311530.0; ~~a", 0xaaaaaaaau);
|
||||
testUInt32Calc("a:=2863311530.0; a >> 8", 0xffaaaaaau);
|
||||
testUInt32Calc("a:=2863311530.0; a << 8", 0xaaaaaa00u);
|
||||
// using double operands (add 0.1 to force as double)
|
||||
// 0xaaaaaaaa = -1431655766
|
||||
// 0xffff0000 = -65536
|
||||
testUInt32Calc("a:=-1431655766.1; b:=-65536.1; a AND b", 0xaaaa0000u);
|
||||
testUInt32Calc("a:=-1431655766.1; b:=-65536.1; a OR b", 0xffffaaaau);
|
||||
testUInt32Calc("a:=-1431655766.1; b:=-65536.1; a XOR b", 0x5555aaaau);
|
||||
testUInt32Calc("a:=-1431655766.1; ~a", 0x55555555u);
|
||||
testUInt32Calc("a:=-1431655766.1; ~~a", 0xaaaaaaaau);
|
||||
testUInt32Calc("a:=-1431655766.1; a >> 8", 0xffaaaaaau);
|
||||
testUInt32Calc("a:=-1431655766.1; a << 8", 0xaaaaaa00u);
|
||||
|
||||
return testDone();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user