15

My program calculates the mathematical constant e, which is irrational. In order to do this, I needed to get factorials of very large numbers.

int cannot handle numbers larger than 170!. (I found that the largest Google's calculator can handle is 170.654259, but I'm not sure how a non integer can be factorized.) float can not handle very large numbers either.

I calculated e to 750000 digits, and math.factorial(750000) is a mind-boggling, large number. Yet, Decimal handled it with apparent ease.

How large of a number can Decimal handle before an OverflowError is raised? Is the size different in Python 2 versus Python 3?

davidism
  • 121,510
  • 29
  • 395
  • 339
Dorian Dore
  • 942
  • 4
  • 15
  • 35
  • 5
    `Decimal` is not actually giving you exact answers. – Dietrich Epp Jan 22 '15 at 04:28
  • 1
    Integers have infinite precision in Python e.g., `math.factorial(170)` is `7257415615307998967396728211129263114716991681296451376543577798900561843401706157852350749242617459511490991237838520776666022565442753025328900773207510902400430280058295603966612599658257104398558294257568966313439612262571094946806711205568880457193340212661452800000000000000000000000000000000000000000`. See [how you could use `decimal.Decimal` to compute an answer with arbitrary (but fixed) precision](http://stackoverflow.com/a/347749/4279) – jfs Jan 22 '15 at 05:14
  • FWIW, it's not that hard to calculate large numbers of decimal digits of e using integer arithmetic. See [here](http://forums.xkcd.com/viewtopic.php?t=14661&p=3066871#p3066964) for example code in Python and C. – PM 2Ring Jan 22 '15 at 05:48
  • @PM2Ring: it is even simpler [using `decimal` module](http://stackoverflow.com/a/28082106/4279) – jfs Jan 22 '15 at 05:59
  • @J.F.Sebastian: Oh, I wasn't suggesting my algorithm was simpler, or even faster. Just that it's not _that_ hard to do this particular calculation with simple (fixed precision) integer arithmetic. OTOH, one nice thing about my algorithm is that you don't have to wait for the calculation to complete before it starts printing digits. – PM 2Ring Jan 22 '15 at 06:01

2 Answers2

14

What is the largest number the Decimal class can handle?

The largest magnitude is infinity:

>>> from decimal import Decimal
>>> Decimal('Inf')
Decimal('Infinity')

The largest representable finite number on a given platform depends on decimal.MAX_EMAX:

>>> from decimal import Context, MAX_EMAX
>>> d = Context(Emax=MAX_EMAX, prec=1).create_decimal('9e'+str(MAX_EMAX))
>>> d.is_finite()
True
>>> d.next_plus()
Decimal('Infinity')
>>> d
Decimal('9E+999999999999999999')

The number of significant digits depends on decimal.MAX_PREC e.g., to calculate e with the given precision:

>>> from decimal import Context
>>> Context(prec=60).exp(1)
Decimal('2.71828182845904523536028747135266249775724709369995957496697')

The constants (MAX_EMAX, MAX_PREC) are only relevant for the C implementation. Pure Python version can use larger values:

>>> from decimal import Context, MAX_EMAX
>>> Context(Emax=MAX_EMAX+1, prec=1).create_decimal('9e'+str(MAX_EMAX+1))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: valid range for Emax is [0, MAX_EMAX]
>>> from _pydecimal import Context, MAX_EMAX
>>> Context(Emax=MAX_EMAX+1, prec=1).create_decimal('9e'+str(MAX_EMAX+1))
Decimal('9E+1000000000000000000')
jfs
  • 399,953
  • 195
  • 994
  • 1,670
2

It depends on the context you provide for the Decimal object. From the library documentation:

class decimal.Context(prec=None, rounding=None, traps=None, flags=None, Emin=None, Emax=None, capitals=1)

Emax and Emin control the bounds of your decimal. If the exponent is greater than Emax or less than Emin there will be an overflow signal. You can look at the fields in decimal.defaultContext to see what they are by default, or decimal.getContext() to see what they are at any given time.

Edit: As @davidism pointed out you don't get exact answers from decimal calculations. The default precision of the module is 28. So all integers up to 999999999999999999999999999999 (28 nines) can be represented exactly, and higher numbers might be rounded.

genisage
  • 1,159
  • 7
  • 17
  • 1
    Only then it will raise an overflow error? When I was calculating e, my computer fan was loud and the system monitor displayed that one of my CPUs was at 100% usage, and they would switch every 15 minutes or so. What if my computer is tasked with intensive instruction that causes it to reach its max temperature? Or what if the number is stored in RAM and the RAM Runs out of space? – Dorian Dore Jan 22 '15 at 04:29
  • not enough memory would give a `MemoryError`. overheating is not something that would give any signal in python as far as i know. – M4rtini Jan 22 '15 at 04:32
  • 1
    the `traps` field determines what things will cause errors and what things it will sweep under the rug. By default overflows are treated as errors. I can't really tell you how much python cares about the physical limits of your computer. But if you don't care too much about your data, I encourage you to run some tests. – genisage Jan 22 '15 at 04:32
  • So there's virtually no limitations for the size of the number Decimal can handle? That's really neat! What about the getcontext() class? – Dorian Dore Jan 22 '15 at 04:48
  • 1
    @DorianDore The only limitation is the amount of memory python has available. And I added the getContext() function to my answer. Thanks. – genisage Jan 22 '15 at 04:54