(skipping the *
import)
In [19]: import mpmath as mp
For some reason, directly setting dps
isn't working:
In [20]: mp.dps=31
In [21]: print(mp.mp)
Mpmath settings:
mp.prec = 53 [default: 53]
mp.dps = 15 [default: 15]
mp.trap_complex = False [default: False]
(solved it. With a mp
import I need to set mp.mp.dps=31
)
But I can set it in a context. Creating the variable with the full desire decimals:
In [22]: with mp.workdps(31):
...: pi_30=mp.mpf('3.141592653589793238462643383279')
...: print(pi_30)
...:
3.141592653589793238462643383279
I can then display it with various dps
using:
In [23]: for i in range(20):
...: with mp.workdps(i):
...: print(pi_30)
...:
3.0
3.0
3.1
3.14
3.142
3.1416
3.14159
3.141593
3.1415927
3.14159265
3.141592654
3.1415926536
3.14159265359
3.14159265359
3.1415926535898
3.14159265358979
3.141592653589793
3.1415926535897932
3.14159265358979324
3.141592653589793238
round
is a python function, returning a python float, so it can't display more than 15, even if the input is mpmath
.
mp.nstr
also works
In [29]: mp.nstr(pi_30,15)
Out[29]: '3.14159265358979'
In [30]: mp.nstr(pi_30,26)
Out[30]: '3.1415926535897932384626434'
My values match the ones you get with python round
, so I'll skip any further discussion of rounding
nuances. Look in mpmath
docs for more information on the relation between binary values and decimal displays.
Regarding why round()
is limited to python floats, here's the mpmath
definition:
In [45]: pi_30.__round__??
Signature: pi_30.__round__(*args)
Docstring: <no docstring>
Source:
def __round__(self, *args):
return round(float(self), *args)
File: /usr/local/lib/python3.8/dist-packages/mpmath/ctx_mp_python.py
Type: method
It is explicitly converting the mp value to float, and then applying the python round
.
https://github.com/fredrik-johansson/mpmath/issues/455 is an old open issue regarding rounding.