misunderstanding calculation involving modulo

moorea21

Senior Member
I've recently resurected a piece of hardware that uses a picaxe 08m2 to read a light sensor before and after an external operation, place those 2 values into variables b1 and b2, and compare. I'ts supposed to check that a) the second reading (b2) is lower than the first, and that the first reading was at least 1.55 x the second. I didn't write any notes with the code, so I'm baffled as to how this part of it is supposed to work. I'm sure it did used to work, but now it doesn't give the expected results.

b3=b1/b2
b4=b1*100/b2//100
if b3 > 0 and b4 > 55 then
etc..

Is this how the picaxe precesses the 2nd line, If b1 = 221 and b2 = 46?

b4 = b1 x 100/b2//100
b4 = 22100/46//100
b4 = 480.4347826//100
b4 = 0.8043478

In which case I must have misunderstood how this is processed, because sometimes it does decide to execute the rest of the code as if b4 was >55.

Thanks anyone who can help
 

oracacle

Senior Member
the primary problem I can see is that 22*100/46//100 will cause b4 to overflow - byte variable can only hold values up 255. a word variable should be use as 22*100 is 2200 and a word variable can hold values up to 65535
 

westaust55

Moderator
I've recently resurected a piece of hardware that uses a picaxe 08m2 to read a light sensor before and after an external operation, place those 2 values into variables b1 and b2, and compare. I'ts supposed to check that a) the second reading (b2) is lower than the first, and that the first reading was at least 1.55 x the second. I didn't write any notes with the code, so I'm baffled as to how this part of it is supposed to work. I'm sure it did used to work, but now it doesn't give the expected results.




b3=b1/b2
b4=b1*100/b2//100
if b3 > 0 and b4 > 55 then
etc..

Is this how the picaxe precesses the 2nd line, If b1 = 221 and b2 = 46?

w4 = b1 x 100/b2//100
b4 = 22100/46//100
b4 = 480.4347826//100
b4 = 0.8043478

In which case I must have misunderstood how this is processed, because sometimes it does decide to execute the rest of the code as if b4 was >55.

Thanks anyone who can help

PICAXE internal math is to 16 bits so for a single line of BASIC math a value up to 65535 can be handled within the intermediate math and no error results, as long as the final result is <=255.

The modulo operation finds the remainder after division of one number by another.
Further, the PICAXE only works with integer (whole number) data.

Thus for b1 = 221 and b2 = 46:

b3 = b1/b2
b3 = 221 / 46
b3 = 4 (not 4.8)

and

b4 = 221 * 100 / 46 // 100
b4 = 22100 / 46 //100
b4 = 480 // 100

Now for the modulus part; consider
480 / 100 = 4
and 100 * 4 = 400
finally b4 = 480 - 400 = 80 (the remainder)
 

moorea21

Senior Member
Thanks westhaus 55, I can see how this routine doesn't give the expected results. I miscalculated the 'remainder' there. Also, if B2 = 52 then b4 = 25, which doesnt reflect that 221/52 > 1.55
I wonder if I should have just coded:

If b3=1 and b4>55 then 'ie if b1/b2 is between 1.55 and 2
do etc
Else if b3>1 then 'ie if b1/b2 is 2 or more
do etc
Else if
don't etc
End if

Would b4 overflow? What would I see on an LCD screen if it did? If this was so, there would be another layer of randomness, but I'm pretty sure I got this thing working as expected 3 years ago, although I am starting to doubt that now.
 

hippy

Technical Support
Staff member
place those 2 values into variables b1 and b2, and compare. I'ts supposed to check that a) the second reading (b2) is lower than the first, and that the first reading was at least 1.55 x the second.
Code:
w2 = b2 ** 36044 + b2                ; w2= b2 * 1.55
If b2 < b1 And b1 >= w2 Then
  ...
End If
 

moorea21

Senior Member
I'm not familiar with **, does it give you the most significant figures of a 32 bit word? Can't work out '36044 + b2', even with the manual...
Would you mind explaining it a bit?
Thanks
 

AllyCat

Senior Member
Hi,

Yes, the ** operator gives the High Word of a Word multiplication. See Variables - Mathematics near the start of Manual 2.

It effectively divides by 65536, so multiply that by the 0.55 to give 36045 (rounded) using a Pocket Calculator or the one within the PE. Alternatively, the ** can be considered as a multiplier of a "fractional binary word", i.e. where the MSBit represents 1/2 (a half), then the next bits 1/4, 1/8, etc. to give a maximum value of 1 (or almost).

So the b2 ** 36045 contributes the 0.55 and then adding b2 gives 1.55 * b2.

Cheers, Alan.
 
Top