|
|
View previous topic :: View next topic |
Author |
Message |
russk2txb
Joined: 30 Mar 2008 Posts: 109 Location: New Jersey
|
subtracting signed 16 bit integers |
Posted: Wed Oct 26, 2011 8:41 am |
|
|
Hi. I ran into a problem today that I can hardly believe is happening. I have code that subtracts 2 signed sixteen bit integers, assigning the result to a third signed 16 bit. It was failing, so I used the CCS debugger to look at the values. The first value is ox0D0F (3343) and the second is 0x0D30 (3376), according to the mouse over display (and confirmed with the eval function of the debugger). The result should be 0xFFDF (-33), but the the stored result is 0x97DF (-26657).
Here is the code. The two values being subtracted are contained in a structure:
Code: |
SINT16 tDiff;
tDiff = Td.CurTemp - Td.LastTemp;
|
I looked at the actual value in ram for tDiff and confirmed the wrong value there. The other two values are buried deep in the struct, and hard to count out, but the values shown by the debugger are correct (temperature values in degrees C * 100).
The compiler is version 4.122. Is this a known problem?
Thanks, Russ |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19506
|
|
Posted: Wed Oct 26, 2011 10:02 am |
|
|
Post the structure.
Though you show your target variable as signed, it is the source variables that must be signed.
What PIC?. There are/have been oddities with quite basic arithmetic on some of the DsPIC's reported. Try deliberately casting in the subtraction.
So:
Code: |
tDiff = (signed int16)Td.CurTemp - (signed int16)Td.LastTemp;
|
However the result is 'wrong', even if unsigned was used. Are you sure nothing else is happening (corrupting a variable - interrupt etc....).
Remember you can look at the .lst file, and see what actual memory address the operation is taking the variables from, and at the .sym, to see where the structure is placed. It shouldn't be that hard to count to where the variables are!.
There were again documented problems with very large structures that cross page boundaries. I'd be suspicious of something like this.
Best Wishes |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Oct 26, 2011 2:18 pm |
|
|
Or post a complete test program. Here is an example. He has a question
about some structure math. I made a test program to check it out.
It's compilable and can be dropped into MPLAB and tested by anyone:
http://www.ccsinfo.com/forum/viewtopic.php?t=43825 |
|
|
russk2txb
Joined: 30 Mar 2008 Posts: 109 Location: New Jersey
|
|
Posted: Wed Oct 26, 2011 2:20 pm |
|
|
Thanks Ttelmah. The pic is 18F6723. Here is the structure:
Code: |
typedef short bool;
typedef signed int16 SINT16;
typedef struct {
long LoadTemp, Addr;
long CurAttn, LastAttn;
int Type, ItemCount, Item;
long DacSet [CH_MAX];
float DacVolts [CH_MAX];
float CurChVolts [CH_MAX];
SINT16 CurTemp, LastTemp;
int NewMagWord, NewPhaseWord;
bool bTempChange, bAttnChange, bMagChange, bPhaseChange;
bool bCustInstr;
} TableData;
|
I was able to make the routine work by assigning the structure variables to local variables before subtracting:
Code: | bool IsNewTemperature ()
{
SINT16 tDiff, t1, t2;
// If the temperature changed by more than 1/2 degree return true
t1 = Td.CurTemp;
t2 = Td.LastTemp;
tDiff = abs (t1 - t2);
if (tDiff > 50) {
Td.LastTemp = Td.CurTemp;
return true;
}
return false;
}
|
I've seen problems before when the compiler does not properly dereference structure variables for some operations, but does for others. And a big problem is trying to figure out whether it is the debugger that is making the mistake, or the compiler. A number of times the program was working find but the debugger was showing wrong values. But I must say that there have been big improvements to the debugger recently.
Anyway, if there are any CCS compiler people reading this I wish they would take a look and fix this problem. It cost me a lot of time.
Thanks, Russ |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19506
|
|
Posted: Wed Oct 26, 2011 2:54 pm |
|
|
You need to post the value of CH_MAX to allow the structure locations to be calculated. However (CH_MAX*10)+11 bytes in for CurTemp.
Try what happens if you move DacSet, CurChVolts & DacVolts after the other variables. If you look in the .sym file, for the location of Td, I really would suspect the page switch problem. I'd also suggest switching the bool declarations to int bitfields, since then all five values will be guaranteed to go into a single byte.
Best Wishes |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|