View previous topic :: View next topic |
Author |
Message |
rhaguiuda
Joined: 05 Sep 2007 Posts: 46 Location: Londrina - Brazil
|
Split Float to 2 INT |
Posted: Wed Sep 05, 2007 8:33 am |
|
|
Hi
What is the easiest way to split a 32 bit float in 2 int?
Exemple:
Float: 124.56
Int1: 124 (integer part of the float)
Int2: 56 (fractional part of the float)
Exemple 2:
Float: 1423.5431
Int1: 1423
Int2: 5431
Any help is welcome.
Thanks a lot! |
|
|
Ttelmah Guest
|
|
Posted: Wed Sep 05, 2007 8:51 am |
|
|
You would have no way of distinguishing 1234.0056, from 1234.5600 with what you show. You need to decide on a scale factor to be used (for the second example, *10000), and keep this the same, so in the first case, the result would be 5600, not 56.
Remember you need to use int16 values to hold anything beyond 255. Also the one holding the part in front of the DP, will need to be signed.
You need to include 'math.h', then use:
Code: |
int16 fract;
signed int16 intval;
float val;
float intpart;
val=1234.5678
fract=(modf(val,&intpart) * 10000);
intval=intpart;
|
The last line automatically casts the integer part (stored as a float), into an integer.
Best Wishes |
|
|
rhaguiuda
Joined: 05 Sep 2007 Posts: 46 Location: Londrina - Brazil
|
|
Posted: Thu Sep 27, 2007 10:53 am |
|
|
Thanks a lot for reply Ttelmah! |
|
|
vasiliok
Joined: 17 May 2011 Posts: 19 Location: Kaunas, Lithuania
|
|
Posted: Wed Mar 30, 2022 11:21 pm |
|
|
Hello!
Could you please tell me what I'm doing wrong?
Code: |
float intpart;
unsigned int16 T1_trupmn;
signed int16 T1_sveikoji;
float DS_T1;
DS_T1 = -10.96; // Temperature
T1_trupmn=(modf(DS_T1,&intpart) * 10000);
T1_sveikoji=intpart;
fprintf (PC, "integer = %Ld\n\r", T1_sveikoji);
fprintf (PC, "fractional = %Lu\n\r", T1_trupmn);
DS_T1 = -0.01; // Temperature
T1_trupmn=(modf(DS_T1,&intpart) * 10000);
T1_sveikoji=intpart;
fprintf (PC, "integer = %Ld\n\r", T1_sveikoji);
fprintf (PC, "fractional = %Lu\n\r", T1_trupmn);
|
Got results:
for -10.96:
integer = -10
fractional = 55936
for -0.01:
integer = 0
fractional = 65436 |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Mar 31, 2022 12:19 am |
|
|
Read the CCS manual:
Quote: | modf( )
The modf() function breaks the argument value into integral and
fractional parts, each of which has the same sign as the argument.
It stores the integral part as a float in the object integral.
|
http://www.ccsinfo.com/downloads/ccs_c_manual.pdf
See page 347. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Thu Mar 31, 2022 12:32 am |
|
|
and (of course), it writes a _float_ value to the variable whose address is
passed. Writing a 4 byte float into a 2 byte integer, is not only going to give
screwy results, it'll probably result in the next variable in memory being
corrupted. |
|
|
vasiliok
Joined: 17 May 2011 Posts: 19 Location: Kaunas, Lithuania
|
|
Posted: Thu Mar 31, 2022 1:11 am |
|
|
Thanks for reply Ttelmah and PCM programmer!
You forced me to read and think!
Corrected my code. Getting integer part and 1 digit of fractional part correctly now.
Code: |
float intpart;
signed int8 T1_trupmn;
signed int8 T1_sveikoji;
float trpmn;
float DS_T1;
DS_T1 = -1.29;
//----------------------------
trpmn=(modf(DS_T1,&intpart) * 10);
T1_sveikoji=(signed int8)intpart;
T1_trupmn = abs((signed int8)trpmn);
fprintf (PC, "integer = %d\n\r", T1_sveikoji);
fprintf (PC, "fractional = %d\n\r", T1_trupmn);
|
Got:
integer = -1
fractional = 2
Tried different negative values and it works fine!
Values are for DS18b20 temperatures so it will be in -40...+60 range.
Need two integer bytes of temperature to send packet via RS485.
It is all ok now! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Thu Mar 31, 2022 4:25 am |
|
|
Good.
Have fun with the rest of the project. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9246 Location: Greensville,Ontario
|
|
Posted: Thu Mar 31, 2022 6:01 am |
|
|
OK, now that it's done and works,..
..I have to ask why not just send the two 'raw data' bytes to the PC instead of having the PIC convert to float, then convert to 2 'split' bytes ?
PICs are slow with floats and fancy 'math',also a lot of memory used for the code.
Just curious.
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Thu Mar 31, 2022 7:51 am |
|
|
Why does it ever get to/involve a float at all?.
The chip returns a binary 'count' of temperature in steps, usually of 0.0625C.
It really should be being handled all the way as integer, Perhaps simply in
counts, or multiplied to give an integer in hundredths of a degree.
Zero need to ever use floats at all.... |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1909
|
|
Posted: Thu Mar 31, 2022 8:22 am |
|
|
The most difficult repeating task I've ever faced is trying to wean fresh graduates off of the "float" mentality. The most extreme example I've ever seen was a co-op student that predated my time at an organization who wrote a completely custom 16 bit "float" type so that the system would display values to 4 decimal places (xxx.xxxx).
What they completely missed was the best case overall system resolution. If they had bothered to take the maximum analog output from the sensor and divide that by the 12 bit A/D (4096 steps) it fed, the absolute best case resolution we could hope to achieve was 0.4 units, or xxx.x.
The only times I've ever needed to use floats was in situations where I needed to compute a logarithm or when I needed to determine the distance between two locations denoted by latitude/longitude. Luckily with both those situations, I didn't need to actually compute things quickly - once per second or so was fast enough. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Thu Mar 31, 2022 10:28 am |
|
|
Absolutely.
The 'float mentality' is unfortunately very much ingrained. However the
more experienced users here (and with any other small chips), instead
use things like scaled integers to do the job, and the code is smaller, faster
and more reliable.
I have got a couple of applications that use floats, for sixth order polynomial
linearisation, and for a logarithmic sensor. However like you I look at the
code size, storage size, and speed involved. |
|
|
|