gmpy2 replaces the mpf type from gmpy 1.x with a new mpfr type based on the MPFR library. The new mpfr type supports correct rounding, selectable rounding modes, and many trigonometric, exponential, and special functions. A context manager is used to control precision, rounding modes, and the behavior of exceptions.
The default precision of an mpfr is 53 bits - the same precision as Python’s float type. If the precison is changed, then mpfr(float('1.2')) differs from mpfr('1.2'). To take advantage of the higher precision provided by the mpfr type, always pass constants as strings.
>>> import gmpy2
>>> from gmpy2 import mpfr
>>> mpfr('1.2')
mpfr('1.2')
>>> mpfr(float('1.2'))
mpfr('1.2')
>>> gmpy2.get_context().precision=100
>>> mpfr('1.2')
mpfr('1.2000000000000000000000000000006',100)
>>> mpfr(float('1.2'))
mpfr('1.1999999999999999555910790149937',100)
>>>
Warning
Contexts and context managers are not thread-safe! Modifying the context in one thread will impact all other threads.
A context is used to control the behavior of mpfr and mpc arithmetic. In addition to controlling the precision, the rounding mode can be specified, minimum and maximum exponent values can be changed, various exceptions can be raised or ignored, gradual underflow can be enabled, and returning complex results can be enabled.
gmpy2.context() creates a new context with all options set to default. gmpy2.set_context(ctx) will set the active context to ctx. gmpy2.get_context() will return a reference to the active context. Note that contexts are mutable: modifying the reference returned by get_context() will modify the active context until a new context is enabled with set_context(). The copy() method of a context will return a copy of the context.
The following example just modifies the precision. The remaining options will be discussed later.
>>> gmpy2.set_context(gmpy2.context())
>>> gmpy2.get_context()
context(precision=53, real_prec=Default, imag_prec=Default,
round=RoundToNearest, real_round=Default, imag_round=Default,
emax=1073741823, emin=-1073741823,
subnormalize=False,
trap_underflow=False, underflow=False,
trap_overflow=False, overflow=False,
trap_inexact=False, inexact=False,
trap_invalid=False, invalid=False,
trap_erange=False, erange=False,
trap_divzero=False, divzero=False,
trap_expbound=False,
allow_complex=False)
>>> gmpy2.sqrt(5)
mpfr('2.2360679774997898')
>>> gmpy2.get_context().precision=100
>>> gmpy2.sqrt(5)
mpfr('2.2360679774997896964091736687316',100)
>>> gmpy2.get_context().precision+=20
>>> gmpy2.sqrt(5)
mpfr('2.2360679774997896964091736687312762351',120)
>>> ctx=gmpy2.get_context()
>>> ctx.precision+=20
>>> gmpy2.sqrt(5)
mpfr('2.2360679774997896964091736687312762354406182',140)
>>> gmpy2.set_context(gmpy2.context())
>>> gmpy2.sqrt(5)
mpfr('2.2360679774997898')
>>> ctx.precision+=20
>>> gmpy2.sqrt(5)
mpfr('2.2360679774997898')
>>> gmpy2.set_context(ctx)
>>> gmpy2.sqrt(5)
mpfr('2.2360679774997896964091736687312762354406183596116',160)
>>>
Note
Specifying a value for precision that is too close to the maximum precision will cause the MPFR library to fail.
There are five rounding modes availble to mpfr types:
Note
It is possible to change the values of emin/emax such that previous mpfr values are no longer valid numbers but should either underflow to +/-0.0 or overflow to +/-Infinity. To raise an exception if this occurs, see trap_expbound.
This attribute controls whether or not an InvalidOperationError exception is raised if a numerical result is not defined. A special NaN (Not-A-Number) value will be returned if an exception is not raised. The InvalidOperationError is a sub-class of Python’s ValueError.
For example, gmpy2.sqrt(-2) will normally return mpfr(‘nan’). However, if allow_complex is set to True, then an mpc result will be returned.
This attribute controls whether or not a RangeError exception is raised when certain operations are performed on NaN and/or Infinity values. Setting trap_erange to True can be used to raise an exception if comparisons are attempted with a NaN.
>>> gmpy2.set_context(gmpy2.context())
>>> mpfr('nan') == mpfr('nan')
False
>>> gmpy2.get_context().trap_erange=True
>>> mpfr('nan') == mpfr('nan')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
gmpy2.RangeError: comparison with NaN
>>>
Contexts can also be used in conjunction with Python’s with ... statement to temporarily change the context settings for a block of code and then restore the original settings when the block of code exits.
gmpy2.local_context() first save the current context and then creates a new context based on a context passed as the first argument, or the current context if no context is passed. The new context is modified if any optional keyword arguments are given. The orginal active context is restored when the block completes.
In the following example, the current context is saved by gmpy2.local_context() and then the block begins with a copy of the default context and the precision set to 100. When the block is finished, the original context is restored.
>>> with gmpy2.local_context(gmpy2.context(), precision=100) as ctx:
... print(gmpy2.sqrt(2))
... ctx.precision += 100
... print(gmpy2.sqrt(2))
...
1.4142135623730950488016887242092
1.4142135623730950488016887242096980785696718753769480731766796
>>>
A context object can also be used directly to create a context manager block. However, instead of restoring the context to the active context when the with ... statement is executed, the restored context is the context used before any keyword argument modifications.
The code:
is equivalent to:
Contexts that implement the standard single, double, and quadruple precision floating point types can be created using ieee().
factorial(n) returns the floating-point approximation to the factorial of n.
See fac(n) to get the exact integer result.
is_inf(x) returns True if x is Infinity or -Infinity.
Note
is_inf() is deprecated; please use if_infinite().
is_number(x) returns True if x is an actual number (i.e. not NaN or Infinity).
Note
is_number() is deprecated; please use is_finite().
mpfr() returns and mpfr object set to 0.0.
mpfr(n[, precison=0]) returns an mpfr object after converting a numeric value n. If no precision, or a precision of 0, is specified; the precision is taken from the current context.
mpfr(s[, precision=0[, [base=0]]) returns an mpfr object after converting a string ‘s’ made up of digits in the given base, possibly with fractional part (with period as a separator) and/or exponent (with exponent marker ‘e’ for base<=10, else ‘@’). If no precision, or a precision of 0, is specified; the precison is taken from the current context. The base of the string representation must be 0 or in the interval 2 ... 62. If the base is 0, the leading digits of the string are used to identify the base: 0b implies base=2, 0x implies base=16, otherwise base=10 is assumed.
The mpfr type supports the __format__() special method to allow custom output formatting.
x.__format__(fmt) returns a Python string by formatting ‘x’ using the format string ‘fmt’. A valid format string consists of:
Note
The formatting codes must be specified in the order shown above.
>>> import gmpy2
>>> from gmpy2 import mpfr
>>> a=mpfr("1.23456")
>>> "{0:15.3f}".format(a)
' 1.235'
>>> "{0:15.3Uf}".format(a)
' 1.235'
>>> "{0:15.3Df}".format(a)
' 1.234'
>>> "{0:.3Df}".format(a)
'1.234'
>>> "{0:+.3Df}".format(a)
'+1.234'