CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

subtracting signed 16 bit integers

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
russk2txb



Joined: 30 Mar 2008
Posts: 109
Location: New Jersey

View user's profile Send private message

subtracting signed 16 bit integers
PostPosted: Wed Oct 26, 2011 8:41 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Oct 26, 2011 10:02 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Oct 26, 2011 2:18 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Oct 26, 2011 2:20 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Oct 26, 2011 2:54 pm     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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