Fixed conversion overflows in tests

Minor tidying-up, added comments about casting for bitwise operations.
This commit is contained in:
Andrew Johnson
2016-02-19 15:57:44 -06:00
parent 599e6635fb
commit 89e6fdbca0
3 changed files with 38 additions and 28 deletions

View File

@@ -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:

View File

@@ -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:

View File

@@ -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();
}