upiterbarg / mpmath

Automatically exported from code.google.com/p/mpmath
Other
0 stars 0 forks source link

Enhancement request: scientific formatting in a canonical fashion #121

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
For those of us that like to do our own formatting of numbers, it would be
nice to have a function analogous to nstr called estr that would always
print mp[fci] numbers in a canonical scientific form.  Lacking that, I'd be
happy with libmpf function analogous to to_str called to_estr that would
just work on mpf's.

For us anal retentives, it's important to be able to format numbers like we
like.  I'm using the code below to allow my program to print in fixed
point, scientific, engineering, and a significant figures mode that I like.
 to_str isn't quite appropriate because it wants to prettify numbers near
unit magnitude.

Here's what I'm using (a slightly modified version of to_str):

from mpmath import *
from mpmath.libmpf import to_digits_exp, fzero, finf, fninf, fnan

def to_estr(s, dps):
    if not s[1]:
        if s == fzero: return '0.0'
        if s == finf: return '+inf'
        if s == fninf: return '-inf'
        if s == fnan: return 'nan'
        raise ValueError
    sign, digits, exponent = to_digits_exp(s, dps+3)
    if not dps:
        if digits[0] in '56789':
            exponent += 1
        digits = ".0"
    else:
        if len(digits) > dps and digits[dps] in '56789' and \
            (dps < 500 or digits[dps-4:dps] == '9999'):
            digits2 = str(int(digits[:dps]) + 1)
            if len(digits2) > dps:
                digits2 = digits2[:dps]
                exponent += 1
            digits = digits2
        else:
            digits = digits[:dps]
        digits = (digits[:1] + "." + digits[1:])
    if exponent >= 0: return sign + digits + "e+" + str(exponent)
    if exponent < 0: return sign + digits + "e" + str(exponent)

if __name__ == "__main__":
    N = 20
    response = raw_input("num digits? ")
    digits = mp.dps
    if response:
        digits = max(1, min(abs(int(response)), mp.dps))
    for i in xrange(-N, N+1):
        x = mpf("1.234567890e%d" % i)
        print "%-20s" % to_estr(x._mpf_, digits)

Original issue reported on code.google.com by someonesdad1@gmail.com on 25 Jan 2009 at 5:57

GoogleCodeExporter commented 9 years ago
I think this is related to issue 69 and issue 66 (__format__
(http://docs.python.org/library/string.html#formatstrings)).

Please note that you can use '%.10e' % mpf(1.234567890e-10), but I don't know 
how
good it works for high precisions.

However, the number formatting should be configurable.

Original comment by Vinzent.Steinberg@gmail.com on 25 Jan 2009 at 8:01

GoogleCodeExporter commented 9 years ago
Agreed, this needs to be fixed. These options should be added to to_str and 
nstr, and
the __format__ method should be implemented.

I think this issue mostly duplicates 69 and 66.

Original comment by fredrik....@gmail.com on 26 Jan 2009 at 2:02

GoogleCodeExporter commented 9 years ago
This format is now possible using to_str(x, n, strip_zeros=False, min_fixed=0,
max_fixed=0). However, there is room for some more generalization, so this 
interface
should not be considered final.

Original comment by fredrik....@gmail.com on 7 Feb 2009 at 7:12