5

My code:

def calc_pi(acc):
     pos = False
     sum = 4.0
     for i in range(2, acc):
          if not pos:
               sum -= 4.0/(2*i-1)
               pos = True
          else:
               sum += 4.0/(2*i-1)
               pos = False
     return float(sum)

print(calc_pi(5000))

And of course, I'm trying to calculate a pi, with more than 10 after-point-digits. But Python seems to round to 10. Is there a simple way, to prevent it from doing this? Like a million after-point-digits?

Thank you!

d0n.key
  • 1,318
  • 2
  • 18
  • 39
  • 1
    might not get you a million, but `decimal` can get you quite a few more. (https://docs.python.org/2/library/decimal.html) – NightShadeQueen Jul 04 '15 at 20:47
  • 1
    As an aside: the algorithm you're using is really slow, and the way you've implemented it introduces extra roundoff error. If you want to compute pi yourself, you might want to research better algorithms. –  Jul 04 '15 at 20:49
  • 1
    @Hurkyl has a fair point. But on the other hand, doing this in python has a lot lot lot more overhead than just that -- this can only be a proof of concept :) – Marcus Müller Jul 04 '15 at 20:50

3 Answers3

8

You can use the Decimal class provided by the standard library.

From the docs:

Unlike hardware based binary floating point, the decimal module has a user alterable precision (defaulting to 28 places) which can be as large as needed for a given problem:

  >>> from decimal import *
  >>> getcontext().prec = 6
  >>> Decimal(1) / Decimal(7)
  Decimal('0.142857')
  >>> getcontext().prec = 28
  >>> Decimal(1) / Decimal(7)
  Decimal('0.1428571428571428571428571429')
musically_ut
  • 34,028
  • 8
  • 94
  • 106
3

You can use Chudnovsky algorithm to calculate 100,000,000 decimal places of π. See also related questions 1000-digits-of-pi-in-python and python-pi-calculation.

If you don't want to implement your own algorithm, you can use mpmath package. For approximately 1000000 digits after decimal with the Chudnovsky series:

from mpmath import mp
mp.dps = 1000000  # number of digits
print(mp.pi)   # calculate pi to a million digits (takes ~10 seconds)
Community
  • 1
  • 1
s0nskar
  • 128
  • 2
  • 10
2

Python's built-in floating point is typically a 64-bit IEEE754 float (typically called "double").

What you want is something that is not a floating point representation but actually something extensible in (binary) digits, just like python's integer type can grow arbitrarily.

I thus urge you to have a look at fractional integer representation, and doing the maths to represent your number in that.

Marcus Müller
  • 34,677
  • 4
  • 53
  • 94
  • "that is not a floating point representation" Not really, he is simply looking for [arbitrary precision floating point representation](https://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic). Since pi is irrational, calculating it to some precision and then looking for the closest fractional integer representation, is kind of adding another layer of complexity. – rth Jul 05 '15 at 11:05
  • @rth: well, floating point will only be necessary if the exponent of the whole number ever changes. But all his iterations will end up between 2 and 4, so having a floating point simply wastes all the exponent bits. what is extensible in an arbitrary precision fp will be the mantissa -- but if you only ever change that, your mantissa becomes the fractional number representation :) – Marcus Müller Jul 06 '15 at 07:24
  • True, but then the mantissa is always a fractional number representation, so following this logic IEEE floats are not floating points either ^^. I suppose it's a mater of vocabulary, whether by floats people mean IEEE floats, or anything with a mantissa and an exponent (with an arbitrary numbers of bit in each). – rth Jul 06 '15 at 08:20
  • 1
    @rth very true :) you're right. The special thing about this case is that the exponent won't change. – Marcus Müller Jul 06 '15 at 09:44