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 support@ccsinfo.com

Using unsigned and signed operands

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







Using unsigned and signed operands
PostPosted: Mon Aug 13, 2007 8:31 am     Reply with quote

Hello!

I have two variables:
Code:

long ul;
signed int si;


Now I add si (which can be positive or negative) to lu and need to make sure that ul does not drop below zero. Because ul is unsigned and I cannot simply add si to ul and do the comparison after that, I do the following:

Code:

if ((ul + si) < 0)
  ul = 0;
else
  ul += si;


This seems to work (at least at first glance) but from the CCS C manual I could not exactly figure out how it works. The compiler seems to do some type conversions here.

Can anyone give me a hint?

Thanks a lot,
Zer0flag
SET



Joined: 15 Nov 2005
Posts: 161
Location: Glasgow, UK

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Mon Aug 13, 2007 2:07 pm     Reply with quote

You might have to watch the case where ul is just below 0xFFFF - then ul + si will overflow. In general the compiler should generate code to so that there is never any overflow - so for (ul + si), result 'should' be 32 bit, and then sign-converted to allow comparison with zero.

Maybe something like:

Code:
if (si < 0) {
  if (-si > ul)
    ul = 0;
  else
    ul += si;
} else {
  if(ul - si < 0xFF)
    ul = 0xFFFF;
  else
    ul += si;
}
Zer0flag
Guest







PostPosted: Mon Aug 13, 2007 3:36 pm     Reply with quote

Thanks for the help SET. I also think that the compiler actually uses 32 bit signed to make the comparison work.

You mean the following code is generated internally by the compiler or did I misunderstand you:

SET wrote:

Maybe something like:

Code:
if (si <0> ul)
    ul = 0;
  else
    ul += si;
} else {
  if(ul - si < 0xFF)
    ul = 0xFFFF;
  else
    ul += si;
}
SherpaDoug



Joined: 07 Sep 2003
Posts: 1640
Location: Cape Cod Mass USA

View user's profile Send private message

PostPosted: Mon Aug 13, 2007 4:28 pm     Reply with quote

Look at the assembly code in the .lst file to be sure.
_________________
The search for better is endless. Instead simply find very good and get the job done.
SET



Joined: 15 Nov 2005
Posts: 161
Location: Glasgow, UK

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Tue Aug 14, 2007 4:52 am     Reply with quote

The compiler may well do it in a number of ways - extend numbers to 32 bit, or perhaps along the lines I suggested - if you actually code it that way then at least you know what is happening. As Doug says though, best to read the actual compiler output!
Zer0flag
Guest







PostPosted: Tue Aug 14, 2007 12:37 pm     Reply with quote

I am trying to analyze the assembler output but I am new to assembler and it can take a while ;) Here is the output if someone else is interested:

Code:

....................                if ((CurrentSet.i16 + enc_dir) < 0)      // to handle multiple turns of the encoder
1110:  CLRF   @7A
1111:  MOVF   43,W
1112:  MOVWF  @77
1113:  BTFSC  @77.7
1114:  DECF   @7A,F
1115:  ADDWF  5B,W
1116:  BSF    STATUS.RP0
1117:  MOVWF  44
1118:  BCF    STATUS.RP0
1119:  MOVF   5C,W
111A:  BSF    STATUS.RP0
111B:  MOVWF  45
111C:  MOVF   @7A,W
111D:  BTFSC  STATUS.C
111E:  INCFSZ @7A,W
111F:  ADDWF  45,F
1120:  BTFSS  45.7
1121:  GOTO   127
....................                   CurrentSet.i16 = 0;
1122:  BCF    STATUS.RP0
1123:  CLRF   5C
1124:  CLRF   5B
....................                else
1125:  GOTO   131
1126:  BSF    STATUS.RP0
....................                   CurrentSet.i16 += enc_dir;   
1127:  CLRF   @7A
1128:  BCF    STATUS.RP0
1129:  MOVF   43,W
112A:  BTFSC  43.7
112B:  DECF   @7A,F
112C:  ADDWF  5B,F
112D:  MOVF   @7A,W
112E:  BTFSC  STATUS.C
112F:  INCFSZ @7A,W
1130:  ADDWF  5C,F
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