This is R FAQ 7.31 translated into Python:
http://www.hep.by/gnu/r-patched/r-faq/R-FAQ_82.html
That example in python gives the same result:
>>> a = math.sqrt(2)
>>> a*a - 2
4.440892098500626e-16
The difference in your tangent example is also very, very small:
>>> math.tan(math.pi/4) - 1
-1.1102230246251565e-16
and is just accumulated through all the floating point operations involved in dividing by four and taking the tan of an angle.
Answer from Spacedman on Stack OverflowThis is R FAQ 7.31 translated into Python:
http://www.hep.by/gnu/r-patched/r-faq/R-FAQ_82.html
That example in python gives the same result:
>>> a = math.sqrt(2)
>>> a*a - 2
4.440892098500626e-16
The difference in your tangent example is also very, very small:
>>> math.tan(math.pi/4) - 1
-1.1102230246251565e-16
and is just accumulated through all the floating point operations involved in dividing by four and taking the tan of an angle.
You will get the precision error as it is very obvious. However if you want to get the relevant value of Pi then you can use this(Also know as Archimedes method):
import math
# max error allowed
eps = 1e-10
# initialize w/ square
x = 4
y = 2*math.sqrt(2)
ctr = 0
while x-y > eps:
xnew = 2*x*y/(x+y)
y = math.sqrt(xnew*y)
x = xnew
ctr += 1
print("PI = " + str((x+y)/2))
print("# of iterations = " + str(ctr))
Finding a number up to n decimal places in Python. Also, is math.pi from python reliable? - Stack Overflow
rounding - How can I make numbers more precise in Python? - Stack Overflow
python - math.pi doesn't give me the good value - Stack Overflow
python - Print pi to a number of decimal places - Stack Overflow
What is math.pi in Python?
Is math.pi the same as numpy.pi?
Can I use pi in Python without importing math?
You can do what you want using format and specifying the number of places:
from math import pi
print (format (pi,'.100f'))
Another solution is by using the mpmath library:
from mpmath import mp
mp.dps = 100 # set number of digits
print(mp.pi)
Other answer are correct for printing with certain precision. However, if you try them with Decimal(math.pi) you will get 3.141592653589793115997963468544185161590576171875, obviously less than 100 digits, and even these digits are not all correct. Reason for this is that math.pi is float, which has limited precision.
To actually calcute correct digits of pi to any precision you can use this code (taken from official Python documentation for decimal library):
def pi():
"""Compute Pi to the current precision.
>>> print(pi())
3.141592653589793238462643383
"""
getcontext().prec += 2 # extra digits for intermediate steps
three = Decimal(3) # substitute "three=3.0" for regular floats
lasts, t, s, n, na, d, da = 0, three, 3, 1, 0, 0, 24
while s != lasts:
lasts = s
n, na = n+na, na+8
d, da = d+da, da+32
t = (t * n) / d
s += t
getcontext().prec -= 2
return +s # unary plus applies the new precision
This presumes you have set getcontext().prec to wanted precision.
Are you sure you need to make them "more precise"? Or do you just need to see more digits than Python shows by default?
>>> import math
>>> math.pi
3.141592653589793
>>>
>>> '{0:0.2f}'.format(math.pi)
'3.14'
>>>
>>> '{0:0.30f}'.format(math.pi)
'3.141592653589793115997963468544'
>>>
>>> '{0:0.60f}'.format(math.pi)
'3.141592653589793115997963468544185161590576171875000000000000'
However, note that
Floating point numbers are usually implemented using double in C; information about the precision and internal representation of floating point numbers for the machine on which your program is running is available in
sys.float_info
I assure you that pi doesn't go to zero after 48 digits :-)
Almost all machines today use IEEE-754 floating point arithmetic, and almost all platforms map Python floats to IEEE-754 “double precision”.
A IEEE-754 double has 64 bits (8 bytes), with the 52 bits of the fraction significand appearing in the memory format, the total precision is approximately 16 decimal digits.
So to represent a float number have a higher precise than that, you should use Decimal.
import decimal
decimal.getcontext().prec = 100
The proposed solutions using np.pi, math.pi, etc only only work to double precision (~14 digits), to get higher precision you need to use multi-precision, for example the mpmath package
>>> from mpmath import mp
>>> mp.dps = 20 # set number of digits
>>> print(mp.pi)
3.1415926535897932385
Using np.pi gives the wrong result
>>> format(np.pi, '.20f')
3.14159265358979311600
Compare to the true value:
3.14159265358979323846264338327...
Why not just format using number_of_places:
''.format(pi)
>>> format(pi, '.4f')
'3.1416'
>>> format(pi, '.14f')
'3.14159265358979'
And more generally:
>>> number_of_places = 6
>>> '{:.{}f}'.format(pi, number_of_places)
'3.141593'
In your original approach, I guess you're trying to pick a number of digits using number_of_places as the control variable of the loop, which is quite hacky but does not work in your case because the initial number_of_digits entered by the user is never used. It is instead being replaced by the iteratee values from the pi string.
It seems you are losing precision in this line:
pi = pi * Decimal(12)/Decimal(640320**(1.5))
Try using:
pi = pi * Decimal(12)/Decimal(640320**Decimal(1.5))
This happens because even though Python can handle arbitrary scale integers, it doesn't do so well with floats.
Bonus
A single line implementation using another algorithm (the BBP formula):
from decimal import Decimal, getcontext
getcontext().prec=100
print sum(1/Decimal(16)**k *
(Decimal(4)/(8*k+1) -
Decimal(2)/(8*k+4) -
Decimal(1)/(8*k+5) -
Decimal(1)/(8*k+6)) for k in range(100))
For people who come here just to get a ready solution to get arbitrary precision of pi with Python (source with a couple of edits):
import decimal
def pi():
"""
Compute Pi to the current precision.
Examples
--------
>>> print(pi())
3.141592653589793238462643383
Notes
-----
Taken from https://docs.python.org/3/library/decimal.html#recipes
"""
decimal.getcontext().prec += 2 # extra digits for intermediate steps
three = decimal.Decimal(3) # substitute "three=3.0" for regular floats
lasts, t, s, n, na, d, da = 0, three, 3, 1, 0, 0, 24
while s != lasts:
lasts = s
n, na = n + na, na + 8
d, da = d + da, da + 32
t = (t * n) / d
s += t
decimal.getcontext().prec -= 2
return +s # unary plus applies the new precision
decimal.getcontext().prec = 1000
pi = pi()