Reputation: 155
The following simple code:
from decimal import getcontext
from decimal import *
import math
context = getcontext()
context.prec = 300
def f(x):
return Decimal(math.atan(10**(-x+1)))
def xNext(x,y):
return x-y*f(2)
def yNext(x,y):
return y+x*f(2)
x= Decimal(1)
y = Decimal(0)
x=xNext(x,y)
y=yNext(x,y)
x=xNext(x,y)
y=yNext(x,y)
x=xNext(x,y)
y=yNext(x,y)
print("{:.16f}".format(x))
print("{:.16f}".format(y))
returns
0.9702971603146833
0.2950554229911823
Which is wrong, should be around 0.97019857 and 0.2980158649 I thought this was a rounding error but this code should be working to 300 decimal places.
Not sure if different problem or not really going to 300 places...
EDIT: Yeah, I doubt it's a rounding error, I've just done the same process on wolfram only to around 20 decimal places at a time and my answer's more accurate than this one.
Upvotes: 0
Views: 89
Reputation: 42758
Decimal doesn't extend your precision, because you use the math
module. But that's not the point. Are you sure you calculation is correct? Just tried:
x, y = 1, 0
x, y = xNext(x,y), yNext(x,y)
x, y = xNext(x,y), yNext(x,y)
x, y = xNext(x,y), yNext(x,y)
And it leads to
0.970198479132
0.298015864998
which is basically your expected result.
Upvotes: 2
Reputation: 9704
I think that the problem lies here :
return Decimal(math.atan(10**(-x+1)))
I would imagine that ALL of the calculations in that formula (especially the math.atan function) will be calculated as a normal precision floating point number - and then converted back to a 300 decimal point Decimal.
If you want 300 point precision, you MUST find a way to ensure that every calculation is executed to that level of precision or better, as your result will only be as precise as your LEAST precise calculation.
Upvotes: 1