Количество цифр в экспоненте

Можно ли установить количество цифр, которые будут использоваться для печати показателя степени числа с плавающей запятой? Я хочу установить его на 3.

В настоящее время,

f = 0.0000870927939438012
>>> "%.14e"%f
'8.70927939438012e-05'
>>> "%0.14e"%f
'8.709279e-005'

Я хочу напечатать: '8.70927939438012e-005'


person nmadzharov    schedule 28.03.2012    source источник
comment
Почему второй пример имеет меньшую точность и 3 цифры в показателе степени?   -  person Anurag Uniyal    schedule 28.03.2012
comment
На моей машине %e % f выводит «8.709279e-05», а %0.14e % f выводит «8.70927939438012e-05». Кроме того, более высокая точность должна быть возможна с такими библиотеками, как mpmath. Тем не менее, я не знаю, соответствует ли это вашим потребностям.   -  person Arseny    schedule 28.03.2012


Ответы (4)


Нет никакого способа контролировать это, лучший способ - написать функцию для этого, например.

def eformat(f, prec, exp_digits):
    s = "%.*e"%(prec, f)
    mantissa, exp = s.split('e')
    # add 1 to digits as 1 is taken by sign +/-
    return "%se%+0*d"%(mantissa, exp_digits+1, int(exp))

print eformat(0.0000870927939438012, 14, 3)
print eformat(1.0000870927939438012e5, 14, 3)
print eformat(1.1e123, 4, 4)
print eformat(1.1e-123, 4, 4)

Выход:

8.70927939438012e-005
1.00008709279394e+005
1.1000e+0123
1.1000e-0123
person Anurag Uniyal    schedule 28.03.2012
comment
Анураг, есть разные способы манипулировать этим как строкой и получить три цифры в показателе степени. Что меня интересовало, так это избежать манипуляций со строками, поскольку второй пример в моем посте показывает, что Python изначально использует три цифры в некоторых случаях. Все еще не уверен, почему это так, как вы также спросили выше. Я просто нашел это во время эксперимента. - person nmadzharov; 02.04.2012
comment
@nmadzharov Я не думаю, что для этого есть какие-либо общедоступные функции, вам следует попробовать изучить код Python, чтобы увидеть, что он на самом деле делает, хотя я не вижу 3 цифры в показателе степени на Python 2.7. - person Anurag Uniyal; 02.04.2012
comment
@Anurag: трехзначные показатели степени появились на некоторых платформах для Python 2.5; это было исправлено в Python 2.6 (я полагаю). Дополнительную информацию см. на странице bugs.python.org/issue1600. - person Mark Dickinson; 13.04.2012
comment
Мне грустно, что этот ответ правильный, конечно, было бы неплохо, если бы вы могли указать количество цифр ... почти проголосовали ... - person foobarbecue; 12.02.2014

Вы можете использовать np.format_float_scientific

from numpy import format_float_scientific

f = 0.0000870927939438012

format_float_scientific(f, exp_digits=3) # prints '8.70927939438012e-005'

format_float_scientific(f, exp_digits=5, precision=2) #prints '8.71e-00005'
person Khalil Al Hooti    schedule 14.11.2018

Вот немного более гибкий ответ (использует либо 'e', либо 'E' для разделения мантиссы и экспоненты, прощает отсутствующие/плохие аргументы). Но я поддерживаю ответ @AnuragUniyal, потому что этот ответ очень компактный.

def efmte(x, n=6, m=2, e='e', nmax=16):
    def _expc(s): # return exponent character of e-formatted float
        return next(filter(lambda character: character in {'E', 'e'}, s))
    def _pad0(s, n): # return string padded to length n
        return ('{0:0>' + str(n) + '}').format(s)
    def _efmtes(s, n): # reformat e-formatted float: n e-digits
        m, e, p = s.partition(_expc(s)) # mantissa, exponent, +/-power
        return m + e + p[0] + _pad0(p[1:], n)
    def _efmt(x, n, e): # returns formatted float x: n decimals, 'e'/'E'
        return ('{0:.' + str(n) + e + '}').format(x)
    x = x if isinstance(x, float) else float('nan')
    nmax = 16 if not isinstance(nmax, int) else max(0, nmax)
    n = 6 if not isinstance(n, int) else min(max(0, n), nmax)
    m = 2 if not isinstance(m, int) else max(0, m)
    e = 'e' if e not in {'E', 'e'} else e
    return _efmtes(_efmt(x, n, e), m)

Примеры:

>>> efmte(42., n=1, m=5)
'4.2e+00001'
>>> efmte('a')
'-1.#IND00e+00'
>>> # Yuck: I was expecting 'nan'. Anyone else?
>>> from math import pi
>>> efmte(pi)
'3.141593e+00'
>>> efmte(pi, m=3)
'3.141593e+000'
person Ana Nimbus    schedule 10.10.2018

Аналогичен ответу @Anurag Unyal, но при желании удаляет знак в показателе степени (полезно, если в нем мало места).

def expformat(f, prec, exp_digits, sign='on'):
    """Scientific-format a number with a given number of digits in the exponent.
    Optionally remove the sign in the exponent"""
    s = "%.*e"%(prec, f)
    mantissa, exp = s.split('e')
    if (sign=='on') :
        # add 1 to digits as 1 is taken by sign +/-
        return "%se%+0*d"%(mantissa, exp_digits+1, int(exp))
    else :
        return "%se%0*d"%(mantissa, exp_digits, int(exp))
person sancho.s ReinstateMonicaCellio    schedule 22.12.2019