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

How to printf float32 float64..
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
miro



Joined: 15 Jan 2011
Posts: 62

View user's profile Send private message

How to printf float32 float64..
PostPosted: Mon Aug 28, 2023 8:06 am     Reply with quote

Hi, we want to printf the float32/64 values and are coping with a problem.
Whatever we do the results are aprox 50 char long strings, basically a correct value, but the printf adds aprox 30-40 chars, perhaps a memory leak or wrongly set char counter in the library?? I would expect 7digits with f32 and 15 with f64 (plus minus).
Both 32/64 produce results like
9.0000006338947539475099073450937453094753031124E+00
PCD 5.112 for a dspic33fj128..


Last edited by miro on Mon Aug 28, 2023 9:14 am; edited 2 times in total
miro



Joined: 15 Jan 2011
Posts: 62

View user's profile Send private message

PostPosted: Mon Aug 28, 2023 8:44 am     Reply with quote

Code:
..

        float32 a32, b32, c32;
        float64 a64, b64, c64;
       
        a32 = 157.827;
        b32 = 346.384;
        c32 = (a32 / b32) * 2.456433e3;
       
        a64 = 157.827;
        b64 = 346.384;
        c64 = (a64 / b64) * 2.456433e3;
       
        printf("c32 = %e\n", c32);
        printf("c64 = %e\n", c64);   
        printf("c64 = %le\n", c64);  //??
         
        while(1){};


c32 = 1.1192532951166480614801912452094256877899169921E+03
c64 = 1.1192533454784300978035460616411000955849885940E+03
c64 = 1.1192533454784300978035460616411000955849885940E+03

PS: fyi - it should be (decimal math off the win calculator)
1.1192533462602198715876021987159E+03
Ttelmah



Joined: 11 Mar 2010
Posts: 19529

View user's profile Send private message

PostPosted: Mon Aug 28, 2023 10:09 am     Reply with quote

I remember this being reported a while ago on the f format. It was fixed
immediately. Suspect nobody tested e.
Report it to CCS, and if you do need e, then just print to a string buffer and
output only the left hand 8 characters, and then the exponent part.
You don't need 'l' the compiler treats all floats as float64 for the output
processing. Only just under 16 digits are significant in the number looks
like the output just keeps going.
temtronic



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

View user's profile Send private message

PostPosted: Mon Aug 28, 2023 10:11 am     Reply with quote

You need to post the compiler version you're using !
It could be a compiler bug....
Ttelmah



Joined: 11 Mar 2010
Posts: 19529

View user's profile Send private message

PostPosted: Mon Aug 28, 2023 10:29 am     Reply with quote

He says 5.112
miro



Joined: 15 Jan 2011
Posts: 62

View user's profile Send private message

PostPosted: Mon Aug 28, 2023 11:37 am     Reply with quote

Yep, I think the "f" did the same (I may retest that again).
Tried to format with %m.ne but the same.
There is also f48, but the math results I got with a test were off, thus I do not bother with the f48 yet..
Ttelmah



Joined: 11 Mar 2010
Posts: 19529

View user's profile Send private message

PostPosted: Mon Aug 28, 2023 11:43 am     Reply with quote

f is fixed in the current compiler. Will have to test if it was wrong in yours.
Contact CCS. If f is fixed already they will probably send you the fixed
file.

I don't think a lot of the f48 stuff works at all.
temtronic



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

View user's profile Send private message

PostPosted: Mon Aug 28, 2023 2:17 pm     Reply with quote

sigh, I gotta trifocals.....or a bigger monitor

had to re-read the post THREE times before I saw it...

the 'split' in the bifocals was right between the dark bold numbers and the next line, also lots of 'fun' trying to walk down stairs..
this getting old isn't the fun 'THEY' said it would be....
miro



Joined: 15 Jan 2011
Posts: 62

View user's profile Send private message

PostPosted: Tue Aug 29, 2023 1:57 am     Reply with quote

..and it is not only the issue with too many digits in their printf, but the precision trouble is there as well.
For example:

..
int64_t c64i = 10000000000000;
c64i = (int64_t)(c64 * c64i);
printf("ic64 = %Ld\n", c64i);

results in:
c64 = 1.1192533449572376197389544927318638656288385391E+05
ic64 = 1119253346260219904

the precise result is (win calc bcd math)
1.1192533462602198715876021987159E+03

therefore - the simple mult/div (in my above example) gives a precise f64bit result (the internal representation), their troubled printf does not (look at the first 16 digits), the "workaround" printout via int64_t shows the precise f64 result.

Be warned - the whole float/double math stuff in this compiler would require a detailed analysis/tests before somebody starts to use it, however.. Sad
temtronic



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

View user's profile Send private message

PostPosted: Tue Aug 29, 2023 5:11 am     Reply with quote

I'm curious.....

Did you confirm that the Win calc result IS the true, real, accurate correct result ?

this...

PS: fyi - it should be (decimal math off the win calculator)

...is concerning as it show Win Calc isn't 100% perfect.

It seems there's at least one 'bug' in the Win calculator.

Compare it to several other 'calculators', maybe even online versions ?

Maybe the result is correct, but I'd expect at least comparing to three others to confirm that WinCalc can be used as an accurate 'reference'. I never sample a sensor just once and use THAT result. I take several reading to ensure the result IS true.

also
Everyone knows PICs aren't great at floating point math. Perhaps you can use 'scaled integers' ? They are far more accurate and a lot faster to compute.

Just looking at options for you to get the result you need.
miro



Joined: 15 Jan 2011
Posts: 62

View user's profile Send private message

PostPosted: Tue Aug 29, 2023 6:09 am     Reply with quote

The win7/10 calculator is pretty precise, it uses 34 digits decimal math, afaik. Of course there is Wolfram Alpha and others with arbitrary precision you may compare with.
I messed a lot with double in past on various mcus, so I am aware of the limits somehow.
The 64bit double works here, it seems, the only big issue I see currently is the printf.
It should allow printing out up to say 15 decimal digits with f64.

Basic float64 math operands like "+-*/ sqrt" shall be last digit precise, the transcendental and trigo functions usually result in 1-3 last digits off, it depends on the implementation and arguments used (it is a rocket science with floating point math, indeed)..

You may use int32/64 math (fractional, scaled, etc) for almost everything when messing with typical 12-16bit sensors, of course, but soon or later you will hit into some calculations with frequency measurements (9-12digits are the raw data off any GPS disciplined system), voltage/currents (6-8 digits are the raw data people are getting today) and not having float64 is really a big pain when you do some processing like filtering/smoothing/averaging, math like standard deviation, etc etc upon those data. Not talking navigation/astronomy related, where at least float64 is a must.

And No, the dspic33/pic24 are not "slow" in float64, they are pretty useful even without an FPU. The mcus with the FPU are usually only 5-8x faster. Of course it depends on the app, but these pic24/dspic33 mcus could be quite useful in the backends of various measurement devices..
miro



Joined: 15 Jan 2011
Posts: 62

View user's profile Send private message

PostPosted: Tue Aug 29, 2023 7:15 am     Reply with quote

For example: sin(PI/5.0)
Wolfram Alpha
Win7 calculator
PCD float64

0.5877852522924731291687059546390727685976524376431459910722724807...
0.58778525229247312916870595463907
0.5877852522924738
Ttelmah



Joined: 11 Mar 2010
Posts: 19529

View user's profile Send private message

PostPosted: Tue Aug 29, 2023 8:00 am     Reply with quote

Seriously, that is better than I'd have expected it to be!....
C sin cos etc., are not high accuracy. However worth understanding that
an error in the fifteenth digit represents microns in any normal calculation.
It is also unavoidable, since the maths is internally only working to
just under 16 digits, and there will be rounding effects in the intermediate
maths stages.

The issue with the e format is more worrying
miro



Joined: 15 Jan 2011
Posts: 62

View user's profile Send private message

PostPosted: Wed Aug 30, 2023 3:28 am     Reply with quote

For example - you want to deliver a package from pointA to pointB and your pic24/dspic driving the drone wants to know where to fly.. Very Happy

Code:
printf ("\n######  DISTANCE AND INITIAL BEARING\n");
       
        float64 Alat, Alon, Blat, Blon;
        float64 Er;
        float64 PhiA, PhiB, XsiA, XsiB, dPhi, dLamb, a, c, d;
        float64 y, x, psi, inibr;
       
        // INPUTS
        Er = 6371.3e3;  // Earth radius in meters
       
        Alon = -88.252299;  // in degrees
        Alat =  42.989772;   // in degrees
       
        Blon = -79.998025;  // in degrees
        Blat =  43.290158;   // in degrees
       

        PhiA = Alat * PI_/180.0;
        PhiB = Blat * PI_/180.0;
       
        XsiA = Alon * PI_/180.0;
        XsiB = Blon * PI_/180.0;
       
        dPhi = (Blat - Alat) * PI_/180.0;
        dLamb = (Blon - Alon) * PI_/180.0;
       
        a = sin(dPhi/2.0) * sin(dPhi/2.0);
        a = a + cos(PhiA) * cos(PhiB) * sin(dLamb/2.0) * sin(dLamb/2.0);
       
        c = 2.0 * atan2(sqrt(a), sqrt(1-a));
         
        d = Er * c;           
       
        printf ("### Distance in meters = %e \n ", d);
       
        y = sin(XsiB-XsiA) * cos(PhiB);
        x = cos(PhiA)*sin(PhiB);
        x = x - sin(PhiA)*cos(PhiB)*cos(XsiB-XsiA);
        psi = atan2(y, x);
        inibr = psi * 180.0/PI_ + 360.0;
        inibr = fmod(inibr, 360.0);
             
        printf ("### Initial Bearing in degrees = %e \n", inibr);
       
        printf ("##### THIS IS THE END \n\n");


Provided your printf works you will get
Code:

### Distance in meters = 6.703201695481880E+005
### Initial Bearing in degrees = 8.432511496196331E+001


It takes aprox 4ms in the dspic33 at 80MHz clock, not bad..
This kind of stuff works with float64 and better math precision, of course, I would not try it with float32 or some fractional integers..
Ttelmah



Joined: 11 Mar 2010
Posts: 19529

View user's profile Send private message

PostPosted: Wed Aug 30, 2023 7:11 am     Reply with quote

Why not?.

Quite simply, no form of compass is going to give you accuracies in
billionths of a degree, and no distance measurement practical on a
flying device is going to measure to microns.

The standard float32 maths can solve calculations for aircraft tracking
that put you within a few cm of the target right across the Atlantic. On
normal drone flight distances you will be within the errors of GPS
navigation over any likely flight distance. Even the wide area augmented
systems only manage a best case of about 30cm.

You are trying to use precision beyond what is needed.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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