![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
newguy
Joined: 24 Jun 2004 Posts: 1903
|
|
Posted: Thu Aug 31, 2023 9:19 am |
|
|
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." |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19358
|
|
Posted: Tue Sep 05, 2023 9:23 am |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
miro
Joined: 15 Jan 2011 Posts: 62
|
|
Posted: Wed Sep 06, 2023 1:14 am |
|
|
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
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](images/smiles/icon_cool.gif)
Last edited by miro on Wed Sep 06, 2023 1:37 am; edited 1 time in total |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19358
|
|
Posted: Wed Sep 06, 2023 1:36 am |
|
|
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..... |
|
![](templates/subSilver/images/spacer.gif) |
miro
Joined: 15 Jan 2011 Posts: 62
|
|
Posted: Wed Sep 06, 2023 1:50 am |
|
|
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). |
|
![](templates/subSilver/images/spacer.gif) |
miro
Joined: 15 Jan 2011 Posts: 62
|
|
Posted: Wed Sep 06, 2023 2:06 am |
|
|
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.. |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9168 Location: Greensville,Ontario
|
|
Posted: Wed Sep 06, 2023 5:54 am |
|
|
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 ? |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19358
|
|
Posted: Wed Sep 06, 2023 7:34 am |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|