# Calculations in one step yield the wrong results

44 views

Hello,

i have ran against a strange behaviour in EW 9.00.

What i want to implement: I am implementing a Pin-Entry Screen. To remember on which position the "cursor" is, i have a uint8 variable that should have values in the range of 0 to 3 (4 digit pin). So when moving the cursor, i simply want to calculate "(current_pos + 1)%4" or "(current_pos - 1)%4". That doesn't produce the correct value in a special case:

Minimal Example:

``````// go one position backwards
var uint8 temp = 0;

temp = (temp - 1)%4;
trace "temp =", temp;``````

When at Position "0", the calculated value should be 3. The trace-output yields 255.

When I split the calculation, all works as expected:

``````// go one position backwards
var uint8 temp = 0;

temp = (temp - 1);
trace "temp1 =", temp;
temp = temp % 4;
trace "temp2 =", temp;``````

Trace:

``````temp1 = 255
temp2 = 3``````

It is not good, when setting braces has not the intended result...

Hello,

thank you very much for this report. I have to confirm that it is an error in the evaluation of nested expressions with uint8 (or uint16) operands and modulo % operator. We will investigate the exact reason for this behavior and fix it in the next release. For the moment you have three options to workaround the problem:

option 1: you perform the expression in two steps (you tried out this already).

option 2: Instead of % (modulo) operator you use the bit-wise & operator. This will work because % 4 corresponds to & 3:

``temp = (( temp - 1 ) & 3 );``

option 3: Use uint32 data type for the variable instead of uint8.

I hope one of the options helps you further ...

Best regards

Paul Banach

Hello,

we have analysed the described issue and found that it is not a bug. The results of the calculation are correct. Following are the results of the analysis:

``````(1) var uint8 temp = 0;

(2) temp = (temp - 1)%4;

(3) trace "temp =", temp;``````

a. The expression in row (2) consists of two parts. First the subtraction temp - 1 is evaluated.

b. The operand temp is 0. The result of the operation is thus -1.

c. Similarly to C, arithmetic expressions are automatically promoted to signed integer. The data type of the expression is consequently int32.

d. Then the modulo operation is calculated with -1 as result of the left operand: -1 % 4. This results in -1. Since the left operand was negative, the result is negative too.

e. Again, the data type of the entire resulting expression is promoted to int32.

f. During the assignment to temp in row (2), the int32 value is implicitly casted to uint8 value. Embedded Wizard reports here a warning:

g. The int32 value -1 is represented internally as 0xFFFFFFFF. The cast to uint8 extracts the lower 8-bit. The resulting value is 0x000000FF.

h. The variable contains the value 255.

We compared the behaviour in a simple C example with following code and results. The C compiler produces the same results as Embedded Wizard:

What can you do?

The result of the left operand in the modulo operation has to be unsigned integer. An additional typecast is needed. It converts the negative -1 value to uint8 value 255. Then the modulo operation produces the expected results:

``````var uint8 temp = 0;

temp = uint8( temp - 1 ) % 4;

trace "temp =", temp;``````

I hope it helps you further.

Best regards

Paul Banach