-
How to prevent variable going below zero?
Code:
reader:
adcin 0,Z
pause 100
IF Z>100 AND Z<130 THEN I=I+5
IF Z<100 THEN I=I-5
if i>255 then i=255
if i<5 then i=0
HPWM 2,I,10000
XY=I
gosub decoder
goto reader
Here is the simple code, the part if i>255 then i=255 works fine, but the part if i<5 then i=0 does not, because when i value goes below 0, it does not go below zero, it goes to 65535 and so on, completely messing whole code. Any ideas?
-
Re: How to prevent variable going below zero?
The convention used by most software is that if the most significant bit is set, then the number is negative.
-
Re: How to prevent variable going below zero?
Picbasic has no idea about negative numbers, anything goes below 0 gets deducted from 65535.
-
Re: How to prevent variable going below zero?
First, you didn't include what size your "z" & "i" variables are; var BYTE or WORD? If you declared them as BYTEs then 256 becomes your roll-over value, not 65536. If you are adding and want to check to see if your variable went over 255 and rolled over, the STATUS Register will show "STATUS.C = 1". If subtracting and want to see if it rolled from 0 to 255, "STATUS.C = 0". Look in your data sheet for the STATUS Register and how it works.
-
Re: How to prevent variable going below zero?
mike would you like to provide some pbp code that demonstrates use of status register following pbp addition or subtraction
the status reg here is not in any way influenced by the subtraction result
i = byte
Code:
j=8
i=6
while j
status=1
i=i-1
s=status
debug 13,10,"status ",bin8 s ," i ", dec i
j=j-1
wend
result
status 00011001 i 5
status 00011001 i 4
status 00011001 i 3
status 00011001 i 2
status 00011001 i 1
status 00011101 i 0
status 00011001 i 255
status 00011001 i 254
-
Re: How to prevent variable going below zero?
Yes variable is WORD, because if use BYTE, IF I>255 statement also wont work :D
-
Re: How to prevent variable going below zero?
Quote:
Originally Posted by
richard
mike would you like to provide some pbp code that demonstrates use of status register following pbp addition or subtraction
the status reg here is not in any way influenced by the subtraction result
i = byte
Code:
j=8
i=6
while j
status=1
i=i-1
s=status
debug 13,10,"status ",bin8 s ," i ", dec i
j=j-1
wend
result
status 0001100
1 i 5
status 0001100
1 i 4
status 0001100
1 i 3
status 0001100
1 i 2
status 0001100
1 i 1
status 00011
10
1 i
0
status 0001100
1 i 255
status 0001100
1 i 254
You don't state what PIC this is for, so I randomly grabbed the data sheet for a PIC16F1824; STATUS Register 3-1, page 24.
STATUS <7:5> = Unimplemented, read as 0
STATUS.4 = TO: Time-Out bit
STATUS.3 = PD: Power-Down bit
STATUS.2 = Z: Zero bit
STATUS.1 = DC: Digit Carry
STATUS.0 = C: Carry
You can see when you reached zero the STATUS.Z reflected that. However, you alter the STATUS Register in your code. About the only thing you can change is the C bit. Delete the "status=1" line and try again.
-
Re: How to prevent variable going below zero?
Quote:
You can see when you reached zero the STATUS.Z reflected that. However, you alter the STATUS Register in your code. About the only thing you can change is the C bit. Delete the "status=1" line and try again.
your assertion is
Quote:
If subtracting and want to see if it rolled from 0 to 255, "STATUS.C = 0". Look in your data sheet for the STATUS Register and how it works.
Quote:
You don't state what PIC this is for, so I randomly grabbed the data sheet for a PIC16F1824; STATUS Register 3-1, page 24.
if your assertion was correct it would not matter but its a12f1840
i repeat
mike would you like to provide some pbp code that demonstrates use of status register following pbp addition or subtraction
for any chip
-
Re: How to prevent variable going below zero?
a look at the lst file yields the reasons .
the status reg is not useful when you add or subtract a const 1
if you use a number greater than 1 or another var then the code does a proper addition/subtraction rather than inc/dec and sets status reg correctly
caveat emptor
-
Re: How to prevent variable going below zero?
Quote:
Originally Posted by
CuriousOne
Picbasic has no idea about negative numbers, anything goes below 0 gets deducted from 65535.
Re-read the single line I sent. I was not talking about PBP. I'm talking about representation of integers in a binary system. Read this article: https://www.cs.cornell.edu/~tomf/not.../twoscomp.html What most software developers do when they want to know when the variable goes "below zero", is look at the most significant bit. If it is high, the number is negative, if it is low, the number is positive. Since you are using a word, then your largest positive number will be 32768.
-
Re: How to prevent variable going below zero?
And since here is PBP forum, not general representation forum, I'm asking how to deal with this in PBP :)
-
Re: How to prevent variable going below zero?
Will this work for you?
iflag var bit
let iflag =0
reader:
adcin 0,Z
pause 100
IF Z>100 AND Z<130 THEN I=I+5
IF Z<100 and iflag = 0 THEN I=I-5 'only if iflag = 0 it's OK to substract
if i>255 then i=255
if i<5 then i=0
if i = 0 then let iflag = 1 'if i hits 0 put up a flag
if i >= 5 then let iflag = 0 'once i hits 5 or more, reset the flag
HPWM 2,I,10000
XY=I
gosub decoder
goto reader
-
Re: How to prevent variable going below zero?
In your original code, change
Code:
IF Z<100 THEN I=I-5
to this
Code:
IF Z<100 AND I>=5 THEN I=I-5
-
Re: How to prevent variable going below zero?
Try this:
if Z.15 = 1 then
Z = 0
endif
-
Re: How to prevent variable going below zero?
Quote:
Originally Posted by
CuriousOne
Code:
reader:
adcin 0,Z
pause 100
IF Z>100 AND Z<130 THEN I=I+5
IF Z<100 THEN I=I-5
if i>255 then i=255
if i<5 then i=0
HPWM 2,I,10000
XY=I
gosub decoder
goto reader
1. tumbleweed caught one problem in your code.
2. The variable I is altered some where? What check are you making ensuring it will not get a value to lead in negative results doing a -5 subtraction inside the reader routine?
Ioannis
-
Re: How to prevent variable going below zero?
I like Tumbleweed's code. Shorter and more to the point.
-
Re: How to prevent variable going below zero?
With a few proviso's mikes way beats it hands down
Code:
IF Z<100 THEN I=I-5
asm
BTFSS STATUS,C
CLRF _I
ENDASM
if i attempts to underflow its set to 0
-
Re: How to prevent variable going below zero?
I like it how a simple logic problem CuriousOne had, lead to another topic with negative numbers and STATUS register!
Quite interesting!
Ioannis
-
Re: How to prevent variable going below zero?
anyone familiar with assembly programming will be well aware of the status reg and its use. what surprised me is that
the value of the status reg was/is preserved even after the completion of the transaction. because the result is transferred from the
working regs back into the result variable during the process i expected the status to be no longer representative of the calculation.
surprised yet again !
-
Re: How to prevent variable going below zero?
You are absolutely right! I do not trust that this may be the case for any PIC though.
Ioannis
-
Re: How to prevent variable going below zero?
Quote:
I do not trust that this may be the case for any PIC though.
its a quick easy test to check, it works on all chips that i tried just make sure the compiler dosn't compress the subtract into a decrement
i var can be byte or word
Code:
j=8
i=6
while j
status=1
i=i-2 ;subtractant cannot be 1
s=status
debug 13,10,"status ",bin8 s ," i ", dec i
j=j-1
wend
-
Re: How to prevent variable going below zero?
Well, thanks for checking out. Wow!
Ioannis
-
Re: How to prevent variable going below zero?
Quote:
Originally Posted by
CuriousOne
Code:
reader:
adcin 0,Z
pause 100
IF Z>100 AND Z<130 THEN I=I+5
IF Z<100 THEN I=I-5
if i>255 then i=255
if i<5 then i=0
HPWM 2,I,10000
XY=I
gosub decoder
goto reader
Here is the simple code, the part if i>255 then i=255 works fine, but the part if i<5 then i=0 does not, because when i value goes below 0, it does not go below zero, it goes to 65535 and so on, completely messing whole code. Any ideas?
Using MAX and MIN operators provided by the compiler ????
4 times IF-THEN in a row, ... Time to have a look to SELECT CASE ...
BTW ... if you want your number staying between 0 and 255 ... use a BYTE, instead of a WORD ... :rolleyes:
I'm just curious about what you try to do ( in the real world, of course ) with such a piece of code !!!
Alain
-
Re: How to prevent variable going below zero?
Quote:
if you want your number staying between 0 and 255 ... use a BYTE, instead of a WORD
That's his problem... he DOES want to use a byte but as he adds or subtracts to the byte value it wraps and gives false operation.
The way I usually handle this sort of thing is to have a routine that does the addition or subtraction with a temp copy of the variable, and only update the variable if the operation is valid.
You don't have to detect a negative number... what you want to know is if you add X to Y will it be < Y (wrapped 255) and if you subtract X from Y will it be > Y (wrapped 0). Don't modify Y until you know the answer. You can have the routine limit the results to 255 or 0 if that's how you want it to work, or ignore the operation.
-
Re: How to prevent variable going below zero?
So this "wrapping" is compiler related issue and can't be fixed, as I understand?
-
Re: How to prevent variable going below zero?
Technically, I solved this problem by making I change between 5 and 260, and outputting HPWM 2,I-5,10000.
-
Re: How to prevent variable going below zero?
If you mean a compiler problem, no. It is not.
If you mean how binary arithmetic works, yes. That is how you count, add or subtract in binary having byte, word or other size variables. In any case that is how you do it in decimal also but do not give it much attention.
The "fix" is in the answers given already to you. SELECT CASE, test before updating for valid result, etc...
Ioannis
-
Re: How to prevent variable going below zero?