|
|
View previous topic :: View next topic |
Author |
Message |
gregoryg
Joined: 21 May 2009 Posts: 14
|
unsigned int |
Posted: Tue Jun 09, 2009 8:45 am |
|
|
Hello,
My code contains this lines :
Code: |
int16 value1,valu2,width;
if ((value1-value2 )>205)
width=20;
//----------------------------
if((value2-value1)>205)
width=40;
//------------------------
if(value1==value2)
width=30;
|
The problem is that when value1 and value2 are not equal i am allways geting width==40 even if value1 is bigger than value2.
I understood that int16 is unsigned char ,so is it possible that when for example value1==600 and value2==300, the second part of the code gets -300 and the program read it as 300?
what can I do to make it work?
Thank you. |
|
|
mkuang
Joined: 14 Dec 2007 Posts: 257
|
Re: unsigned int |
Posted: Tue Jun 09, 2009 8:47 am |
|
|
gregoryg wrote: | Hello,
My code contains this lines :
Code: |
int16 value1,valu2,width;
if ((value1-value2 )>205)
width=20;
//----------------------------
if((value2-value1)>205)
width=40;
//------------------------
if(value1==value2)
width=30;
|
The problem is that when value1 and value2 are not equal i am allways geting width==40 even if value1 is bigger than value2.
I understood that int16 is unsigned char ,so is it possible that when for example value1==600 and value2==300, the second part of the code gets -300 and the program read it as 300?
what can I do to make it work?
Thank you. |
Not sure if this is the problem but you have "value2" and "valu2". Are these suppose to be the same number? |
|
|
Ttelmah Guest
|
|
Posted: Tue Jun 09, 2009 9:01 am |
|
|
You don't get -ve numbers. What you get are overflowed results.
300-600, for an 'unsigned' calculation, gives 65236....
If you are working with unsigned values, _you_ need to ensure your arithmetic stays +ve, or handle the overflow yourself.
So:
Code: |
int16 value1,value2,width;
width=other_val; //what do you want it to be, if delta is <205?,
//and values are not equal?.
if (value1>value2) {
if ((value1-value2) > 205 width=20;
}
else {
if (value1==value2) width=30;
else if ((value2-value1)>205 width=40;
}
|
As shown, you also should handle the situation where the difference between the values <=205, but the values are not equal. Otherwise the result for this, will be garbage, depending on what else is happening in your memory.....
Best Wishes |
|
|
gregoryg
Joined: 21 May 2009 Posts: 14
|
|
Posted: Tue Jun 09, 2009 9:14 am |
|
|
So if it doesnt matter to me if the values are equal or the delta is <205
it will look like this?
Code: | int16 value1,value2,width;
width=30;
if (value1>value2) {
if ((value1-value2) > 205 width=20;
}
else {
if ((value2-value1)>=205 width=40;
}
|
Thank you very much for the help Ttelmah.
P.S This is a part of a code for suntracking robot. value1 , value2 are A2D converted data from photoresistors and width is the duty cycle for the servo motor. 205 is about 1V because I dont want my solar panel to move every small change in light. |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Tue Jun 09, 2009 10:13 am |
|
|
If it's possible that the result from your arithmetic could be a negative number then you need to be able to accomodate for that. An unsigned int16 will not do this. You would need to declare your variable as a signed int16 otherwise your result will roll over, as Ttelmah has explained, and give your the incorrect result.
Ronald |
|
|
mkuang
Joined: 14 Dec 2007 Posts: 257
|
|
Posted: Tue Jun 09, 2009 10:16 am |
|
|
rnielsen wrote: | If it's possible that the result from your arithmetic could be a negative number then you need to be able to accomodate for that. An unsigned int16 will not do this. You would need to declare your variable as a signed int16 otherwise your result will roll over, as Ttelmah has explained, and give your the incorrect result.
Ronald |
Int16 is by default a signed integer so I think the declaration is correct. And to the OP, the "char" declaration" is for a signed character -128 to 127 and is not the same as an int16. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jun 09, 2009 12:09 pm |
|
|
Quote: |
Int16 is by default a signed integer so I think the declaration is correct.
And to the OP, the "char" declaration" is for a signed character -128 to
127 and is not the same as an int16. |
That's not true. CCS is different. Integer Data types are unsigned by
default. Look at page 38 in the CCS manual (page 48 in the Acrobat
reader):
http://www.ccsinfo.com/downloads/ccs_c_manual.pdf
It says:
Quote: |
Note: All types, except float, by default are unsigned; however, [they]
may be preceded by unsigned or signed.
|
You can force the compiler to use signed declarations by default, if you
use the "#device ANSI" statement. Example:
Quote: |
#include <16F877.H>
#device ANSI
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
//======================
void main()
{
int16 x, y, z;
x = 10;
y = -1;
z = x / y;
printf("z = %ld \n\r", z);
while(1);
} |
Here's the result with #device ANSI. The 'int16' data type is treated as
'signed' by default.
Without #device ANSI, we get this result, which is expected if data types
are unsigned by default:
Also, in CCS, the 'char' data type is always unsigned, even if
#device ANSI is used. To make it be 'signed', it must be declared as
'signed char'. This was tested with the PCM compiler, vs. 4.093. |
|
|
mkuang
Joined: 14 Dec 2007 Posts: 257
|
|
Posted: Tue Jun 09, 2009 1:14 pm |
|
|
Thanks for the clarification. I have a one page summary from the manual you quoted and it there it says "int16 defines a 16 bit number" so I thought it was signed. Now I can go back and get rid of all those "unsigned" prefixes in my code. Thanks. |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
save the trouble |
Posted: Tue Jun 09, 2009 1:24 pm |
|
|
If you want UNSIGNED and have already done the entry
then there is no need to edit the code to remove the keyword.
With or without - compiler does the UNSIGNED THING
unless you are explicit to the contrary. |
|
|
Ttelmah Guest
|
|
Posted: Tue Jun 09, 2009 3:04 pm |
|
|
It is worth pointing out (once again), that CCS is not 'exceptional' in all of this.
K&R, has the following comment:
"Whether plain chars are signed or unsigned, is machine dependent, but printable characters are always unsigned". Given that in CCS, all chars are 'printable', their decision, here is sensible.
Where they differ, is in making the default integer 'unsigned'. You can though simply change this, by using the key line:
#type signed
However their own library functions may well not be reliable with this. However if you include this after their libraries, you can then treat integers as signed in your own code, just with the 'caveat', to remember that their functions generally expect to receive unsigned values.
Best Wishes |
|
|
|
|
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
|