exponent digits in scientific notation in Python
Asked Answered
B

3

8

In Python, scientific notation always gives me 2 digits in exponent:

print('%17.8E\n' % 0.0665745511651039)
6.65745512E-02

However, I badly want to have 3 digits like:

6.65745512E-002

Can we do this with a built-in configuration/function in Python?

I know my question is basically the same question as: Python - number of digits in exponent, but this question was asked 4 years ago and I don't want to call such a function thousand times. I hope there should be a better solution now.

Bathesda answered 27/8, 2016 at 19:3 Comment(1)
Possible duplicate of Python - number of digits in exponentAssure
T
4

Unfortunately, you can not change this default behavior since you can not override the str methods.

However, you can wrap the float, and use the __format__ method:

class MyNumber:
    def __init__(self, val):
        self.val = val

    def __format__(self,format_spec):
        ss = ('{0:'+format_spec+'}').format(self.val)
        if ( 'E' in ss):
            mantissa, exp = ss.split('E')            
            return mantissa + 'E'+ exp[0] + '0' + exp[1:]
        return ss


     print( '{0:17.8E}'.format( MyNumber(0.0665745511651039)))
Topographer answered 27/8, 2016 at 21:55 Comment(4)
Yes, the wrapping-the-float method perfectly works for print(). Thank you. However, I would also like to write the output to a file and it works only half way: 'ValueError: invalid literal for float(): -4.10522747+00' I need your help. Let me edit my original question to explain this error.Bathesda
When the number is between 1 <= n < 10, the format doesn't work and simply shows 2 digits. ` -6.08474553E-001 -4.10522747+00 -4.75716448+00 -1.58045329E-002 4.72555542+00` (It didn't work for print(), too.) Could you please fix this?Bathesda
Updated for positive exponentTopographer
It works like a charm. Now it shows all in 3 digits. ` -6.08474553E-001 -4.10522747E+000 -4.75716448E+000 -1.58045329E-002 4.72555542E+000` Thank you so much!Bathesda
T
0

You can use your own formatter and override format_field:

import string
class MyFormatter(string.Formatter): 
    def format_field(self, value, format_spec):
        ss = string.Formatter.format_field(self,value,format_spec)
        if format_spec.endswith('E'):
            if ( 'E' in ss):
                mantissa, exp = ss.split('E')
                return mantissa + 'E'+ exp[0] + '0' + exp[1:]                  
        return ss

print( MyFormatter().format('{0:17.8E}',0.00665745511651039) )
Topographer answered 28/8, 2016 at 5:19 Comment(0)
A
0

You can use the numpy.format_float_scientific() to do this:

import numpy as np

foo = -0.000123
foo_str = np.format_float_scientific(foo, precision=2, exp_digits=1)
print(foo_str)

will give:
-1.23e-4

Or with 3 exponent positions like the OP was seeking (exp_digits=3):
-1.23e-004

Alexio answered 29/5 at 8:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.