1

How can I let the python mpmath.nstr function keep all the trailing zeros for mpmath.mpf('0')? It looks that the strip_zeros optional argument does not work for mpmath.mpf('0') as seen in the following example:

Python 3.8.5 (default, Jul 28 2020, 12:59:40) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import mpmath
>>> mpmath.dps=30
>>> mpmath.nstr(mpmath.mpf('0'), 10, strip_zeros=False)
'0.0'
>>> mpmath.nstr(mpmath.mpf('1'), 10, strip_zeros=False)
'1.000000000'
>>> 
norio
  • 3,652
  • 3
  • 25
  • 33

1 Answers1

1

From the source, it appears that this is by design (https://github.com/fredrik-johansson/mpmath/blob/master/mpmath/libmp/libmpf.py) in to_str():

    # Special numbers
    if not s[1]:
        if s == fzero:
            if dps: t = '0.0'
            else:   t = '.0'
            if show_zero_exponent:
                t += 'e+0'
            return t
        if s == finf: return '+inf'
        if s == fninf: return '-inf'
        if s == fnan: return 'nan'
        raise ValueError

I don't have an explanation why this would be the case, but considering this is not something wrong with your code, you should probably ask the maintainers of the project for the reason (and perhaps for a way around it, if you require it).

Grismar
  • 27,561
  • 4
  • 31
  • 54
  • The second argument to `nstr` is supposed to be the number of significant digits, but that's not meaningful for 0. There are no significant digits in `'0.0'` or `'0.000000000'`, no matter how many zeros you tack on. – user2357112 Dec 14 '20 at 01:59
  • 1
    That's assuming a value is "true zero", but if you divide 0.0008 (5 significant digits) by two, you'd get 0.0000, not 0.0. I.e., a value indicating that it's closest to 0.0000, by four or more decimals. So, I interpreted the question as how to obtain such a value, other than artificially computing it, since it has the same significance as 1.0000 vs 1.0. – Grismar Dec 14 '20 at 02:37
  • 1
    In other words: it seems to me that there needs to be a way to define 'true zero' (special in the same way +inf and -inf are) as well as a real value close to zero, with some specific significance. – Grismar Dec 14 '20 at 02:38
  • That's not how significant digits work. While there are levels of precision involved in measuring something to be zero, the concept of significant digits doesn't have enough nuance to distinguish such details. Significant digits start at the first nonzero digit, so all the digits in `0.0000` are insignificant. (Also, 0.0008 has only one significant digit, the 8, and dividing it by 2 produces 0.0004, not 0.0000.) – user2357112 Dec 14 '20 at 05:17
  • Note that if you ask mpmath to compute `mpmath.nstr(mpmath.mpf(0.0008), 5, strip_zeros=False)`, it gives `'0.00080000'`, not `'0.0008'`, indicating that it agrees that none of the leading zeros are significant. – user2357112 Dec 14 '20 at 05:20
  • Sorry, changed the example and introduced the error, should have read something like "divide 0.0001 by 3" - I appreciate your argument about significance, but by that same token, 1.0000 is as meaningless as 0.0000, which it clearly isn't in context of this library. (however, it would appear the author agrees and for good mathematical reason - it just leads to the kind of confusion with the OP) – Grismar Dec 14 '20 at 05:20
  • Well, the docstring is explicit: "Convert a raw mpf to a decimal floating-point literal with ***at most*** `dps` decimal digits in the mantissa." – paxdiablo Dec 14 '20 at 06:32