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 CCS Technical Support

A strange problem with a float

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



Joined: 08 Apr 2008
Posts: 16

View user's profile Send private message

A strange problem with a float
PostPosted: Fri Nov 15, 2013 2:11 pm     Reply with quote

Hi there,

I have been trying to print a float value to a display and it seems to print the wrong value. For example:

Code:
float set_temperature = 50;

...

printf(lcd_putc, "A:%f",set_temperature);


I get:

A:49.999999

If i try it with a value of 10 i get 10 on the output.

Sorry if this is a stupid question - i have tried all sorts of things but seem to get the same result. Any help would be great!
newguy



Joined: 24 Jun 2004
Posts: 1907

View user's profile Send private message

PostPosted: Fri Nov 15, 2013 2:17 pm     Reply with quote

For floats this is normal. Often a float can't "exactly" store a value. It can be argued that 49.999999 is 50.
mxkid



Joined: 08 Apr 2008
Posts: 16

View user's profile Send private message

PostPosted: Fri Nov 15, 2013 2:26 pm     Reply with quote

Thanks for the fast reply. What i want to do is take the average of two temperature probes and use that to control an output. So:

Probe 1 = 20 degree's.
Probe 2 = 21 degree's
Average = 20.5 degrees.

I think if i have a look up table i can just "print" the average value without using a float or a calculation.

Cheers - any other ideas welcome Very Happy
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Fri Nov 15, 2013 2:54 pm     Reply with quote

Often decimal fixed point numbers with one or two fractional digits are a solution, particularly if they fit a 16 bit variable.

Otherwise rounding and respective format control with float numbers.
newguy



Joined: 24 Jun 2004
Posts: 1907

View user's profile Send private message

PostPosted: Fri Nov 15, 2013 3:41 pm     Reply with quote

I agree that using an int instead is a much more attactive option. Even declaring a float (and not using it) alarmingly adds to the ROM and RAM used by a project, nevermind the fact that floats are very, very slow to deal with.

Getting back to the int idea....instead of 20 degrees, store 200 in a variable, which actually equals 20.0 degrees. 21 degrees would be 210. Average the two and you have 205, or 20.5 degrees. Much faster to execute, much smaller ROM/RAM "footprint" in code.
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Sat Nov 16, 2013 5:44 am     Reply with quote

and (of course), remember that CCS has the ability to print an int, with a decimal point 'added' using %w.

It is worth realising that (for example), financial calculations _never_ use float, for exactly this reason. Languages designed to work with values where 'cents matter', have libraries to use scaled integers this way.

Also worth saying though, that if using floats, then 'limit the decimals'. So (for instance):
Code:

printf(lcd_putc, "A:%7.2f",set_temperature+0.005);


Will display just two decimal places, and half a digit to the third (undisplayed) decimal, to give rounding.

Repeat again though, just how bulky and slow fp maths is....

Best Wishes
mxkid



Joined: 08 Apr 2008
Posts: 16

View user's profile Send private message

PostPosted: Sat Nov 16, 2013 12:01 pm     Reply with quote

Hi all,

Thanks for your replies!

Ttelmah,

How would i use %w in my code to produce a decimal point? I have:

Code:
printf(lcd_putc, "S:%Ld", set_temperature);


I've tried a few variations - if i calculate 'set_temperature' to "205" how can i use %w to display "20.5"? I just tend to get errors. I've looked through the reference manual / other texts and i can't seem to find anything on it. Sorry if i'm being a goonball!

Thanks! Very Happy
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Sun Nov 17, 2013 1:12 am     Reply with quote

Code:

printf(lcd_putc, "S:%03.1Lw", set_temperature);


The 'w' replaces the 'd'. Needs the 'L' to say a long integer. Then needs the '.1' to say display with one decimal. The 03, means it will display as 0.0, when zero etc. Three 'characters' minimum displayed, and leading zeros, when these characters are zero.

Best Wishes
mxkid



Joined: 08 Apr 2008
Posts: 16

View user's profile Send private message

PostPosted: Sun Nov 17, 2013 2:44 am     Reply with quote

Hi Ttelmah,

Thanks for the reply. I actually tried that variation but i keep getting:

Error 115 Printf format (%) invalid

My Version is 3.230 so it's pretty old - my spider senses are telling me that this was not supported at the time my compiler was made.

Thanks again - back to the drawing board Very Happy
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Sun Nov 17, 2013 3:08 am     Reply with quote

Unfortunately, yes....

I don't think %w, was actually added till about 3.240. Also for the first few versions, it wouldn't accept a 'long'. Wasn't in the 3.226 manual, but had appeared by 3.249.

However you should be able to 'cheat'. Div had been added by then. So:
Code:

//with the declarations at the top of your code
#include <stdlib.h> //needed for the type declarations
ldiv_t splitter;

     //Then when you want to print
     splitter=ldiv(set_temperature,10);
     printf(lcd_putc, "S:%01Ld.%01Ld", splitter.quot,splitter.rem);


More complex, but should give the correct display.

About 179 compiler releases, and 8+ years old version....

Best Wishes
mxkid



Joined: 08 Apr 2008
Posts: 16

View user's profile Send private message

PostPosted: Mon Nov 18, 2013 1:28 pm     Reply with quote

Hi Ttelmah,

Thanks - that works well. Much better to use int's and insert a decimal point for what i want - happy days Very Happy
newguy



Joined: 24 Jun 2004
Posts: 1907

View user's profile Send private message

PostPosted: Mon Nov 18, 2013 1:37 pm     Reply with quote

Ttelmah wrote:
It is worth realising that (for example), financial calculations _never_ use float, for exactly this reason. Languages designed to work with values where 'cents matter', have libraries to use scaled integers this way.


Same can be said for GPS coordinates. My company has GPS receivers on all field equipment and we need the location data to be accurate down to < 3m (usually not a concern if WAAS signals are available).

I designed the GPS -> our system interface device and another engineer here (pure comp sci education) then integrated the data into a mapping database. First attempt was horrible - accuracy was on the order of a km, not a few meters. Turns out he was taking the integer location data and loading it into a float and going from there. Once I told him to treat the data as an int, our accuracy suddenly increased by several orders of magnitude.
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