|
|
View previous topic :: View next topic |
Author |
Message |
georpo
Joined: 18 Nov 2008 Posts: 281 Location: Athens, Greece.
|
atof error |
Posted: Fri Jan 27, 2023 3:28 am |
|
|
Hi,
I am using a PIC24FJ128GL305
Compiler 5.104
I get a wrong value returned from atof()
Code: |
fprintf(DBGUART,"\n\r%s",DatStr);
fprintf(DBGUART,"\n\r%2.2f",atof(DatStr));
|
Code: |
fprintf(DBGUART,"\n\r%s",DatStr);
fprintf(DBGUART,"\n\r%2.4f",atof(DatStr));
|
Code: |
result:
2.55
2.5499
|
and the other way around:
Code: |
fprintf(DBGUART,"\n\r%2.4f",(float)36/3600);
result:
0.0000
|
Code: |
fprintf(DBGUART,"\n\r%2.4f",(double)36/3600);
result:
0.0099
|
Any ideas? _________________ George. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19545
|
|
Posted: Fri Jan 27, 2023 6:40 am |
|
|
You need to understand that FP numbers are inherently not accurate.
Have a look here:
[url]
https://www.ibm.com/support/pages/single-precision-floating-point-accuracy
[/url]
[url]
https://learn.microsoft.com/en-us/cpp/build/why-floating-point-numbers-may-lose-precision?view=msvc-170
[/url]
There are lot of other sites describing the same problem.
For example, '0.1', can't actually be stored in a standard FP number.
The value it stores evaluates as 0.100000001490116119384765625
(if you could work with so many digits).
In this case, 'atof' has to walk through storing and multiplying the
digits of the incoming value, and there are errors at every stage of this.
result the number will never be exactly 2.55.
If you want accuracy, you have to work with integers, not FP values.
This is why 'scaled integers' are extolled by all the 'old hands' here. So
use a 32bit integer and %7.4LW, extract the digits manually from the
string so you have 25500, and print this, and you will see 2.5500.
Also, your fp print format is wrong. In C, the number in front of the decimal,
is the total output width. The number after is the number of decimals. So
your output is always overflowing the first value, resulting in the compiler
effectively having to ignore the first value and overflow the result. You
would want 7.4f to actually show correctly the values you are working with.
Printf also does not 'round' a value when being printed. So you would
have to do this yourself to the FP value to give a 4/5 rounded result
in the last digit of the output. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Fri Jan 27, 2023 9:15 am |
|
|
In addition to what Mr. T says....
Unless you have a floating point processor ( someone actually made them for PICs.... ) scaled integers are FASTER than floating point !! If you're going to use the data in 'real time', you need speed.
Also FP math consumes a HUGE amount of memory space,which in the 877 is very small compared to today's powerhouse PICs. |
|
|
|
|
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
|