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

Boundary checking on signed value using bit test

 
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

Boundary checking on signed value using bit test
PostPosted: Tue May 25, 2010 5:49 pm     Reply with quote

I'm trying to do a fast boundary check on a value that keeps increasing with every iteration of the loop. The magnitude that the value increases with each iteration is fixed. So I should be able to do the following to keep the accumulating_number variable from going much above 8192 and below -8192:

Code:
if(!bit_test(accumulating_number,13)) accumulating_number += error;


Both accumulating_number and error are declared as signed int16's.

But, when error is consistently negative, it grows well beyond the -8192. I haven't seen any values less than -32768, but they are almost always -32xxx.

As long as I do the following code, it works fine (but the above is *much* faster):

Code:

accumulating_number += error;
if(accumulating_number > 8192) accumulating_number = 8192;
else if(accumulating_number < -8192) accumulating_number = -8192;


Any ideas? I'm baffled.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue May 25, 2010 8:54 pm     Reply with quote

If you're in doubt about how something works, make a little test program
to study the boundary conditions. This code will do your negated bit 13
test, and step through values that are near to 8192 and -8192. You can
run it in MPLAB simulator, with "UART1" sending the printf output to the
MPLAB Output Window so you can see the results:
Quote:

8190 (1ffe): Negated Bit 13 test = 1
8191 (1fff): Negated Bit 13 test = 1
8192 (2000): Negated Bit 13 test = 0
8193 (2001): Negated Bit 13 test = 0
8194 (2002): Negated Bit 13 test = 0

-8190 (e002): Negated Bit 13 test = 0
-8191 (e001): Negated Bit 13 test = 0
-8192 (e000): Negated Bit 13 test = 0
-8193 (dfff): Negated Bit 13 test = 1
-8194 (dffe): Negated Bit 13 test = 1

Test program:
Code:

#include <18F452.h>
#fuses XT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
 
//======================================
void main(void)
{
signed int16 acc_number;

for(acc_number = 8190; acc_number < 8195; acc_number++)
   {
    printf("%ld (%lx): ", acc_number, acc_number);

    printf("Negated Bit 13 test = %u", !bit_test(acc_number,13));
   
    printf("\r");
   }

printf("\r");

for(acc_number = -8190; acc_number > -8195; acc_number--)
   {
    printf("%ld (%lx): ", acc_number, acc_number);

    printf("Negated Bit 13 test = %u", !bit_test(acc_number,13));
   
    printf("\r");
   }

while(1);
}

How to use "UART1" in MPLAB:
http://www.ccsinfo.com/forum/viewtopic.php?t=40045
Ttelmah



Joined: 11 Mar 2010
Posts: 19260

View user's profile Send private message

PostPosted: Wed May 26, 2010 2:15 am     Reply with quote

PCM programmer has shown how to 'see' what is happening. The reason, is in how -ve numbers are stored. Remember -1, is 0xFFFF.
Your test can be done in a number of ways:
Code:

accumulating_number += error;
if ((bit_test(accumulating_number,15)?\
bit_test(accumulating_number,13):!bit_test(accumulating_number,13))

Or:
Code:

if (!(bit_test(accumulating_number,13)^bit_test(accumulating_number,13)))

Or (obviously), performing the test on the abs value.

Best Wishes
evsource



Joined: 21 Nov 2006
Posts: 129

View user's profile Send private message

PostPosted: Wed May 26, 2010 9:14 am     Reply with quote

Ttelmah wrote:
PCM programmer has shown how to 'see' what is happening. The reason, is in how -ve numbers are stored. Remember -1, is 0xFFFF.


Thanks Ttelmah and PCM programmer. Ttelmah, you weeded out my innocence (stupidity might be an interchangeable word here! Confused ). I had the mistaken idea that the negative representation of the number was identical to the positive number, only with the sign bit flipped. Back to two's compliment 101.

I see my mistake now. As you said, easy enough to fix:

Code:

if((!bit_test(accumulating_number,15) && !bit_test(accumulating_number,13)) || (bit_test(accumulating_number,15) && bit_test(accumulating_number,13)) ) accumulating_number += error;


Probably some ways to optimize further for speed, if it's known whether the error will tend more towards being positive or negative.
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