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

abs() function ... is there a more efficient way?

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



Joined: 21 Nov 2006
Posts: 129

View user's profile Send private message

abs() function ... is there a more efficient way?
PostPosted: Thu Sep 24, 2009 1:37 pm     Reply with quote

I need to get the absolute value of a signed long that is known to be negative. The abs() function does this in several instructions, when it seems there is a much easier way to do it (unless I'm doing something wrong).

Code:

raw_temperature_reading = abs(sum_of_all_good);

// take the two's compliment of the negative number to give the positive equivalent
sum_of_all_good ^= 0xFFFF;
sum_of_all_good++;



The list file:

Code:

....................           raw_temperature_reading = abs(sum_of_all_good);
01776:  MOVFF  274,03
0177A:  MOVF   x73,W
0177C:  BTFSS  x74.7
0177E:  BRA    1790
01780:  MOVLW  00
01782:  BSF    FD8.0
01784:  SUBFWB x73,W
01786:  MOVWF  00
01788:  MOVLW  00
0178A:  SUBFWB x74,W
0178C:  MOVWF  03
0178E:  MOVF   00,W
01790:  MOVWF  x6F
01792:  MOVFF  03,270
.................... 
....................           // take the two's compliment of the negative number to give the positive equivalent
....................           sum_of_all_good ^= 0xFFFF;
01796:  MOVLW  FF
01798:  XORWF  x73,F
0179A:  XORWF  x74,F
....................           sum_of_all_good++;
0179C:  INCF   x73,F
0179E:  BTFSC  FD8.2
017A0:  INCF   x74,F


Am I doing something wrong? Is it really that much more efficient to do it the second way, i.e. not using abs()?
Ttelmah
Guest







PostPosted: Thu Sep 24, 2009 2:46 pm     Reply with quote

The 'point' of the ABS function, is that it returns the positive value, for both positive, and negative inputs. If you _know_ the value is -ve, then just use:

-sum_of_all_good

The compiler does this using just two comf instructions, followed by the increment (and carry if needed), using five instructions. One better than the XOR version.

Best Wishes
evsource



Joined: 21 Nov 2006
Posts: 129

View user's profile Send private message

PostPosted: Thu Sep 24, 2009 2:58 pm     Reply with quote

Ttelmah wrote:
The 'point' of the ABS function, is that it returns the positive value, for both positive, and negative inputs. If you _know_ the value is -ve, then just use:

-sum_of_all_good

The compiler does this using just two comf instructions, followed by the increment (and carry if needed), using five instructions. One better than the XOR version.


Very good, thank you!

I'm taking 6 temperature measurements (can be positive or negative celsius), tossing out the high and the low (eliminate the most likely noise candidates), then averaging. Here's my implementation of what we just discussed to perform the averaging (BTW, "sum_of_all_good" is the summation of all the recorded values except the tossed high and low):

Code:

if(sum_of_all_good >= 0) temperature = sum_of_all_good >> 2;
else {
     -sum_of_all_good;
     temperature = sum_of_all_good >> NTS_PWR2;
     -temperature;
}


One final question - is the compiler smart enough to handle the sign bit for math operations involving int8's and int16's? For example, if I have my temperature values stored as signed int8's, and sum them into my signed int16 "sum_of_all_good", will the sign come out right if the int8 values are mixed between positive and negative in the int16 variable? (I know I can try this and see, but thought I'd ask in case someone else ever has the question)
SherpaDoug



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

View user's profile Send private message

PostPosted: Thu Sep 24, 2009 4:56 pm     Reply with quote

If you could do the summing and averaging with the raw A/D readings before converting them to temperatures you wouldn't have to worry about signs. Of course that depends on where the temperature data is coming from, and if the A/D count vs temperature is linear over the range of readings in any one set of samples.
_________________
The search for better is endless. Instead simply find very good and get the job done.
barryg



Joined: 04 Dec 2006
Posts: 41

View user's profile Send private message

PostPosted: Thu Sep 24, 2009 5:37 pm     Reply with quote

Um...those statements like
Code:
    -sum_of_all_good;
will compile, because C allows any statement to evaluate to a number. But it won't change the value! I tested this and the compiler simply leaves that line out. You have to have an assignment, like
Code:
    sum_of_all_good = -sum_of_all_good;

Barry
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