Python Decimal – технические обозначения для mili (10e-3) и микро (10e-6)
Вот пример, который беспокоит меня:
>>> x = decimal.Decimal('0.0001') >>> print x.normalize() >>> print x.normalize().to_eng_string() 0.0001 0.0001
Есть ли способ иметь технические обозначения для представления mili (10e-3) и micro (10e-6)?
- Преобразование XLSX в CSV правильно с использованием python
- Чтение в integer из stdin в Python
- Калибровка камеры с помощью OpenCV - Как настроить размер шахматной доски?
- Как Python 2.7 сравнивает элементы внутри списка
- Функция сдвига текста в Python
- Python Pandas проверяет, происходит ли значение более одного раза в тот же день
- Как проверить, зашифрован ли zip-файл, используя стандартный zip-файл стандартной библиотеки python?
- Недопустимый заголовок http_host
- Вид не возвращал объект HttpResponse. Вместо этого он вернул None
- Как добавить параметр «Новый» сценарий Python в контекстное меню?
5 Solutions collect form web for “Python Decimal – технические обозначения для mili (10e-3) и микро (10e-6)”
Вот функция, которая делает вещи явно, а также поддерживает использование суффиксов СИ для экспоненты:
def eng_string( x, format='%s', si=False): ''' Returns float/int value <x> formatted in a simplified engineering format - using an exponent that is a multiple of 3. format: printf-style string used to format the value before the exponent. si: if true, use SI suffix for exponent, eg k instead of e3, n instead of e-9 etc. Eg with format='%.2f': 1.23e-08 => 12.30e-9 123 => 123.00 1230.0 => 1.23e3 -1230000.0 => -1.23e6 and with si=True: 1230.0 => 1.23k -1230000.0 => -1.23M ''' sign = '' if x < 0: x = -x sign = '-' exp = int( math.floor( math.log10( x))) exp3 = exp - ( exp % 3) x3 = x / ( 10 ** exp3) if si and exp3 >= -24 and exp3 <= 24 and exp3 != 0: exp3_text = 'yzafpnum kMGTPEZY'[ ( exp3 - (-24)) / 3] elif exp3 == 0: exp3_text = '' else: exp3_text = 'e%s' % exp3 return ( '%s'+format+'%s') % ( sign, x3, exp3_text)
decimal
модуль выполняет десятичную арифметическую спецификацию , которая гласит:
to-science-string – преобразование в числовую строку
[…]
Коэффициент сначала преобразуется в строку в базе десять с использованием символов от 0 до 9 без начальных нулей (кроме случаев, когда его значение равно нулю, и в этом случае используется один символ 0). Затем вычисляется скорректированный показатель; это показатель, плюс число символов в преобразованном коэффициенте, меньше одного. То есть показатель экспоненты + (clength-1), где clength – это длина коэффициента в десятичных разрядах.
Если показатель меньше или равен нулю, а скорректированный показатель больше или равен -6, число будет преобразовано в символьную форму без использования экспоненциальной нотации.
[…]
to-engineering-string – преобразование в числовую строку
Эта операция преобразует число в строку, используя техническую нотацию, если требуется показатель степени.
Преобразование точно следует правилам преобразования в научную числовую строку, за исключением случаев конечных чисел, где используется экспоненциальная нотация.
Или, другими словами:
>>> for n in (10 ** e for e in range(-1, -8, -1)): ... d = Decimal(str(n)) ... print d.to_eng_string() ... 0.1 0.01 0.001 0.0001 0.00001 0.000001 100E-9
«Полная» цитата показывает, что не так!
decimal
модуль действительно соответствует проприетарной (IBM) десятичной арифметической спецификации. Цитируя эту спецификацию IBM в decimal.to_eng_string()
ясно показывает, что не так с decimal.to_eng_string()
(выделено мной):
to-engineering-string – преобразование в числовую строку
Эта операция преобразует число в строку, используя техническую нотацию, если требуется показатель степени.
Преобразование точно следует правилам преобразования в научную числовую строку, за исключением случаев конечных чисел, где используется экспоненциальная нотация. В этом случае преобразованный экспонент корректируется как кратный трем (инженерная нотация) , позиционируя десятичную точку с одним, двумя или тремя символами, предшествующими ей (т. Е. Часть до десятичной точки будет варьироваться от 1 до 999 ). Это может потребовать добавления одного или двух завершающих нулей.
Если после корректировки десятичная точка не будет следовать цифре, она не будет добавлена. Если конечный показатель равен нулю, то никакая буква и показатель индикатора не будут суффиксными.
Эта проприетарная спецификация IBM фактически допускает не применять инженерную нотацию для чисел с бесконечным десятичным представлением , для которого вместо этого используется обычная научная нотация! Это явно неправильное поведение, для которого был открыт отчет об ошибке Python .
Решение
from math import floor, log10 def powerise10(x): """ Returns x as a*10**b with 0 <= a < 10 """ if x == 0: return 0,0 Neg = x < 0 if Neg: x = -x a = 1.0 * x / 10**(floor(log10(x))) b = int(floor(log10(x))) if Neg: a = -a return a,b def eng(x): """Return a string representing x in an engineer friendly notation""" a,b = powerise10(x) if -3 < b < 3: return "%.4g" % x a = a * 10**(b % 3) b = b - b % 3 return "%.4gE%s" % (a,b)
Источник: https://code.activestate.com/recipes/578238-engineering-notation/
Результат испытаний
>>> eng(0.0001) 100E-6
Основываясь на превосходном ответе Джулиана Смита (и на этом ответе), я изменил функцию, чтобы улучшить следующие моменты:
- Совместимость с Python3 (целочисленное деление)
- Совместимо для ввода 0
- Округление до значительного числа цифр, по умолчанию 3, без конечных нулей, напечатанных
так что вот обновленная функция:
import numpy as np def eng_string( x, sig_figs=3, si=True): """ Returns float/int value <x> formatted in a simplified engineering format - using an exponent that is a multiple of 3. sig_figs: number of significant figures si: if true, use SI suffix for exponent, eg k instead of e3, n instead of e-9 etc. """ x = np.float(x) sign = '' if x < 0: x = -x sign = '-' elif x == 0: exp = 0 exp3 = 0 x3 = 0 else: exp = int( np.floor( np.log10( x))) exp3 = exp - ( exp % 3) x3 = x / ( 10 ** exp3) x3 = round( x3, -int(np.floor(np.log10(abs( x3 ))) - (sig_figs-1)) ) if x3 == int(x3): # prevent from displaying .0 x3 = int(x3) if si and exp3 >= -24 and exp3 <= 24 and exp3 != 0: exp3_text = 'yzafpnum kMGTPEZY'[ exp3 // 3 + 8] elif exp3 == 0: exp3_text = '' else: exp3_text = 'e%s' % exp3 return ( '%s%s%s') % ( sign, x3, exp3_text)
Я понимаю, что это старый поток, но он подходит к началу поиска python engineering notation
для python engineering notation
и кажется разумным, чтобы эта информация находилась здесь.
Я инженер, которому нравятся инженерные единицы «инженерная 101». Мне даже не нравятся обозначения, такие как 0.1uF
, я хочу, чтобы это прочитало 100nF
. Я играл с классом Decimal
и не очень любил его поведение по диапазону возможных значений, поэтому я свернул пакет с именем engineering_notation
который можно установить в pp-install.
pip install engineering_notation
Изнутри Python:
>>> from engineering_notation import EngNumber >>> EngNumber('1000000') 1M >>> EngNumber(1000000) 1M >>> EngNumber(1000000.0) 1M >>> EngNumber('0.1u') 100n >>> EngNumber('1000m') 1
Этот пакет также поддерживает сравнения и другие простые числовые операции.
- Почему класс datetime python имеет метод «fromtimestamp», но не метод «totimestamp»?
- Разрешение AmbiguousTimeError из make_aware от Django