I'm trying to enter in a number and calculate pi to that digit input. I managed to be able to calculate Pi, however no matter what number I type it will still generate the same amount of Pi numbers.
I'm a bit confused at what point it's causing to do that
from math import factorial
from decimal import Decimal, getcontext
# Chudnovsky algorithm for figuring out pi
getcontext().prec=100
pi_input = input('How many digits of pi would you like?')
n = int(pi_input)
def calc(n):
t= Decimal(0)
pi = Decimal(0)
deno= Decimal(0)
for k in range(n):
t = ((-1)**k)*(factorial(6*k))*(13591409+545140134*k)
deno = factorial(3*k)*(factorial(k)**3)*(640320**(3*k))
pi += Decimal(t)/Decimal(deno)
pi = pi * Decimal(12) / Decimal(640320 ** Decimal(1.5))
pi = 1/pi
return pi
print calc(n)
Here is my output
How many digits of pi would you like? 5
3.141592653589793238462643383279502884197169399375105820974944592307816346
94690247717268165239156011
Using the Chudnovsky algorithm, the calculation produces about 14.18 decimal digits per iteration: log10((640320^3)/(24*6*2*6)) ~= 14.18. This can be more clearly seen in the formula for ak / ak-1 as shown on this web page:
https://www.craig-wood.com/nick/articles/pi-chudnovsky
For n = 5, the result has about 70 digits of precision.
I just added round function in the return statement in your code and hope and it works for you as it for me.
from math import factorial
from decimal import Decimal, getcontext
# Chudnovsky algorithm for figuring out pi
getcontext().prec=1000
pi_input = input('How many digits of pi would you like?')
n = int(pi_input)
def cal(n):
t= Decimal(0)
pi = Decimal(0)
deno= Decimal(0)
for k in range(n):
t = ((-1)**k)*(factorial(6*k))*(13591409+545140134*k)
deno = factorial(3*k)*(factorial(k)**3)*(640320**(3*k))
pi += Decimal(t)/Decimal(deno)
pi = pi * Decimal(12) / Decimal(640320 ** Decimal(1.5))
pi = 1/pi
return round(pi,n)
print(cal(n))
you can use "%.nf"to format the output string where n is the number of digits you want to output.
e.g.
import numpy as np
print "%.5f"%(np.pi)
from math import factorial
from decimal import Decimal, getcontext
n = int(input('How many digits of pi would you like?'))
# Chudnovsky algorithm for figuring out pi
getcontext().prec=n+1
def calc(n):
t= Decimal(0)
pi = Decimal(0)
deno= Decimal(0)
k=0
#t = ((-1)**k)*(factorial(6*k))*(13591409+545140134*k)
t=(1)*(factorial(1))*(13591409+545140134*k)
deno = factorial(3*k)*(factorial(k)**3)*(640320**(3*k))
pi += Decimal(t)/Decimal(deno)
pi = pi * Decimal(12) / Decimal(640320 ** Decimal(1.5))
pi = 1/pi
return pi
print (calc(n))
this might be a simple code for understanding
from numpy import *
n = int(input('How many digits of pi after decimal would you like to print'))
print(pi)
#print (" value of pi at {:.4f} is" .format(pi))
print('{pi:0.{precision}f}'.format(pi=pi,precision=n))
this is how I would do it :-)
import math
digits = int(input("to how many digits to you want to round PI?"))
def roundpi(n):
return round(pi,n)
roundpi(digits)
Please try this and let me know if it works for you
import numpy as np
def pi_nth(n):
new_str = ''
for i in range(n+2):
new_str += str(np.pi)[i]
return float(new_str)
I answered the same question the short way using PI from the math module.
from math import pi
print()
nums = int(input("Enter the number of decimals: "))
print("Pi to the {}th number of decimals is %.{}f".format(nums, nums) % (pi))
Output
Enter the number of decimals: 5
Pi to the 5th number of decimals is 3.14159
This is in python 3.8 hope it helps.
#To print the Nth decimal place values of pi
from math import pi
#Receive the input value for number of decimal points of pi needed from user
i=input("Enter the number of decimal places needed in pi")
#Variable to hold the pi value upto nth decimal.Assign it to empty string initially
n_val=""
#Convert the pi value to string
string_pi=str(pi)
x=0
#loop through each literals and add the value to a string variable and then print it
while x<=int(i)+1:
n_val+=string_pi[x]
x=x+1
print(n_val)
from math import pi
num = int(input('Enter the number of decimals: '))
print(f"Pi upto {num}th number is {pi:{1}.{num+1}}")
Related
I'm trying to write a program that calculates pi with different accuracies and prints out the number and the time elapsed. I want to print the result with the current accuracy each time. I used print('pi = %*f'%(i, pi)) where i is my current floating point accuracy. This made the program round up the number to the i decimal digit. I'm attaching a picture showing my results running the same algorithm but changing output from:
print (" pi = ", pi, " =with ", i-1, " decimal points accuracy= in: ", (-1)*t, "sec")
to:
print (" pi = %.*f"%(i, pi), " =with ", i-1, " decimal points accuracy= in: ", (-1)*t, "sec")
This is my full code:
import time
accuracy = 4
for i in range(1,accuracy + 1):
pi = 0
prevPi = 1
x = 0
t = time.time()
while abs((pi * 4) - prevPi) > 10**((-1)*(i+1)):
#while x < lim:
prevPi = pi * 4
pi += (((-1)**(x))/(1+(2*x)))
#print(abs((pi * 4) - prevPi))
x += 1
pi *= 4
t -= time.time()
print (" pi = %.*f"%(i, pi), " =with ", i-1, " decimal points accuracy= in: ", (-1)*t, "sec")
How do I print the number with i decimal digits WITHOUT rounding?
You could approach your problem by defining function which truncates your number. That function could take two arguments:
number which you want to truncate,
position, at which it would drop all following values.
def truncate(number, position):
'''Return number with dropped decimal places past specified position.'''
return number - number%(10**position)
For instance if you would want number 3.14 truncated to 3.1, you should call following:
truncate(3.14, -1)
Also I modified your code so it would be simpler and match PEP 8 coding conventions. Therefore now it has increased variable naming clarity and better code formatting.
#!/usr/bin/env python3
'''Module for different pi accuracies calculation time comparison.'''
from time import time
def truncate(number, position):
'''Return number with dropped decimal places past specified position.'''
return number - number%(10**position)
def calculate_pi(accuracy):
'''Return pi with certain floating point accuracy.'''
previous_pi = 0
current_pi = 4
iterator = 1
while abs(current_pi - previous_pi) > 10 ** (accuracy-1):
previous_pi = current_pi
current_pi += 4 * ((-1)**iterator) / (1+(2*iterator))
iterator += 1
return truncate(current_pi, accuracy)
def calculation_speed_comparison(max_accuracy):
'''Print comparison of different accuracy pi calculation time.'''
for current_accuracy in range(max_accuracy+1):
calculation_time = time()
current_pi = calculate_pi(-current_accuracy)
calculation_time -= time()
print('pi = {} with {} decimal points accuracy in {} seconds.'.format(
current_pi, current_accuracy, -calculation_time))
calculation_speed_comparison(4)
Output to this code remains very similar to original one:
pi = 3.0 with 0 decimal points accuracy in 3.266334533691406e-05 seconds.
pi = 3.1 with 1 decimal points accuracy in 0.00016045570373535156 seconds.
pi = 3.14 with 2 decimal points accuracy in 0.0014882087707519531 seconds.
pi = 3.141 with 3 decimal points accuracy in 0.01430201530456543 seconds.
pi = 3.1415 with 4 decimal points accuracy in 0.1466822624206543 seconds.
I am trying to write a program to calclulate digits of pi using the Nilakantha Series in python. Every time it runs though it will not give me more than 50 decimals. Still learning python so any help is appreciated.
# Program using Nilakantha Series to crunch digits of pi
from math import *
from decimal import *
getcontext().prec = 200 # this is not doing anything
# epsilon is how accurate I want to be to pi
EPSILON = 0.000000000000000000000000000000000000000000000000000001
sum = float(3)
step = 0
i = 2
while abs(pi - sum) >= EPSILON:
step += 1
print (step)
if step % 2 == 1:
sum += 4.0 / (i * (i + 1) * (i + 2))
i += 2
else:
sum -= 4.0 / (i * (i + 1) * (i + 2))
i += 2
print (Decimal(sum))
print (Decimal(pi))
print ("Total itterations: ", step)
print ("Accurate to: ", EPSILON)
You are not using the Decimal class to calculate Pi, but rather the float class. getcontext() affects Decimal, not float.
If you want to use Decimal, modify your code to convert to Decimal before looping. Note that AFAIK, the value of Pi is not available as a decimal in Python, so you need to get the value from someplace else (http://www.geom.uiuc.edu/~huberty/math5337/groupe/digits.html).
I want to make a small python script to calculate pi to N number of decimal points and then only output that number of decimals. I don't know how to change the print statement to dynamically limit the number of outputted decimals. Here's my code.
#!python
import math
N = input("Enter the number of digits of pi you would like to compute: ")
runs = math.ceil(N/math.log(2))
a_0 = 1.0
b_0 = 1.0/(2.0**(1.0/2.0))
t_0 = 1.0/4.0
p_0 = 1.0
for x in xrange(1,N):
a = (a_0 + b_0)/2
b = (a_0*b_0)**(1.0/2.0)
t = t_0 - p_0*(a_0 - a)**2
p = 2*p_0
pi = ((a_0 + b_0)**2)/(4*t)
print pi
a_0 = a
b_0 = b
t_0 = t
p_0 = p
print 'Pi to %d number of digits is: ' % (N)
print "%0" N "d\n" % pi
I know my last print statement isn't how you implement this feature, but it gives an idea of how you might do it in something kinda like C.
I just want that last print statement to output pi to N number of digits.
I am trying to calculate pi with the Machin formula: http://en.wikipedia.org/wiki/Machin-like_formula.
It works when I do not use python's decimal library to get arbitrary precision (source code: http://pastie.org/9650936) but it only gave like 14 digits (3.14159265358979400417638316866941750049591064453125). I decided I wanted to get arbitrary precision but when I did the code for that, it changed the final value for pi. All I really changed was adding Decimal() for all the values, so I'm wondering what is wrong. Source code:
#!/usr/local/bin/python2.7
from decimal import *
getcontext().prec = 100
pi = Decimal(0)
ctwo = Decimal(239)
cfive = Decimal(5)
inc = Decimal(3)
a = Decimal(1)
epi = Decimal(1)/Decimal(5)
opi = Decimal(1)/Decimal(239)
for a in range(1, 10):
if (a%2 != 0):
epi -= Decimal(1)/Decimal((Decimal(inc)*(Decimal(cfive)**Decimal(inc))))
opi -= Decimal(1)/Decimal((inc*(ctwo**inc)))
inc = inc + Decimal(2)
a = a + Decimal(1)
elif (a%2 == 0):
epi += Decimal(1)/Decimal((inc*(cfive**inc)))
opi += Decimal(1)/Decimal((inc*(ctwo**inc)))
inc = inc + Decimal(2)
a = a + Decimal(1)
pi = Decimal(4)*Decimal((epi)-(opi))
pi = Decimal(4) * pi
print pi
and the value I get is slightly off, (3.091383741564895010542821040108680015248075199241027019420298084548814621985888671367248358277198010)
and I have done some experimenting and haven't been able to find out why it's doing this or how to fix it. Any help would be appreciated! Thanks!
I would like to use the Decimal() data type in python and convert it to an integer and exponent so I can send that data to a microcontroller/plc with full precision and decimal control. https://docs.python.org/2/library/decimal.html
I have got it to work, but it is hackish; does anyone know a better way? If not what path would I take to write a lower level "as_int()" function myself?
Example code:
from decimal import *
d=Decimal('3.14159')
t=d.as_tuple()
if t[0] == 0:
sign=1
else:
sign=-1
digits= t[1]
theExponent=t[2]
theInteger=sign * int(''.join(map(str,digits)))
theExponent
theInteger
For those that havent programmed PLCs, my alternative to this is to use an int and declare the decimal point in both systems or use a floating point (that only some PLCs support) and is lossy. So you can see why being able to do this would be awesome!
Thanks in advance!
You could do this :
[ This is 3 times faster than the other methods ]
d=Decimal('3.14159')
list_d = str(d).split('.')
# Converting the decimal to string and splitting it at the decimal point
# If decimal point exists => Negative exponent
# i.e 3.14159 => "3", "14159"
# exponent = -len("14159") = -5
# integer = int("3"+"14159") = 314159
if len(list_d) == 2:
# Exponent is the negative of length of no of digits after decimal point
exponent = -len(list_d[1])
integer = int(list_d[0] + list_d[1])
# If the decimal point does not exist => Positive / Zero exponent
# 3400
# exponent = len("3400") - len("34") = 2
# integer = int("34") = 34
else:
str_dec = list_d[0].rstrip('0')
exponent = len(list_d[0]) - len(str_dec)
integer = int(str_dec)
print integer, exponent
Performance testing
def to_int_exp(decimal_instance):
list_d = str(decimal_instance).split('.')
if len(list_d) == 2:
# Negative exponent
exponent = -len(list_d[1])
integer = int(list_d[0] + list_d[1])
else:
str_dec = list_d[0].rstrip('0')
# Positive exponent
exponent = len(list_d[0]) - len(str_dec)
integer = int(str_dec)
return integer, exponent
def to_int_exp1(decimal_instance):
t=decimal_instance.as_tuple()
if t[0] == 0:
sign=1
else:
sign=-1
digits= t[1]
exponent = t[2]
integer = sign * int(''.join(map(str,digits)))
return integer, exponent
Calculating the time taken for 100,000 loops for both methods :
ttaken = time.time()
for i in range(100000):
d = Decimal(random.uniform(-3, +3))
to_int_exp(d)
ttaken = time.time() - ttaken
print ttaken
Time taken for string parsing method : 1.56606507301
ttaken = time.time()
for i in range(100000):
d = Decimal(random.uniform(-3, +3))
to_int_exp1(d)
ttaken = time.time() - ttaken
print ttaken
Time taken for convertion to tuple then extract method : 4.67159295082
from functools import reduce # Only in Python 3, omit this in Python 2.x
from decimal import *
d = Decimal('3.14159')
t = d.as_tuple()
theInteger = reduce(lambda rst, x: rst * 10 + x, t.digits)
theExponent = t.exponent
Get the exponent directly from the tuple as you were:
exponent = d.as_tuple()[2]
Then multiply by the proper power of 10:
i = int(d * Decimal('10')**-exponent)
Putting it all together:
from decimal import Decimal
_ten = Decimal('10')
def int_exponent(d):
exponent = d.as_tuple()[2]
int_part = int(d * (_ten ** -exponent))
return int_part, exponent
from decimal import *
d=Decimal('3.14159')
t=d.as_tuple()
digits=t.digits
theInteger=0
for x in range(len(digits)):
theInteger=theInteger+digits[x]*10**(len(digits)-x)