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

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



Joined: 24 Jun 2004
Posts: 1902

View user's profile Send private message

PostPosted: Thu Aug 31, 2023 9:19 am     Reply with quote

Ttelmah wrote:
You are trying to use precision beyond what is needed.


The creed of all young engineers:

"Calculate to 12 decimal points, measure with string, mark it with chalk, and cut it with an axe."
Ttelmah



Joined: 11 Mar 2010
Posts: 19227

View user's profile Send private message

PostPosted: Tue Sep 05, 2023 9:23 am     Reply with quote

Er:
Quote:

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


Your last line there is wrong.
The win calc bcd maths result cannot be right.

You have
1.1192533449572376197E5.

You multiply this by 10000000000000
So the result has to be this with the decimal moved 13 places right.
So
1.1192533449572376197E18
Or
1119253344957237619

The
1119253346260219904

Is actually the correct answer to the limitations of the accuracy of float64.
(just over 15 digits).
On this one your 'test' is wrong.

Also though your expectations here are wrong. You take a float64,
and multiply it with an int64 (should use float64 maths), then cast
this to an int64, and cast this back to a float64 (since you put it into
a float64 value). This results in the accuracy being trimmed at two
locations in the maths. Potentially makes errors worse.

I have reported the 'e' problem to CCS, since they tell me you have not
done so.
miro



Joined: 15 Jan 2011
Posts: 62

View user's profile Send private message

PostPosted: Wed Sep 06, 2023 1:14 am     Reply with quote

Ttelmah wrote:
Er:
Quote:

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


Your last line there is wrong.
The win calc bcd maths result cannot be right.

You have
1.1192533449572376197E5.

You multiply this by 10000000000000
So the result has to be this with the decimal moved 13 places right.
So
1.1192533449572376197E18
Or
1119253344957237619

The
1119253346260219904

Is actually the correct answer to the limitations of the accuracy of float64.
(just over 15 digits).
On this one your 'test' is wrong.

Also though your expectations here are wrong. You take a float64,
and multiply it with an int64 (should use float64 maths), then cast
this to an int64, and cast this back to a float64 (since you put it into
a float64 value). This results in the accuracy being trimmed at two
locations in the maths. Potentially makes errors worse.

I have reported the 'e' problem to CCS, since they tell me you have not
done so.


I do not know what you did above, or what kind of problem you indicate, but the results in my above post are ok, imho.

The c64 "result" is the "printed out result" of a calculation. Here I indicated the printf does not make the printf properly - a) there is an error inside their math (while doing the printf), b) their printf prints out too many digits for my taste Very Happy

Now, imagine you want to check the "internal valid digits representation" of the float64. You may do it by a) printing out the hex representation of it, or b) to "export the decimal mantissa" (aka "valid digits") somehow out.

I did it by multiplying the float64 c64 by a "large integer64 number" (max 19digits there), casting it into the ic64, thus I captured the internal decimal c64 representation (exponent regardless) into the ic64. That is the standard way in doing that, provided the int64 and float64 math per-se work.

Thus I got the ic64 (the series of decimal numbers in the c64 mantissa, the "exponent" regardless) and I compared it with the "win calc's" first 15 digits. Both results match in the first 15 places, therefore I concluded the int64 and float64 works.

I do not see any problem with my approach, imo.. Cool


Last edited by miro on Wed Sep 06, 2023 1:37 am; edited 1 time in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19227

View user's profile Send private message

PostPosted: Wed Sep 06, 2023 1:36 am     Reply with quote

The point is what you posted is wrong. You say:
Quote:

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

But you have a value scaled 1E5 by 1E13. Result should be
scaled 1E18, not 1E3.....
miro



Joined: 15 Jan 2011
Posts: 62

View user's profile Send private message

PostPosted: Wed Sep 06, 2023 1:50 am     Reply with quote

miro wrote:
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


Above is the math I did at the very beginning..

.. and in my final source I did

Code:
        a64 = 157.827;
        b64 = 346.384;
        c64 = (a64 / b64) * 2.456433e5;


therefore ..E+05 and not E+03 and diff in last digits (due to the issue they have in printf).
miro



Joined: 15 Jan 2011
Posts: 62

View user's profile Send private message

PostPosted: Wed Sep 06, 2023 2:06 am     Reply with quote

Ttelmah wrote:
The point is what you posted is wrong. You say:
Quote:

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

But you have a value scaled 1E5 by 1E13. Result should be
scaled 1E18, not 1E3.....


OK, I see now, the multiplication by that large 1000000000.. number is not related to the proving the exact number together with its "decimal exponent" ("do not care about the exponent") but what matters are the "mantissa digits" only - as I wanted to see the "valid mantissa digits" - that is important when talking "precision to 15 digits". You may have any "decimal" exponent, it does not matter here. So, what we talk here are the first valid 15 digits of the results.

The mult by 1000000000.. is the tool how to extract the mantissa only, and to check the digits in the valid decimal places (the first 15 decimals in this case, theoretically it is 15.95) are correct (the f64 mantissa is stored internally as a number around 1.0, with 53 significant bits in the IEEE), therefore you pump out the valid decimal digits by multiplying the float64 by 10^something and storing it into an int64.

It is used when you do not have printf "e/f/g" handy, and you want see whether the float math works with a certain precision or not.
An int64 can store up to 19digits, therefore the float64's mantissa fits inside just fine.

Example: float64 mynumber = 1.23456789123456E+167, I want to see the mantissa, it has to fit into 19 digits of an int64, therefore I divide it by 1E+167 for example, and mult it by an int64 100.000.000.000.000 and store it in an int64, and I get first 15 valid digits printed out via a printf int64.

You may do it by printing out the float64 in the HEX format for the 8bytes (IEEE-754/1985/2008/2019 standard format) of the float64 but you have to mess with the conversion of the IEEE format to decimal then.. Also not sure the ccs is using IEEE..
temtronic



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

View user's profile Send private message

PostPosted: Wed Sep 06, 2023 5:54 am     Reply with quote

Sigh, I just pity the poor PIC for having to crunch huge numbers like those ! In the beginning, PICs did simple,easy stuff......

Kinda wondering HOW the onboard computers in spacecraft got men to the moon... 1/2 century ago.....

Now wondering if there's a FPU for PICs, similar to what early PCs had ?
Ttelmah



Joined: 11 Mar 2010
Posts: 19227

View user's profile Send private message

PostPosted: Wed Sep 06, 2023 7:34 am     Reply with quote

Problem is that a float64, only has just over 15 usable digits of accuracy.
Expecting anything more is pointless, and in fact most of the functions
will be lucky to get even 13 usable digits. However working to even half this
will be more than any real application will need/want. Also the 'theoretical'
accuracy of float64 values changes with the numbers involved. There are
specific values that the IEEE format cannot represent at all accurately.
So (for example), 1/3.
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 Previous  1, 2
Page 2 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