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

a strange problem

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



Joined: 18 May 2010
Posts: 78

View user's profile Send private message

a strange problem
PostPosted: Wed Oct 19, 2011 3:54 am     Reply with quote

Hi
I make a program with PIC16f877a. In one of functions when I subtract two values (for example : delta=32760-(-32760)) its result is odd because its result is -16.
delta=32760-(-32760)=-16
Code:

#include <16f877a.h>
#FUSES NOWDT,PUT,BROWNOUT,NOLVP,HS
#use delay (clock=16000000)
#use rs232(baud=19200, xmit=PIN_C6,rcv=PIN_C7)
#include <math.h>
#define DAC1 PIN_B4
#define DAC2 PIN_B5

//=========variables=================
signed int16 pre_in,input,step;
signed int16 delta;
unsigned int16 step_in,pre_step;


and

Code:
delta=32760-(-32760);
  if(abs(delta)<=abs(step_in))
  pre_step=abs(delta);
  else
  pre_step=abs(step_in);
  if(delta<0)
  step=-pre_step;
  else
  step=pre_step;


Thanks


Last edited by mojsa2000 on Wed Oct 19, 2011 4:10 am; edited 1 time in total
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Wed Oct 19, 2011 4:10 am     Reply with quote

Why do you find it odd? Its precisely what I'd expect your code to do. If you find it odd, that suggests you don't fully understand signed 2's compliment representation.

You are using 16 bit signed integers, with a range of -32768 to 32767. 32760-(-32760) is 32760 + 32760 which would give 65520, or 0xFFF0, as the sum will be done in unsigned 16bit arithmetic since both constants are unsigned, *despite* those minus signs: in C integer literals are always unsigned. However, you then assign the result to a *signed* 16 bit varaible and so 0xFFF0 is interpreted, in its 2's compliment form, as -16. Put another way, your sum has overflowed the range of signed 16bit and the result has wrapped round. Either way, its exactly what you should expect from the numbers and the variable type you've chosen to use.

RF Developer
mojsa2000



Joined: 18 May 2010
Posts: 78

View user's profile Send private message

PostPosted: Wed Oct 19, 2011 4:47 am     Reply with quote

Dear RF_Developer
this is my function and definitions:

Code:
signed int16 pre_in,input,step,delta;
unsigned int16 step_in,pre_step;
signed int8 buffer[4];
int1 start_flag=0,int_flag=0,cal_flag=0,dg_flag=0,step_flag=0,nxt_byte=0;
int1 nxt_st_byte=0;


Code:
void make_data(){
  input=make16(buffer[1],buffer[0]);
  pre_in=make16(read_eeprom(0x01),read_eeprom(0));//hi=0x01,low=0x0
  step_in=make16(buffer[3],buffer[2]);
  delay_us(50);
  write_eeprom(0x01, make8(input,1));
  write_eeprom(0, make8(input,0));
  delta=input-pre_in;
  if(abs(delta)<=abs(step_in))
  pre_step=abs(delta);
  else
  pre_step=abs(step_in);
  if(delta<0)
  step=-pre_step;
  else
  step=pre_step;
  //return input,pre_in,step;
  }


ore_in & input are signed integers and give a signed integer as delta
now,what do I do?
please help me.
thanks again
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Wed Oct 19, 2011 6:14 am     Reply with quote

mojsa2000 wrote:

this is my function and definitions (reformatted to make them readable):

Code:
signed int16 pre_in, input, step, delta;
unsigned int16 step_in, pre_step;
signed int8 buffer[4];
int1 start_flag=0, int_flag=0, cal_flag=0, dg_flag=0, step_flag=0, nxt_byte=0;
int1 nxt_st_byte=0;


Code:
void make_data(){
  input = make16(buffer[1], buffer[0]);
  pre_in = make16(read_eeprom(0x01), read_eeprom(0)); //hi=0x01,low=0x0
  step_in = make16(buffer[3], buffer[2]);
  delay_us(50);
  write_eeprom(0x01, make8(input,1));
  write_eeprom(0, make8(input,0));
  delta = input - pre_in;
  if(abs(delta) <= abs(step_in))
      pre_step = abs(delta);
  else
      pre_step = abs(step_in);
  if(delta<0)
      step = -pre_step;
  else
      step = pre_step;
  //return input,pre_in,step;
  }



What are you trying to do? This code does what it does, which as you're asking, is clearly not what you want it to do. So, what do you want this code to do? What problem are you trying to solve?

RF Developer
mojsa2000



Joined: 18 May 2010
Posts: 78

View user's profile Send private message

PostPosted: Wed Oct 19, 2011 6:51 am     Reply with quote

Hi again
I read two values on RS232 Port as "input" and "step".
then last "input" value that stored on memory on previous level, is loaded as "pre_in" .then I will count from "pre_in" to "input" .step is the "step"value.
for example :
I send 32760 as "input" and 100 as "step".assume that "pre_in" is -32760.
well,sign of "input-pre_in", determines if count up or count down and also "pre_in - input " value must be greater than "step" value.in this example :delta =32760-(-32760)=65520 and step is 100.
thus it counts up from -32760 to 32760 .each step is 100.note that step must be recieved on RS232 as a positive value (unsigned).
I simulate this code in protuos and I checked delta.
I think you're right.because when I count from zero to 32760 or -32760 its true but when I count from a negative value to positive value ( or viceversa) it do wrong.

thanks
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Wed Oct 19, 2011 8:11 am     Reply with quote

HINT:
you can try try int32 vars -
and then use a bit of TYPE casting to fewer bits ,
when generating your results
mojsa2000



Joined: 18 May 2010
Posts: 78

View user's profile Send private message

PostPosted: Wed Oct 19, 2011 8:45 am     Reply with quote

Hi
thank you
I did it
Code:
delta=((signed int32 )input- (signed int32 )pre_in);


best regards
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Wed Oct 19, 2011 11:19 am     Reply with quote

Still, I think you have a problem.
The delta between -32760 and + 32760 is too big to fit into a signed integer.
You could change the delta variable to type unsigned, but then it would only work for a positive delta value (32760 - (-32760)) and fail for the delta in the other direction.
Easiest fix is to change delta to an int32.
mojsa2000



Joined: 18 May 2010
Posts: 78

View user's profile Send private message

PostPosted: Wed Oct 19, 2011 2:08 pm     Reply with quote

Thanks for your attention.
I did it and it worked. I define a variable as signed int32 that supports -32760 to 32760. Then by "type casting", I did subtraction as you see.
Thanks again.
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Wed Oct 19, 2011 7:45 pm     Reply with quote

think you will find ....
Quote:
a variable as signed int32 that supports -32760 to 32760


that a signed int32 will hold MUCH Bigger values than that ..... Razz Very Happy
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