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

Split Float to 2 INT

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



Joined: 05 Sep 2007
Posts: 46
Location: Londrina - Brazil

View user's profile Send private message

Split Float to 2 INT
PostPosted: Wed Sep 05, 2007 8:33 am     Reply with quote

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. Very Happy

Thanks a lot!
Ttelmah
Guest







PostPosted: Wed Sep 05, 2007 8:51 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Sep 27, 2007 10:53 am     Reply with quote

Thanks a lot for reply Ttelmah! Razz
vasiliok



Joined: 17 May 2011
Posts: 19
Location: Kaunas, Lithuania

View user's profile Send private message

PostPosted: Wed Mar 30, 2022 11:21 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Mar 31, 2022 12:19 am     Reply with quote

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: 19195

View user's profile Send private message

PostPosted: Thu Mar 31, 2022 12:32 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Mar 31, 2022 1:11 am     Reply with quote

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: 19195

View user's profile Send private message

PostPosted: Thu Mar 31, 2022 4:25 am     Reply with quote

Good. Very Happy

Have fun with the rest of the project.
temtronic



Joined: 01 Jul 2010
Posts: 9081
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Mar 31, 2022 6:01 am     Reply with quote

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: 19195

View user's profile Send private message

PostPosted: Thu Mar 31, 2022 7:51 am     Reply with quote

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: 1899

View user's profile Send private message

PostPosted: Thu Mar 31, 2022 8:22 am     Reply with quote

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: 19195

View user's profile Send private message

PostPosted: Thu Mar 31, 2022 10:28 am     Reply with quote

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.
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