Try to construct two different programs to calculate the value of
Some will immediately noticed that this is actually , but we try doing it by definition.
First, we calculate the sum by usual order
Next, we calculate the sum by reversed order
The answer should be the same, even for computers, right? However, when I tried in C++
First approach:
1 2 3 4 5 6 7 |
|
Second approach:
1 2 3 4 5 6 7 |
|
And a constant value for reference:
1 |
|
Three values are:
1 2 3 |
|
So, the second approach seems more accurate, why is that?
The discrepancy is due to roundoff issues. A float holds only so many digits and (on my computer) the epsilon value for a float is around . This means that by the time the sum reaches , the value held in ans is too large for the addition of to have any effect. Many terms at the end of the series have little or no effect on the sum; their contribution is lost. However, those tail terms do have a cumulative contribution on the actual sum and are needed to give an accurate result. By summing in the reverse order these small terms do not have their contributions lost.
C++ For Mathematicians by Edward Scheinerman
Easy Math Editor
This discussion board is a place to discuss our Daily Challenges and the math and science related to those challenges. Explanations are more than just a solution — they should explain the steps and thinking strategies that you used to obtain the solution. Comments should further the discussion of math and science.
When posting on Brilliant:
*italics*
or_italics_
**bold**
or__bold__
paragraph 1
paragraph 2
[example link](https://brilliant.org)
> This is a quote
\(
...\)
or\[
...\]
to ensure proper formatting.2 \times 3
2^{34}
a_{i-1}
\frac{2}{3}
\sqrt{2}
\sum_{i=1}^3
\sin \theta
\boxed{123}
Comments
At first I thought this was something like @Mursalin Habib 's fallacies. After I finished reading it I realized it was a computer science problem :D
Try doing the same using a double instead of a float, does it return a similar result?
When written in Visual Basic, I did not face this problem at all.
Log in to reply
Can you explain why Visual Basic worked better than C++?
Log in to reply
Possibly because I used double precision variables (8 bytes) not float which is single precision (4 bytes) so the machine epsilon in my case is much smaller.
Java has BigDecimal. I got
1.6449330668487264363057484999793918558856165440796 1.6449330668487264363057484999793918558856165440640 1.6449340668482264
Using MathContext mc = new MathContext(50, RoundingMode.HALF_UP); n=1000000
Executes in a couple of minutes.
My 2 numbers deviate around the 48th decimal place.
But my constant, deviates around the 6th decimal place.
If anyone wants to see the entire source code, let me know.
Log in to reply
Do you have small file to send an accessible Java BigDecimal program via the internet? Where can I obtain instead?
"zeta"? Uhm. Where is the zeta?
Log in to reply
constant is the zeta
the problem is the method of storing number (float & double ) specially float.
This is just a sum of Fourier Series found in engineering mathematics for its exact proof. Sum to computing's significant figures always incur serious errors for series of less convergence which must go for a long run of up to 10^12 terms. Product to computing is relatively much more favorable with less inaccuracies. Turbo Pascal's EXTENDED of 18 S.F. appears to user is quite good to replace REAL by {$N+} or adjust numeric processing from software to 8087/80287 at Compiler under Options.
programming