|
|
View previous topic :: View next topic |
Author |
Message |
s_mack
Joined: 04 Jun 2009 Posts: 107
|
Data type conversion question |
Posted: Tue May 04, 2010 9:01 pm |
|
|
Really quickly just to make sure I have this straight...
If I have:
Code: |
unsigned int16 global_var = 2435;
myerror = function( 2048 )
int function( unsigned int16 local_var )
{
float error;
error = ( float )( local_var - global_var ) / 32.0;
return error;
}
|
myerror would be -12.09375, right?
You don't have to check the math, I just want to be sure I have the type conversion correct in this example.
Or do I need to go:
Code: |
error = ( (float)local_var - (float)global_var ) / (float)32.0
|
?
and do the unsigned vars have to be signed because the difference is negative? (I don't think so... but checking)
Thanks. |
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Wed May 05, 2010 2:04 am |
|
|
The first forula will give
error = (float)(2048 - 2435) / 32.0
2048 - 2435 = -387 but with unsigned int 16 math you will get 65149
You then convert to float and divide by 32.0 = 2035.90625
Your second formula should work.
You can always try it and output the answer to see what happens. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19551
|
|
Posted: Wed May 05, 2010 2:08 am |
|
|
You need to convert to signed, before the subtraction.
As it stands:
error = ( float )( local_var - global_var ) / 32.0;
The arithmetic (local_var - global_var) will be performed using unsigned int16 arithmetic (since both local_var, and global_var, are unsigned), and then the result converted to 'float'.
This will give 2048-2435=65149 (unsigned overflow.....)
You need:
error =( (signed int16)local_var - (signed int_16)global_var ) / 32.0;
You don't need the 'float' conversion, since '32.0', is a float value, conversion to float, is forced automatically, for the division, but you do need to force the subtraction to be performed using signed arithmetic.
Realistically, unless you 'need' values over 32767, just declare global_var, and local_var, as signed int16, to avoid this problem.
In C, the 'standard' is that for any arithmetic operation, involving two types, the 'lowest' type, is automatically converted to the higher type, and the arithmetic is performed using the maths of the higher type.
Conversion of 'signed', is a problem, since it depends on the ability of the processor. The rule is:
If one value is 'signed', the conversion depends on whether a 'signed' value can represent all possible unsigned values.
On some processors, the 'sign' bit is stored separately, so you effectively have 16bit +sign. On the PIC, signed, is only 15bit plus sign, so there is not an implicit conversion to signed, hence you have to explicitly force the conversion. With neither value 'signed', 'unsigned' arithmetic would always be the default.
Best Wishes |
|
|
s_mack
Joined: 04 Jun 2009 Posts: 107
|
|
Posted: Wed May 05, 2010 8:28 am |
|
|
Ahh, OK thanks. Glad I asked then!
I thought (float)(equation involving vars) would convert all the vars inside the equation to be floats. No problem, I'll just make those vars signed.... in this case there's no reason not to.
Quote: | You can always try it and output the answer to see what happens. |
Not easily. I figured there'd be no harm in asking instead. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19551
|
|
Posted: Wed May 05, 2010 8:44 am |
|
|
Things inside brackets, are performed before operations outside, so the maths is performed, before the float conversion.
If you went:
((float)local_var-global_var)
Then local_var is converted to float, floating point arithmetic is used, with 'global_var' being implicitly converted as well, and the result is a float. Here, since 'float' is definately a higher precedence 'type' than int16, the second number is automatically converted as well.
Downside of course is that float arithmetic is slower than int...
Best Wishes |
|
|
smithdwsn
Joined: 11 May 2010 Posts: 1
|
|
Posted: Wed May 12, 2010 10:03 am |
|
|
In c, there two types of casting. One is Implicit casting and other is Explicit casting. Which type of casting are you using its depend on you. But i can help in with simple both type of casting.
1. Explicit Casting.
eg.
short a=250;
int b;
b = (int) a;
b = int (a);
2. Implicit Casting
short a=250;
int b;
b=a;
I think it is the basic understanding of both type casting. _________________ r4 adapter |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Wed May 12, 2010 11:43 am |
|
|
smithdwsn,
In CCS the type "short" is 1 bit. So "short a=250;" isn't going to fly. Your code may work for a PC compiler where a short is 8 bits and an int is even bigger, but it doesn't work for CCS. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
Ken Johnson
Joined: 23 Mar 2006 Posts: 197 Location: Lewisburg, WV
|
|
Posted: Wed May 12, 2010 2:22 pm |
|
|
One more note:
Your "int function" will take the float error, truncate it, and return whatever fits in an "int" - CCS int is an 8-bit unsigned thingy, as I recall
Ken |
|
|
|
|
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
|