Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Format floating point to a fixed width python

I don't care about the placement of the decimal point, and would like to print in scientific notation when appropriate to display with maximum accuracy. However, I would like to round appropriately to maintain a fixed width, ragged left or ragged right is fine.

e.g.

>>> my_format("{:10f}", 0.0000000456)
"  4.56e-08"
>>> my_format("{:10f}", 12.345678987654321)
" 12.345679"
#or "12.34567890" because significant digits
#but not "1.2346e+01", since it is less accurate than the above representations
>>> my_format("{:10f}", 12345678987654321)
"1.2345e+16"

EDIT to clarify the examples, the width formatting specifier does not provide a fixed width. It provides a minimum width. How do I obtain a fixed width representation?

like image 847
Him Avatar asked Oct 22 '25 05:10

Him


1 Answers

the g format specifier is generally good if you want scientific notation, i.e:

my_format = "{:.10g}".format

should do the right thing:

>>> list(my_format(v) for v in (0.0000000456, 12.345678987654321, 12345678987654321))
['4.56e-08', '12.34567899', '1.234567899e+16']

I realised later that the above function doesn't do what the OP wanted

Based on helpful comments from @a_guest I've come up with the following:

def my_format(v, length=10):
    n = length
    while n > 0:
        i = len('%#.*g' % (n, v))
        s = '%.*g' % (n + n - i, v)
        if len(s) <= length:
            return s
        n -= 1
    return s

I now get ['4.56e-08', '12.345679', '1.2346e+16'] back which is closer to what was wanted.

I've tested this by generating a lot of random numbers using:

from random import uniform
def rnd_float():
    return uniform(-10, 10) * 10 ** (uniform(-1.6, 1.6) ** 11)

pretty arbitrary, but generates numbers reasonably close to the distribution I care about. I.e. mostly around 1, but some very small and large with decent probability.

I've passed numbers from this to my_format 100k times and I get appropriately formatted numbers back.

like image 154
Sam Mason Avatar answered Oct 23 '25 22:10

Sam Mason



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!