View previous topic :: View next topic |
Author |
Message |
levdev
Joined: 19 May 2010 Posts: 36 Location: UK
|
Testing for overflow in 16 and 32 bit maths |
Posted: Tue Feb 15, 2011 4:51 pm |
|
|
I have the code:
Code: |
int16 a, b, c;
c=a+b;
|
or
Code: |
int16 a, b, c;
c=a-b;
|
how can I tell if my int16 c has overflowed?
Testing the Status bits doesn't seem to work (possible because it's a 16 bit sum rather than 8 bit). |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Wed Feb 16, 2011 2:51 am |
|
|
Why do you think that that status register bits (C and OV) aren't valid for multi byte arithmetic. The status value after an arithmetic operation holds the result of MSB processing, which in fact does inform about signed overflow or unsigned carry. |
|
|
levdev
Joined: 19 May 2010 Posts: 36 Location: UK
|
|
Posted: Wed Feb 16, 2011 9:21 am |
|
|
On further investigating I have found that you are right FvM, the status register bits are valid for multi byte arithmetic. The problem was I was using the SFR tab in the debug window which doesn't seem to give a true value of the STATUS register, even if you set a breakpoint and use the refresh button.
Thanks for your reply. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Feb 16, 2011 12:52 pm |
|
|
Are you proposing that in the C language, we can depend upon machine
level flags being persistent and available at the C language source level ? |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Wed Feb 16, 2011 1:59 pm |
|
|
It may work, but I would not consider it good C programming form to depend on the overflow flag. It would be better to design the data path so overflow will never happen. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
levdev
Joined: 19 May 2010 Posts: 36 Location: UK
|
|
Posted: Wed Feb 16, 2011 2:39 pm |
|
|
One of the calculations I am doing is a simple Pythagoras calculation:
Code: |
int16 a,b,c;
int32 a2, b2, c2;
a=get_val_from_sensor_a();
b=get_val_from_sensor_b();
a2=_mul(a2,a2);
b2=_mul(b2,b2);
c2=a2+b2;
c=sqrt32(c2);
|
Now if a2+b2>2^32-1 then c2 will overflow. In my case if it overflows I don't need to know the value as it is out of range, so I could set it to the maximum value 2^32-1. But how do I know if it overflows? At the moment I am testing the STATUS register which seems to be working OK. I can't pre-test the a and b values because the expression combines to the two sqaures so only by calculating this expression can you get the result. I don't want to get into using 64 bit maths on a PIC18F. I suppose I could divide the a and b values by two before squaring and then double c at the end, but then I will lose some precision.
Any other suggestions would be appreciated. |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1907
|
|
Posted: Wed Feb 16, 2011 3:10 pm |
|
|
levdev wrote: | One of the calculations I am doing is a simple Pythagoras calculation:
Code: |
int16 a,b,c;
int32 a2, b2, c2;
a=get_val_from_sensor_a();
b=get_val_from_sensor_b();
a2=_mul(a2,a2);
b2=_mul(b2,b2);
c2=a2+b2;
c=sqrt32(c2);
|
Now if a2+b2>2^32-1 then c2 will overflow. In my case if it overflows I don't need to know the value as it is out of range, so I could set it to the maximum value 2^32-1. But how do I know if it overflows? At the moment I am testing the STATUS register which seems to be working OK. I can't pre-test the a and b values because the expression combines to the two sqaures so only by calculating this expression can you get the result. I don't want to get into using 64 bit maths on a PIC18F. I suppose I could divide the a and b values by two before squaring and then double c at the end, but then I will lose some precision.
Any other suggestions would be appreciated. |
Easy. Check to see if the result (a^2 + b^2) is less than either a^2 or b^2. If it is, there was an overflow. It's not a valid test for all combinations of a & b, but it's probably sufficient most of the time. |
|
|
|