float to str help

Discussion on projects that are created by users and posted on mikroElektronika website.
Post Reply
Author
Message
mmike87
Posts: 55
Joined: 25 Jun 2010 11:22

float to str help

#1 Post by mmike87 » 13 Jun 2011 19:20

Hi,
i've written this code but doesn't work.. the decimals are always **.999999 instead the correct numbers.. the ** numers are correct.. How can I do?
thank you
mike

Code: Select all

it2 = ADC_Read(0);
it1=1*it2/3*5/1024*100;
floattostr(it1,t);
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,"internal  Temp.  ");
lcd_out(2,1,t);

sasa72
Posts: 89
Joined: 21 Apr 2011 05:21

Re: float to str help

#2 Post by sasa72 » 14 Jun 2011 03:01

There is few basic "problems":

1. Binary floating point number cannot represent many decimal numbers exactly. There is not much you can do about.

2. mE products still do not supports biased/unbiased rounding. That mean, i.e, 0.3 + 0.7 can actually be 0.9xxxx, not 1.0.

3. As long you have many divisions and multiplications, significant error will accumulate very fast.

4. Notice dividing integers actually mean returning integer part of division. Use decimal point behind integer number to force compiler to use floating point math.

Solutions (if problem is no related with 4.):

1. You can use Janni's replacement libraries which supports biased/unbiased rounding. Still you facing with the original "problem" of binary representation of floats.

2. Since you need only integer part, you can use floor() or similar in C functions to round and convert floats to integer, or you can use even implicit typecasting assigning float to integer variable.

abcdefgg
Posts: 146
Joined: 19 Apr 2011 11:54
Location: Toko Japan

Re: float to str help

#3 Post by abcdefgg » 14 Jun 2011 07:03

Hi sasa,

Thanks for the information, but

I do not know why

2. mE products still do not supports biased/unbiased rounding. That mean, i.e, 0.3 + 0.7 can actually be 0.9xxxx, not 1.0.

Would you please elaborate on that?
Thanks a lot

mmike87
Posts: 55
Joined: 25 Jun 2010 11:22

Re: float to str help

#4 Post by mmike87 » 14 Jun 2011 08:14

Hi everybody,
thank you for your asnwers..
this is the code reported in the help of MikroC Pro:

Code: Select all

 float ff1 = -374.2;
float ff2 = 123.456789;
float ff3 = 0.000001234;
char txt[15];
...
FloatToStr(ff1, txt);  // txt is "-374.2"
FloatToStr(ff2, txt);  // txt is "123.4567"
FloatToStr(ff3, txt);  // txt is "1.234e-6"

 
now we can see in ff2 that the number has 4 decimal correctly converted.. my case it's not ff3 because i have numbers.. it's only a conversion of the adc.. i can do (adc result) * (constant) where constant is the result of 5/1024/3 so i doesn't have to a lot of divisions and moltiplications... i've tried but the result is the same..
thanks

mmike87
Posts: 55
Joined: 25 Jun 2010 11:22

Re: float to str help

#5 Post by mmike87 » 14 Jun 2011 08:18

another way is to delete all the decimal numbers in this way: the risult of 5/1024/3*100 is 0,162760 so i can do the counts with an int type eg. 103 (adc result) * 1627 (constant without decimals) = and than print char[1] char[2] "." char[3] char[4] .... how many you want..
what do you think about? thank you

sasa72
Posts: 89
Joined: 21 Apr 2011 05:21

Re: float to str help

#6 Post by sasa72 » 14 Jun 2011 09:29

abcdefgg wrote: 2. mE products still do not supports biased/unbiased rounding. That mean, i.e, 0.3 + 0.7 can actually be 0.9xxxx, not 1.0.

Would you please elaborate on that?
Similar logic for decimal floating point, if we fix precision up to 5 decimal places:

3.33333 + 6.66666 = 9.99999, not 10 which is logical since error limit is 10^(-5).

That is the core of needs for biased/unbiased rounding to "the nearest neighbor". In binary form for floating point, LSB (Lowest Significant Bit) of mantissa is need to be handled. Without it, error will accumulate on each primitive operation. AFAIK, that is not supported in mE compilers.

// Janni's replacement library supports unbiased rounding
http://www.mikroe.com/forum/viewtopic.php?f=93&t=21871

// Fine article to read
http://www.russinoff.com/libman/text/node22.html

janni
Posts: 5373
Joined: 18 Feb 2006 13:17
Contact:

Re: float to str help

#7 Post by janni » 14 Jun 2011 12:58

mmike87 wrote:another way is to delete all the decimal numbers in this way: the risult of 5/1024/3*100 is 0,162760 so i can do the counts with an int type eg. 103 (adc result) * 1627 (constant without decimals) = and than print char[1] char[2] "." char[3] char[4] .... how many you want..
what do you think about? thank you
Certainly the best method for simple calculations is to move to fixed-point math and operate on integral numbers only.

In your case it should be (adc result)/1023*(normalisation factor=500/3) which gives (adc result)*0.1629195..

(adc result)*16292 is pretty good fixed-point approximation with decimal point fixed before fifth digit from end (i.e. result will range from 0 to 16 667 716 corresponding to 0.00000 to 166.66716). Declaring the result as unsigned long and using LongWordToStrWithZeros conversion procedure, one may easily form a string for display with properly placed digital point and up to five significant digits after it.

mmike87
Posts: 55
Joined: 25 Jun 2010 11:22

Re: float to str help

#8 Post by mmike87 » 14 Jun 2011 13:53

thank you janny.. I have another post for interrupts problems with pic16f1937.. Could you help me there? I don't know why it doesn't work..
Thanks


abcdefgg
Posts: 146
Joined: 19 Apr 2011 11:54
Location: Toko Japan

Re: float to str help

#10 Post by abcdefgg » 15 Jun 2011 02:55

Thank you all!

sasa72
Posts: 89
Joined: 21 Apr 2011 05:21

Re: float to str help

#11 Post by sasa72 » 20 Jun 2011 07:55

In addition to Janni's post. If you do not need floating point math, nor integer multiplication for your project, you can speed all a bit more and save some space:

Code: Select all

x = value from port;
x = (x << 14)  - (x << 6) - (x << 5) + ( x << 2);
Or to "force" compiler to create much more efficient code:

Code: Select all

x = value from port;
x = (x << 7) - 1;
x = (x << 2) + 1;
x = (x << 3) + 1;
x = (x << 2) ;
Upper code is equivalent to multiplication with constant 16292, however much more efficient. Similar optimization technique always can be considered when is suitable for the project.

Post Reply

Return to “User Projects”